From 14dfdf0be5ac36c2cf20ee8839eeaf96d71fae55 Mon Sep 17 00:00:00 2001 From: izzabizz5 Date: Thu, 30 Jan 2025 14:51:19 -0500 Subject: [PATCH 001/166] copy files from v1 to v2 --- elements/app-hax/lib/v2/AppHaxBackendAPI.js | 259 ++++ elements/app-hax/lib/v2/AppHaxRouter.js | 81 ++ elements/app-hax/lib/v2/AppHaxStore.js | 320 +++++ elements/app-hax/lib/v2/app-hax-button.js | 282 ++++ .../app-hax/lib/v2/app-hax-hat-progress.js | 232 +++ elements/app-hax/lib/v2/app-hax-label.js | 94 ++ elements/app-hax/lib/v2/app-hax-search-bar.js | 155 ++ elements/app-hax/lib/v2/app-hax-site-bar.js | 208 +++ .../app-hax/lib/v2/app-hax-site-button.js | 157 ++ .../app-hax/lib/v2/app-hax-site-details.js | 379 +++++ elements/app-hax/lib/v2/app-hax-site-login.js | 278 ++++ elements/app-hax/lib/v2/app-hax-steps.js | 1274 +++++++++++++++++ elements/app-hax/lib/v2/app-hax-toast.js | 60 + elements/app-hax/lib/v2/app-hax-top-bar.js | 130 ++ .../lib/v2/app-hax-user-menu-button.js | 70 + elements/app-hax/lib/v2/app-hax-user-menu.js | 110 ++ .../app-hax/lib/v2/app-hax-wired-toggle.js | 47 + 17 files changed, 4136 insertions(+) create mode 100644 elements/app-hax/lib/v2/AppHaxBackendAPI.js create mode 100644 elements/app-hax/lib/v2/AppHaxRouter.js create mode 100644 elements/app-hax/lib/v2/AppHaxStore.js create mode 100644 elements/app-hax/lib/v2/app-hax-button.js create mode 100644 elements/app-hax/lib/v2/app-hax-hat-progress.js create mode 100644 elements/app-hax/lib/v2/app-hax-label.js create mode 100644 elements/app-hax/lib/v2/app-hax-search-bar.js create mode 100644 elements/app-hax/lib/v2/app-hax-site-bar.js create mode 100644 elements/app-hax/lib/v2/app-hax-site-button.js create mode 100644 elements/app-hax/lib/v2/app-hax-site-details.js create mode 100644 elements/app-hax/lib/v2/app-hax-site-login.js create mode 100644 elements/app-hax/lib/v2/app-hax-steps.js create mode 100644 elements/app-hax/lib/v2/app-hax-toast.js create mode 100644 elements/app-hax/lib/v2/app-hax-top-bar.js create mode 100644 elements/app-hax/lib/v2/app-hax-user-menu-button.js create mode 100644 elements/app-hax/lib/v2/app-hax-user-menu.js create mode 100644 elements/app-hax/lib/v2/app-hax-wired-toggle.js diff --git a/elements/app-hax/lib/v2/AppHaxBackendAPI.js b/elements/app-hax/lib/v2/AppHaxBackendAPI.js new file mode 100644 index 0000000000..2adea8defc --- /dev/null +++ b/elements/app-hax/lib/v2/AppHaxBackendAPI.js @@ -0,0 +1,259 @@ +import { LitElement, html } from "lit"; +import { localStorageGet } from "@haxtheweb/utils/utils.js"; +import "@haxtheweb/jwt-login/jwt-login.js"; +import { toJS, autorun } from "mobx"; +import { store } from "./AppHaxStore.js"; +import { SimpleColorsSharedStylesGlobal } from "@haxtheweb/simple-colors-shared-styles/simple-colors-shared-styles.js"; +import { SimpleIconIconsetsManifest } from "@haxtheweb/simple-icon/lib/simple-iconset-manifest.js"; +// this element will manage all connectivity to the backend +// this way everything is forced to request through calls to this +// so that it doesn't get messy down below in state +export class AppHaxBackendAPI extends LitElement { + static get tag() { + return "app-hax-backend-api"; + } + + constructor() { + super(); + this.jwt = localStorageGet("jwt", null); + this.method = + window && globalThis.appSettings && globalThis.appSettings.demo + ? "GET" + : "POST"; + this.basePath = "/"; + this.lastResponse = {}; + this.appSettings = {}; + autorun(() => { + this.appSettings = toJS(store.appSettings); + // allow setting in session driven environments + if (this.appSettings.method) { + this.method = this.appSettings.method; + } + if (this.appSettings.jwt) { + this.jwt = this.appSettings.jwt; + } + }); + autorun(() => { + this.token = toJS(store.token); + }); + } + + static get properties() { + return { + jwt: { type: String }, + basePath: { type: String, attribute: "base-path" }, + appSettings: { type: Object }, + method: { type: String }, + token: { type: String }, + }; + } + + render() { + return html``; + } + + // failed to get valid JWT, wipe current + jwtFailed(e) { + this.jwt = null; + this.token = null; + } + // event meaning we either got or removed the jwt + async jwtChanged(e) { + this.jwt = e.detail.value; + // sanity check we actually got a response + // this fires every time our JWT changes so it can update even after already logging in + // like hitting refresh or coming back to the app + if (!this.__loopBlock && this.jwt) { + this.__loopBlock = true; + const userData = await this.makeCall("getUserDataPath"); + if (userData && userData.data) { + store.user = { + name: userData.data.userName, + }; + this.__loopBlock = false; + } + } + } + + async makeCall(call, data = {}, save = false, callback = false) { + if (this.appSettings && this.appSettings[call]) { + var urlRequest = `${this.basePath}${this.appSettings[call]}`; + var options = { + method: this.method, + }; + if (this.jwt) { + data.jwt = this.jwt; + } + if (this.token) { + data.token = this.token; + } + // encode in search params or body of the request + if (this.method === "GET") { + urlRequest += "?" + new URLSearchParams(data).toString(); + } else { + options.body = JSON.stringify(data); + } + const response = await fetch(`${urlRequest}`, options).then( + (response) => { + if (response.ok) { + return response.json(); + } else if (response.status === 401) { + // call not allowed, log out bc unauthorized + globalThis.dispatchEvent( + new CustomEvent("jwt-login-logout", { + composed: true, + bubbles: true, + cancelable: false, + detail: true, + }), + ); + } + // we got a miss, logout cause something is wrong + else if (response.status === 404) { + // call not allowed, log out bc unauthorized + globalThis.dispatchEvent( + new CustomEvent("jwt-login-logout", { + composed: true, + bubbles: true, + cancelable: false, + detail: true, + }), + ); + } else if (response.status === 403) { + // if this was a 403 it should be because of a bad jwt + // or out of date one. let's kick off a call to get a new one + // hopefully from the timing token, knowing this ALSO could kick + // over here. + globalThis.dispatchEvent( + new CustomEvent("jwt-login-refresh-token", { + composed: true, + bubbles: true, + cancelable: false, + detail: { + element: { + obj: this, + callback: "refreshRequest", + params: [call, data, save, callback], + }, + }, + }), + ); + } + return {}; + }, + ); + // ability to save the output if this is being done as a bg task + // that way we can get access to the result later on + if (save) { + this.lastResponse[call] = response; + } + if (callback) { + callback(); + } + return response; + } + } + + /** + * Attempt to salvage the request that was kicked off + * when our JWT needed refreshed + */ + refreshRequest(jwt, response) { + const { call, data, save, callback } = response; + // force the jwt to be the updated jwt + // this helps avoid any possible event timing issue + if (jwt) { + this.jwt = jwt; + this.makeCall(call, data, save, callback); + } + } + + // set instance of API in store + firstUpdated(changedProperties) { + if (super.firstUpdated) { + super.firstUpdated(changedProperties); + } + // set store refernece to this singleton + store.AppHaxAPI = this; + // site creation roped into the promise list + // after knowing our data structure since we'll definitely call this + store.newSitePromiseList = [ + ...store.newSitePromiseList, + async () => + await this.makeCall("createSite", this._formatSitePostData(), true), + ]; + } + // just easier to read here + _formatSitePostData() { + const site = toJS(store.site); + // html contents if we are starting from a file import, otherwise its null + const items = toJS(store.items); + const itemFiles = toJS(store.itemFiles); + const colors = Object.keys(SimpleColorsSharedStylesGlobal.colors); + const buildData = { + site: { + name: site.name, + description: `${site.type} ${site.structure}`, + theme: site.theme, + }, + build: { + type: site.type, + structure: site.structure, + items: items, + files: itemFiles, + }, + theme: { + // select a random color + color: colors[Math.floor(Math.random() * colors.length)], + // select a random av icon + icon: `${SimpleIconIconsetsManifest[0].name}:${ + SimpleIconIconsetsManifest[0].icons[ + Math.floor( + Math.random() * SimpleIconIconsetsManifest[0].icons.length, + ) + ] + }`, + }, + }; + return buildData; + } + + updated(changedProperties) { + if (super.updated) { + super.updated(changedProperties); + } + changedProperties.forEach((oldValue, propName) => { + if (propName === "jwt") { + store.jwt = this[propName]; + } + if (propName === "token") { + store.token = this[propName]; + } + }); + } +} + +globalThis.AppHaxAPI = globalThis.AppHaxAPI || {}; + +globalThis.AppHaxAPI.requestAvailability = () => { + if (!globalThis.AppHaxAPI.instance) { + globalThis.AppHaxAPI.instance = globalThis.document.createElement( + AppHaxBackendAPI.tag, + ); + globalThis.document.body.appendChild(globalThis.AppHaxAPI.instance); + } + return globalThis.AppHaxAPI.instance; +}; +export const AppHaxAPI = globalThis.AppHaxAPI.requestAvailability(); + +customElements.define(AppHaxBackendAPI.tag, AppHaxBackendAPI); diff --git a/elements/app-hax/lib/v2/AppHaxRouter.js b/elements/app-hax/lib/v2/AppHaxRouter.js new file mode 100644 index 0000000000..169c3758fa --- /dev/null +++ b/elements/app-hax/lib/v2/AppHaxRouter.js @@ -0,0 +1,81 @@ +import { Router } from "@vaadin/router"; +import { autorun, toJS } from "mobx"; +import { store } from "./AppHaxStore.js"; + +/** + * `app-hax-router` + */ +export class AppHaxRouter extends HTMLElement { + /** + * Store the tag name to make it easier to obtain directly. + */ + + static get tag() { + return "app-hax-router"; + } + /** + * ready life cycle + */ + + constructor() { + super(); + // create router + const options = {}; + if (this.baseURI) { + options.baseUrl = this.baseURI; + } + this.windowControllers = new AbortController(); + this.router = new Router(this, options); + autorun(() => { + this._updateRouter(toJS(store.routes)); + }); + autorun(() => { + const manifest = toJS(store.manifest); + const baseURI = toJS(store.AppHaxAPI.basePath); + if (manifest && manifest.items && manifest.items.length > 0) { + const siteItemRoutes = manifest.items.map((i) => { + return { + path: i.slug.replace(baseURI, ""), // replacement of the basePath ensures routes match in haxiam / subdirs + slug: i.slug, + name: i.id, + component: `fake-${i.id}-e`, + }; + }); + store.routes = [...siteItemRoutes].concat(store.baseRoutes); + } + }); + } + + connectedCallback() { + globalThis.addEventListener( + "vaadin-router-location-changed", + this._routerLocationChanged.bind(this), + { signal: this.windowControllers.signal }, + ); + } + /** + * Detached life cycle + */ + + disconnectedCallback() { + this.windowControllers.abort(); + } + + /** + * Update the router based on a manifest. + */ + _updateRouter(routerItems) { + this.router.setRoutes([...routerItems]); + } + /** + * React to page changes in the vaadin router and convert it + * to a change in the mobx store. + * @param {event} e + */ + + // eslint-disable-next-line class-methods-use-this + _routerLocationChanged(e) { + store.location = e.detail.location; + } +} +customElements.define(AppHaxRouter.tag, AppHaxRouter); diff --git a/elements/app-hax/lib/v2/AppHaxStore.js b/elements/app-hax/lib/v2/AppHaxStore.js new file mode 100644 index 0000000000..90f7717fdb --- /dev/null +++ b/elements/app-hax/lib/v2/AppHaxStore.js @@ -0,0 +1,320 @@ +/* eslint-disable max-classes-per-file */ +import { localStorageGet, localStorageSet } from "@haxtheweb/utils/utils.js"; +import { observable, makeObservable, computed, configure } from "mobx"; +import { DeviceDetails } from "@haxtheweb/replace-tag/lib/PerformanceDetect.js"; +configure({ enforceActions: false }); // strict mode off + +class Store { + constructor() { + this.badDevice = null; + this.evaluateBadDevice(); + this.location = null; + this.token = + globalThis.appSettings && globalThis.appSettings.token + ? globalThis.appSettings.token + : null; + this.version = "0.0.0"; + this.items = null; + this.itemFiles = null; + this.refreshSiteList = true; + this.createSiteSteps = false; + fetch(new URL("../../../haxcms-elements/package.json", import.meta.url)) + .then((response) => response.json()) + .then((obj) => (this.version = obj.version)); + this.appSettings = globalThis.appSettings || {}; + // defer to local if we have it for JWT + if (this.appSettings.jwt) { + localStorageSet("jwt", this.appSettings.jwt); + } + this.jwt = localStorageGet("jwt", null); + // placeholder for when the actual API Backend gets plugged in here + this.AppHaxAPI = {}; + this.newSitePromiseList = [ + () => import("@haxtheweb/i18n-manager/lib/I18NMixin.js"), + () => import("@haxtheweb/wc-autoload/wc-autoload.js"), + () => import("@haxtheweb/replace-tag/replace-tag.js"), + () => import("@haxtheweb/utils/utils.js"), + () => import("@haxtheweb/grid-plate/grid-plate.js"), + () => import("@haxtheweb/simple-fields/simple-fields.js"), + () => import("mobx/dist/mobx.esm.js"), + () => import("@haxtheweb/h-a-x/h-a-x.js"), + () => import("@haxtheweb/haxcms-elements/lib/core/haxcms-site-store.js"), + () => import("@haxtheweb/haxcms-elements/lib/core/haxcms-site-router.js"), + () => + import("@haxtheweb/haxcms-elements/lib/core/haxcms-site-builder.js"), + () => + import("@haxtheweb/haxcms-elements/lib/core/HAXCMSLitElementTheme.js"), + () => import("@haxtheweb/haxcms-elements/lib/core/haxcms-site-editor.js"), + () => + import("@haxtheweb/haxcms-elements/lib/core/haxcms-editor-builder.js"), + () => + import("@haxtheweb/haxcms-elements/lib/core/haxcms-site-editor-ui.js"), + ]; + this.appEl = null; + this.appReady = false; + this.soundStatus = localStorageGet("app-hax-soundStatus", true); + // If user is new, make sure they are on step 1 + this.appMode = "search"; + this.activeSiteOp = null; + this.activeSiteId = null; + this.baseRoutes = [ + { + path: "createSite-step-1", + component: "fake", + step: 1, + name: "step-1", + label: "New Journey", + statement: "What sort of journey is it?", + title: "Step 1: Create", + }, + { + path: "createSite-step-2", + component: "fake", + step: 2, + name: "step-2", + label: "Structure", + statement: "How is the :structure organized?", + title: "Step 2: Structure", + }, + { + path: "createSite-step-3", + component: "fake", + step: 3, + name: "step-3", + label: "Theme select", + statement: "What your :structure feels like?", + title: "Step 3: Theme", + }, + { + path: "createSite-step-4", + component: "fake", + step: 4, + name: "step-4", + label: "Name", + statement: "What do you want to call your site?", + title: "Step 4: Name", + }, + { + path: "createSite-step-5", + component: "fake", + step: 5, + name: "step-5", + label: "Building..", + statement: "Getting your :structure ready to launch", + title: "Step 5: Building site", + }, + { + path: "home", + component: "fake", + name: "home", + label: "Welcome back", + statement: "Let's go on a HAX Journey", + title: "Home", + }, + { + path: "index.html", + component: "fake", + name: "home", + label: "Welcome back", + statement: "Let's go on a HAX Journey", + title: "Home", + }, + { + path: "index.php", + component: "fake", + name: "home", + label: "Welcome back", + statement: "Let's go on a HAX Journey", + title: "Home", + }, + { + path: "search", + component: "fake", + name: "search", + label: "Search", + statement: "Discover active adventures", + title: "Search sites", + }, + { + path: "/", + component: "fake", + name: "welcome", + label: "Welcome", + statement: "Let's build something awesome!", + title: "Home", + }, + { + path: "/(.*)", + component: "fake", + name: "404", + label: "404 :[", + statement: "it's not you.. it's me", + title: "FoUr Oh FoUr", + }, + ]; + this.routes = this.baseRoutes; + this.siteReady = false; + this.manifest = {}; + this.searchTerm = ""; + this.user = { + name: "", + }; + this.site = !localStorageGet("app-hax-site") + ? { structure: null, type: null, theme: null, name: null } + : localStorageGet("app-hax-site"); + this.step = this.stepTest(null); + this.darkMode = !localStorageGet("app-hax-darkMode") + ? false + : localStorageGet("app-hax-darkMode"); + + makeObservable(this, { + // internal state for routing + location: observable.ref, // router location in url + routes: observable, // routes that are valid + // internal state requirements + appSettings: observable, // endpoint connections to the backend app + appReady: observable, // all ready to paint + appMode: observable, // mode the app is in. search, create, etc + createSiteSteps: observable, // if we're making a site or in another part of app + step: observable, // step that we're on in our build + site: observable, // information about the site being created + newSitePromiseList: observable, + items: observable, // site items / structure from a docx micro if option selected + itemFiles: observable, // files related to the items to be imported from another site format + version: observable, // version of haxcms FRONTEND as per package.json + // user related data + jwt: observable, // JSON web token + token: observable, // XSS prevention token + manifest: observable, // sites the user has access to + user: observable, // user object like name after login + // user preferences + searchTerm: observable, // current search term for filtering own list of sites + darkMode: observable, // dark mode pref + soundStatus: observable, // toggle sounds on and off + activeItem: computed, // active item is route + isNewUser: computed, // if they are new so we can auto kick to createSiteSteps if needed + isLoggedIn: computed, // basic bool for logged in + badDevice: observable, // if we have a terrible device or not based on detected speeds + activeSiteOp: observable, // active operation for sites if working with them + activeSiteId: observable, // active Item if working w/ sites + activeSite: computed, // activeSite from ID + siteReady: observable, // implied that we had a site and then it got built and we can leave app + refreshSiteList: observable, // used to force state to refresh sitelisting + }); + } + setPageTitle(title) { + if (globalThis.document.querySelector("title")) { + globalThis.document.querySelector("title").innerText = `HAX: ${title}`; + } + } + // refresh + refreshSiteListing() { + this.refreshSiteList = false; + // @todo this causes a reactive feedbackloop in + this.refreshSiteList = true; + } + // filter to just get data about THIS site + get activeSite() { + if (this.activeSiteId && this.manifest && this.manifest.items) { + const sites = this.manifest.items.filter( + (item) => item.id === this.activeSiteId, + ); + if (sites.length === 1) { + return sites.pop(); + } + return null; + } + } + // see if this device is poor + async evaluateBadDevice() { + this.badDevice = await DeviceDetails.badDevice(); + if (this.badDevice === true) { + this.soundStatus = false; + } + } + // validate if they are on the right step via state + // otherwise we need to force them to the correct step + stepTest(current) { + if (this.site.structure === null && current !== 1) { + return 1; + } else if ( + this.site.structure !== null && + this.site.type === null && + current !== 2 + ) { + return 2; + } else if ( + this.site.structure !== null && + this.site.type !== null && + this.site.theme === null && + current !== 3 + ) { + return 3; + } else if ( + this.site.structure !== null && + this.site.type !== null && + this.site.theme !== null && + this.site.name === null && + current !== 4 + ) { + return 4; + } else if ( + this.site.structure !== null && + this.site.type !== null && + this.site.theme !== null && + this.site.name !== null + ) { + return 5; + } + return current; + } + + get isLoggedIn() { + if (this.appReady && this.AppHaxAPI) { + return this.jwt !== "null" && this.jwt; + } + } + + get isNewUser() { + if (this.manifest && this.manifest.items) { + return this.manifest.items.length === 0; + } + } + + // site{ structure, type, theme } (course, portfolio, buz, colors) + get activeItem() { + if (this.routes.length > 0 && this.location && this.location.route) { + if (this.createSiteSteps) { + const routeItem = this.routes.find((item) => { + if (item.step === undefined || item.step !== this.step) { + return false; + } + return true; + }); + return routeItem; + } else { + return this.location.route; + } + } + } + + // centralize toast messages + toast(msg, duration = 3000, extras = {}) { + globalThis.dispatchEvent( + new CustomEvent("haxcms-toast-show", { + bubbles: true, + cancelable: true, + composed: true, + detail: { + text: msg, + duration: duration, + ...extras, + }, + }), + ); + } +} +/** + * Central store + */ +export const store = new Store(); diff --git a/elements/app-hax/lib/v2/app-hax-button.js b/elements/app-hax/lib/v2/app-hax-button.js new file mode 100644 index 0000000000..f20af41f16 --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-button.js @@ -0,0 +1,282 @@ +import "@haxtheweb/simple-icon/lib/simple-icon-lite.js"; +import "@haxtheweb/hax-iconset/lib/simple-hax-iconset.js"; +import "wired-elements/lib/wired-button.js"; +import { html, css, LitElement } from "lit"; +const postIt = new URL("../assets/images/PostIt.svg", import.meta.url).href; +const betaPostIt = new URL("../assets/images/BetaPostIt.svg", import.meta.url) + .href; + +export class AppHaxButton extends LitElement { + // a convention I enjoy so you can change the tag name in 1 place + static get tag() { + return "app-hax-button"; + } + + constructor() { + super(); + this.icon = "save"; + this.type = null; + this.value = null; + this.disabled = false; + this.elevation = 2; + this.active = false; + this.comingSoon = false; + this.prompt = null; + this.callback = null; + this.param = null; + this.beta = false; + this.addEventListener("click", this._handleClick); + this.addEventListener("click", this._handleClick); + this.addEventListener("focus", this._handleFocus); + this.addEventListener("blur", this._handleBlur); + this.addEventListener("mouseover", this._handleFocus); + this.addEventListener("mouseout", this._handleBlur); + } + + _handleFocus() { + if (!this.disabled && !this.comingSoon) { + this.active = true; + this.elevation = "4"; + } + } + + _handleBlur() { + if (!this.disabled && !this.comingSoon) { + this.active = false; + this.elevation = "2"; + } + } + + _handleClick() { + if (!this.disabled && !this.comingSoon) { + this.shadowRoot.querySelector(".haxButton").blur(); + } + } + + static get properties() { + return { + icon: { type: String }, + type: { type: String, reflect: true }, + disabled: { type: Boolean, reflect: true }, + elevation: { type: Number }, + active: { type: Boolean, reflect: true }, + comingSoon: { type: Boolean, reflect: true, attribute: "coming-soon" }, + beta: { type: Boolean, reflect: true }, + prompt: { type: String }, + callback: { type: String }, + param: { type: String }, + }; + } + + firstUpdated(changedProperties) { + if (super.firstUpdated) { + super.firstUpdated(changedProperties); + } + changedProperties.forEach((oldValue, propName) => { + if (propName === "type") { + switch (this.type) { + case "technology": + this.icon = "hardware:desktop-mac"; + this.value = "technology"; + break; + case "business": + this.icon = "maps:local-atm"; + this.value = "business"; + break; + case "art": + this.icon = "image:palette"; + this.value = "art"; + break; + case "6w": + this.icon = "hax:messages-6"; + this.value = "6 Week"; + break; + case "15w": + this.icon = "social:school"; + this.value = "15 Week"; + break; + case "training": + this.icon = "hax:bricks"; + this.value = "Training"; + break; + case "docx import": + this.icon = "hax:file-docx"; + this.value = "docx"; + break; + case "docx": + this.icon = "hax:file-docx"; + this.value = "docx"; + break; + case "evolution": + this.icon = "communication:business"; + this.value = "evo"; + break; + case "pressbooks": + this.icon = "hax:wordpress"; + this.value = "pressbooks"; + break; + case "gitbook": + this.icon = "mdi-social:github-circle"; + this.value = "gitbook"; + break; + case "elms:ln": + this.icon = "lrn:network"; + this.value = "elmsln"; + break; + case "haxcms": + this.icon = "hax:hax2022"; + this.value = "haxcms"; + break; + case "notion": + this.icon = "book"; + this.value = "notion"; + break; + case "html": + this.icon = "icons:code"; + this.value = "HTML"; + break; + case "Blog": + this.icon = "social:public"; + this.value = "Blog"; + break; + default: + this.icon = "image:photo-filter"; + this.value = "own"; + this.type = "Create Your Own"; + break; + } + } + }); + } + + static get styles() { + return [ + css` + :host { + display: block; + --background-color: transparent; + --background-color-active: white; + font-family: "Press Start 2P", sans-serif; + } + :host([coming-soon]) .haxButton { + pointer-events: none; + background-color: var(--simple-colors-default-theme-grey-6); + } + :host([active]) .haxButton { + color: var( + --app-hax-background-color, + var(--background-color-active) + ); + background-color: var(--app-hax-accent-color, var(--accent-color)); + } + :host([active]) simple-icon-lite { + --simple-icon-color: var( + --app-hax-background-color, + var(--background-color-active) + ); + } + :host([active]) .type { + background-color: var(--app-hax-accent-color, var(--accent-color)); + color: var( + --app-hax-background-color, + var(--background-color-active) + ); + } + + #container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-around; + width: 132px; + height: 112px; + } + .coming-soon { + display: block; + height: 114px; + width: 140px; + z-index: 1; + position: absolute; + margin-top: -75px; + } + .beta { + display: block; + height: 100px; + width: 120px; + z-index: 1; + position: absolute; + top: 0; + left: 0; + margin-left: -50px; + margin-top: -10px; + } + .haxButton { + background-color: var( + --app-hax-background-color, + var(--background-color) + ); + color: var(--app-hax-accent-color, var(--accent-color)); + display: inline-flex; + } + simple-icon-lite { + --simple-icon-width: 60px; + --simple-icon-height: 60px; + --simple-icon-color: var(--app-hax-accent-color, var(--accent-color)); + } + .type { + font-size: 10px; + color: var(--app-hax-accent-color, var(--accent-color)); + } + @media (max-width: 800px) { + #container { + width: 100px; + height: 75px; + } + + .beta, + .coming-soon { + margin-top: -50px; + height: 114px; + width: 100px; + } + } + `, + ]; + } + + render() { + return html` + +
+ +
${this.type}
+
+ ${this.comingSoon + ? html`Feature coming soon` + : ``} + ${this.beta + ? html`Feature in beta` + : ``} +
+ `; + } +} +customElements.define(AppHaxButton.tag, AppHaxButton); diff --git a/elements/app-hax/lib/v2/app-hax-hat-progress.js b/elements/app-hax/lib/v2/app-hax-hat-progress.js new file mode 100644 index 0000000000..0b71287949 --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-hat-progress.js @@ -0,0 +1,232 @@ +import { html, css } from "lit"; +import { SimpleColors } from "@haxtheweb/simple-colors/simple-colors.js"; +import { autorun, toJS } from "mobx"; +import { store } from "./AppHaxStore.js"; +import "@haxtheweb/promise-progress/promise-progress.js"; + +export class AppHaxHatProgress extends SimpleColors { + static get tag() { + return "app-hax-hat-progress"; + } + + constructor() { + super(); + this.promises = []; + this.max = 100; + autorun(() => { + this.promises = toJS(store.newSitePromiseList); + }); + autorun(() => { + this.dark = toJS(store.darkMode); + }); + } + + static get properties() { + return { + ...super.properties, + promises: { type: Array }, + }; + } + + process() { + this.shadowRoot.querySelector("#progress2").process(); + } + + firstUpdated(changedProperties) { + if (super.firstUpdated) { + super.firstUpdated(changedProperties); + } + this.dispatchEvent(new CustomEvent("progress-ready", { detail: true })); + + setTimeout(() => { + this.shadowRoot + .querySelector("#progress2") + .addEventListener("value-changed", (e) => { + this.shadowRoot.querySelector("#value").textContent = e.detail.value; + }); + this.shadowRoot + .querySelector("#progress2") + .addEventListener("max-changed", (e) => { + this.max = e.detail.value; + }); + this.shadowRoot + .querySelector("#progress2") + .addEventListener("promise-progress-finished", (e) => { + if (e.detail.value) { + // this will seem like magic... but our createSite + // Promise has a special flag on the function that + // saves the result in an object relative to our API broker + // this way if we ask it for the last thing it created + // the response is there even though we kicked it off previously + // we more or less assume it completed bc the Promises all resolved + // and it was our 1st Promise we asked to issue! + + // state clean up incase activated twice + if (this.shadowRoot.querySelector(".game")) { + this.shadowRoot.querySelector(".game").remove(); + } + + const createResponse = store.AppHaxAPI.lastResponse.createSite.data; + const text = globalThis.document.createElement("button"); + this.shadowRoot.querySelector("#value").textContent = this.max; + text.textContent = "Let's go!"; + text.classList.add("game"); + text.addEventListener("pointerdown", () => { + store.appEl.playSound("click"); + }); + text.addEventListener("click", () => { + store.appEl.reset(); + setTimeout(() => { + globalThis.location = createResponse.slug.replace( + "index.html", + "", + ); + }, 0); + }); + this.shadowRoot + .querySelector("#progress2") + .parentNode.appendChild(text); + // show you saying you got this! + store.toast( + `${createResponse.title ? createResponse.title : ""} ready!`, + 1500, + { + hat: "random", + }, + ); + store.setPageTitle( + `${createResponse.title ? createResponse.title : ""} ready!`, + ); + setTimeout(() => { + store.toast(`redirecting in 3..`, 10000, { + hat: "random", + walking: true, + }); + store.setPageTitle("Redirecting in 3.."); + setTimeout(() => { + store.toast(`redirecting in 2..`, 10000, { + hat: "random", + walking: true, + }); + store.setPageTitle("Redirecting in 2.."); + setTimeout(() => { + store.toast(`redirecting in 1..`, 10000, { + hat: "random", + walking: true, + }); + store.setPageTitle("Redirecting in 1.."); + store.appEl.reset(); + setTimeout(() => { + store.setPageTitle(`Enjoy!`); + globalThis.location = createResponse.slug.replace( + "index.html", + "", + ); + }, 1000); + }, 1000); + }, 1000); + }, 1800); + this.dispatchEvent( + new CustomEvent("promise-progress-finished", { + composed: true, + bubbles: true, + cancelable: true, + detail: true, + }), + ); + } + }); + }, 0); + } + + static get styles() { + return [ + super.styles, + css` + :host { + display: block; + height: 400px; + width: 400px; + } + img { + width: 400px; + height: 400px; + pointer-events: none; + } + .progress { + margin: -148px 0 0 10px; + z-index: -1; + } + .progress::part(progress) { + height: 100px; + width: 338px; + margin-top: -1px 0 0 -4px; + } + + .progress::part(progress)::-moz-progress-bar { + background-color: red; + height: 50px; + margin: 24px 0 0 0; + border: none; + } + + .count { + color: var(--simple-colors-default-theme-grey-1, white); + font-family: "Press Start 2P", sans-serif; + width: 350px; + text-align: center; + position: relative; + display: block; + font-size: 30px; + margin-top: -250px; + margin-left: 30px; + } + .game { + font-family: "Press Start 2P", sans-serif; + font-size: 28px; + font-weight: bold; + text-align: center; + width: 310px; + background-color: var(--simple-colors-default-theme-red-7, red); + color: var(--simple-colors-default-theme-grey-1, white); + border: 0px; + height: 54px; + display: block; + position: relative; + margin: 138px 0px 0px 52px; + padding: 0; + box-sizing: border-box; + } + .game:focus, + .game:hover { + cursor: pointer; + background-color: var(--simple-colors-default-theme-red-8); + color: var(--simple-colors-default-theme-grey-2); + } + .game:active { + cursor: progress; + background-color: var(--simple-colors-default-theme-red-10); + color: var(--simple-colors-default-theme-grey-5); + } + `, + ]; + } + + render() { + return html` + + +
0%
+ `; + } +} +customElements.define(AppHaxHatProgress.tag, AppHaxHatProgress); diff --git a/elements/app-hax/lib/v2/app-hax-label.js b/elements/app-hax/lib/v2/app-hax-label.js new file mode 100644 index 0000000000..320fdfb4e6 --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-label.js @@ -0,0 +1,94 @@ +// dependencies / things imported +import { LitElement, html, css } from "lit"; + +export class AppHaxLabel extends LitElement { + // a convention I enjoy so you can change the tag name in 1 place + static get tag() { + return "app-hax-label"; + } + + constructor() { + super(); + this.title = "Welcome"; + this.subtitle = "Start your journey now!"; + } + + static get properties() { + return { + title: { type: String }, + subtitle: { type: String }, + }; + } + + // TODO: If scaling is weird with font-sizes, try using clamp() (https://css-tricks.com/linearly-scale-font-size-with-css-clamp-based-on-the-viewport/) + static get styles() { + return css` + :host { + font-family: "Press Start 2P", sans-serif; + text-align: center; + } + + .title { + -webkit-text-stroke: 1px + var(--app-hax-accent-color, var(--accent-color)); + -webkit-text-fill-color: var( + --app-hax-background-color, + var(--background-color) + ); + font-weight: normal; + font-size: 3.5vw; + display: inline-flex; + align-items: center; + } + + .subtitle { + color: var(--app-hax-accent-color, var(--accent-color)); + font-weight: normal; + margin-top: 2px; + font-size: 20px; + } + @media (max-width: 700px) { + .subtitle { + font-size: 12px; + } + } + + .bracket { + font-size: 8vw; + font-weight: normal; + vertical-align: middle; + -webkit-text-stroke: 0px; + -webkit-text-fill-color: var( + --app-hax-accent-color, + var(--accent-color) + ); + } + @media (max-height: 500px) { + .title { + -webkit-text-stroke: unset; + -webkit-text-fill-color: unset; + } + .bracket { + font-size: 4vw; + margin: 0; + padding: 0; + } + } + `; + } + + render() { + return html` +
+
+ <${this.title}> +
+
+ ${this.subtitle} +
+
+ `; + } +} +customElements.define(AppHaxLabel.tag, AppHaxLabel); diff --git a/elements/app-hax/lib/v2/app-hax-search-bar.js b/elements/app-hax/lib/v2/app-hax-search-bar.js new file mode 100644 index 0000000000..c3036f8c76 --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-search-bar.js @@ -0,0 +1,155 @@ +/* eslint-disable no-return-assign */ +import { LitElement, html, css } from "lit"; +import "@haxtheweb/simple-tooltip/simple-tooltip.js"; +import { store } from "./AppHaxStore.js"; + +export class AppHaxSearchBar extends LitElement { + // a convention I enjoy so you can change the tag name in 1 place + static get tag() { + return "app-hax-search-bar"; + } + + constructor() { + super(); + this.searchTerm = ""; + this.disabled = false; + this.showSearch = false; + } + + // Site.json is coming from + + static get properties() { + return { + searchTerm: { type: String }, + showSearch: { type: Boolean, reflect: true, attribute: "show-search" }, + disabled: { type: Boolean, reflect: true }, + }; + } + + updated(changedProperties) { + changedProperties.forEach((oldValue, propName) => { + if (propName === "searchItems") { + this.displayItems = [...this.searchItems]; + } else if (propName === "searchTerm") { + store.searchTerm = this.searchTerm; + } else if (propName === "showSearch" && oldValue !== undefined) { + if (this[propName] === false) { + this.searchTerm = ""; + } + } + }); + } + + static get styles() { + return [ + css` + :host { + overflow: hidden; + } + input { + visibility: none; + opacity: 0; + width: 0; + transition: all ease-in-out 0.3s; + padding: 4px; + font-family: "Press Start 2P", sans-serif; + font-size: 20px; + margin: 2px 0 0 16px; + } + :host([show-search]) input { + visibility: visible; + opacity: 1; + width: 250px; + max-width: 25vw; + } + @media (max-width: 780px) { + :host([show-search]) input { + width: 250px; + max-width: 20vw; + } + } + @media (max-width: 600px) { + :host([show-search]) input { + width: 200px; + max-width: 20vw; + } + } + + simple-toolbar-button[disabled] { + background-color: #cccccc; + pointer-events: none; + cursor: help; + } + simple-toolbar-button { + min-width: 48px; + margin: 0; + --simple-toolbar-border-color: #dddddddd; + height: 48px; + --simple-toolbar-button-disabled-border-color: transparent; + --simple-toolbar-button-disabled-opacity: 0.3; + --simple-toolbar-button-padding: 3px 6px; + --simple-toolbar-border-radius: 0; + } + simple-toolbar-button:hover, + simple-toolbar-button:active, + simple-toolbar-button:focus { + background-color: var(--hax-ui-background-color-accent); + color: var(--hax-ui-color); + } + simple-toolbar-button:hover, + simple-toolbar-button:active, + simple-toolbar-button:focus { + --simple-toolbar-border-color: var(--hax-ui-color-accent); + } + `, + ]; + } + testKeydown(e) { + if (e.key === "Escape" || e.key === "Enter") { + this.toggleSearch(); + } + } + // eslint-disable-next-line class-methods-use-this + search() { + store.appEl.playSound("click"); + this.searchTerm = this.shadowRoot.querySelector("#searchField").value; + } + + render() { + return html` + + Toggle Search + + `; + } + + toggleSearch() { + if (!this.disabled) { + this.shadowRoot.querySelector("#searchField").value = ""; + store.appEl.playSound("click"); + this.showSearch = !this.showSearch; + setTimeout(() => { + this.shadowRoot.querySelector("#searchField").focus(); + }, 300); + } + } +} +customElements.define(AppHaxSearchBar.tag, AppHaxSearchBar); diff --git a/elements/app-hax/lib/v2/app-hax-site-bar.js b/elements/app-hax/lib/v2/app-hax-site-bar.js new file mode 100644 index 0000000000..587932b03b --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-site-bar.js @@ -0,0 +1,208 @@ +/* eslint-disable no-console */ +// dependencies / things imported +import { html, css, unsafeCSS } from "lit"; +import "@haxtheweb/simple-icon/lib/simple-icons.js"; +import "@haxtheweb/simple-icon/lib/simple-icon-button-lite"; +import { SimpleColors } from "@haxtheweb/simple-colors/simple-colors.js"; +import "@haxtheweb/simple-tooltip/simple-tooltip.js"; +import { animate } from "@lit-labs/motion"; + +const DropDownBorder = new URL( + "../assets/images/DropDownBorder.svg", + import.meta.url, +); +// EXPORT (so make available to other documents that reference this file) a class, that extends LitElement +// which has the magic life-cycles and developer experience below added +export class AppHaxSiteBars extends SimpleColors { + // a convention I enjoy so you can change the tag name in 1 place + static get tag() { + return "app-hax-site-bar"; + } + + // HTMLElement life-cycle, built in; use this for setting defaults + constructor() { + super(); + this.icon = "link"; + this.opened = false; + this.inprogress = false; + this.iconLink = "/"; + this.textInfo = {}; + this.siteId = ""; + } + + // properties that you wish to use as data in HTML, CSS, and the updated life-cycle + static get properties() { + return { + ...super.properties, + opened: { type: Boolean, reflect: true }, + icon: { type: String }, + inprogress: { type: Boolean, reflect: true }, + iconLink: { type: String, attribute: "icon-link" }, + textInfo: { type: Object }, + siteId: { type: String, reflect: true, attribute: "site-id" }, + }; + } + + // updated fires every time a property defined above changes + // this allows you to react to variables changing and use javascript to perform logic + updated(changedProperties) { + if (super.updated) { + super.updated(changedProperties); + } + changedProperties.forEach((oldValue, propName) => { + if (propName === "opened" && oldValue !== undefined) { + this.dispatchEvent( + new CustomEvent(`${propName}-changed`, { + detail: { + value: this[propName], + }, + }), + ); + } + }); + } + + // CSS - specific to Lit + static get styles() { + return [ + super.styles, + css` + :host { + --main-banner-width: 513px; + --main-banner-height: 60px; + --band-banner-height: 208px; + display: inline-block; + background-color: var(--simple-colors-default-theme-accent-3); + color: var(--simple-colors-default-theme-grey-12); + border-color: var(--simple-colors-default-theme-accent-4); + border-style: solid; + border-width: 5px 10px 5px 10px; + } + + #labels { + display: block; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + } + #labels ::slotted(*) { + font-family: "Press Start 2P", sans-serif; + font-size: 25px; + } + #labels ::slotted(a) { + color: var(--simple-colors-default-theme-accent-11); + padding: 8px 0; + display: block; + } + #labels ::slotted(a:focus), + #labels ::slotted(a:hover) { + color: var(--simple-colors-default-theme-accent-3); + background-color: var(--simple-colors-default-theme-accent-11); + } + + :host([opened]) { + background-color: var(--simple-colors-default-theme-accent-3); + } + #mainCard { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + width: var(--main-banner-width); + height: var(--main-banner-height); + padding: 2px 4px; + } + + #band-container { + display: block; + visibility: hidden; + height: 1px; + width: var(--main-banner-width); + } + + :host([opened]) #band-container { + height: var(--band-banner-height); + visibility: visible; + } + a { + flex: 1; + } + #labels { + flex: 6; + overflow: hidden; + text-overflow: ellipsis; + } + #icon { + --simple-icon-width: 49px; + --simple-icon-height: 49px; + color: var(--simple-colors-default-theme-accent-11); + } + #icon:hover, + #icon:focus, + #icon:active { + color: var(--simple-colors-default-theme-accent-3); + background-color: var(--simple-colors-default-theme-accent-11); + } + #dots { + --simple-icon-width: 49px; + --simple-icon-height: 49px; + color: var(--simple-colors-default-theme-grey-12); + background-image: url(${unsafeCSS(DropDownBorder)}); + background-repeat: no-repeat; + background-position: center; + } + @media (max-width: 640px) { + :host { + --main-banner-height: 40px; + --band-banner-height: 140px; + } + #icon, + #dots { + --simple-icon-width: 30px; + --simple-icon-height: 30px; + } + #mainCard { + padding: 0; + } + } + `, + ]; + } + + __clickButton() { + this.opened = !this.opened; + } + + // HTML - specific to Lit + render() { + return html` +
+ + + +
+ +
+ +
+
+ +
+ Access site + More options + `; + } + + // HAX specific callback + // This teaches HAX how to edit and work with your web component + /** + * haxProperties integration via file reference + */ +} +customElements.define(AppHaxSiteBars.tag, AppHaxSiteBars); diff --git a/elements/app-hax/lib/v2/app-hax-site-button.js b/elements/app-hax/lib/v2/app-hax-site-button.js new file mode 100644 index 0000000000..ea28009a88 --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-site-button.js @@ -0,0 +1,157 @@ +/* eslint-disable no-console */ +// dependencies / things imported +import { html, css } from "lit"; +import "@haxtheweb/simple-icon/lib/simple-icons.js"; +import "@haxtheweb/simple-icon/lib/simple-icon-lite.js"; +import { SimpleColors } from "@haxtheweb/simple-colors/simple-colors.js"; +import "wired-elements/lib/wired-button.js"; + +const postIt = new URL("../assets/images/PostIt.svg", import.meta.url).href; + +// EXPORT (so make available to other documents that reference this file) a class, that extends LitElement +// which has the magic life-cycles and developer experience below added +export class AppHaxSiteButton extends SimpleColors { + // a convention I enjoy so you can change the tag name in 1 place + static get tag() { + return "app-hax-site-button"; + } + + // HTMLElement life-cycle, built in; use this for setting defaults + constructor() { + super(); + this.label = null; + this.value = null; + this.disabled = false; + this.elevation = "3"; + this.active = false; + this.comingSoon = false; + this.addEventListener("click", this._handleClick); + this.addEventListener("focus", this._handleFocus); + this.addEventListener("blur", this._handleBlur); + this.addEventListener("mouseover", this._handleFocus); + this.addEventListener("mouseout", this._handleBlur); + } + + // properties that you wish to use as data in HTML, CSS, and the updated life-cycle + static get properties() { + return { + label: { type: String }, + value: { type: String }, + disabled: { type: Boolean, reflect: true }, + elevation: { type: Number }, + active: { type: Boolean, reflect: true }, + comingSoon: { type: Boolean, reflect: true, attribute: "coming-soon" }, + }; + } + + // CSS - specific to Lit + static get styles() { + return css` + :host { + --background-color: transparent; + --background-color-active: white; + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + font-family: "Press Start 2P", sans-serif; + width: fit-content; + margin: 20px 0; + } + :host([coming-soon]) .haxButton { + pointer-events: none; + background-color: var(--simple-colors-default-theme-grey-6); + } + @media (max-width: 800px) { + :host { + width: 320px; + } + } + :host([active]) .haxButton { + color: var(--app-hax-background-color, var(--background-color-active)); + background-color: var(--app-hax-accent-color, var(--accent-color)); + } + .haxButton { + background-color: var( + --app-hax-background-color, + var(--background-color) + ); + color: var(--app-hax-accent-color, var(--accent-color)); + font-size: var(--app-hax-site-button-font-size, 26px); + } + .contents { + display: flex; + justify-content: right; + } + .label { + width: var(--app-hax-site-button-width, auto); + min-width: var(--app-hax-site-button-min-width, auto); + height: var(--app-hax-site-button-height, auto); + display: inline-flex; + } + .coming-soon { + display: block; + height: 90px; + width: 110px; + z-index: 1; + position: absolute; + margin-right: -25px; + margin-top: -25px; + } + `; + } + + _handleFocus() { + if (!this.disabled && !this.comingSoon) { + this.active = true; + this.elevation = "5"; + } + } + + _handleBlur() { + if (!this.disabled && !this.comingSoon) { + this.active = false; + this.elevation = "3"; + } + } + + _handleClick() { + if (!this.disabled && !this.comingSoon) { + this.shadowRoot.querySelector(".haxButton").blur(); + } + } + + // HTML - specific to Lit + render() { + return html` + +
+ ${this.label} + ${this.comingSoon + ? html`Feature coming soon` + : ``} +
+
+ `; + } + + // HAX specific callback + // This teaches HAX how to edit and work with your web component + /** + * haxProperties integration via file reference + */ +} + +customElements.define(AppHaxSiteButton.tag, AppHaxSiteButton); diff --git a/elements/app-hax/lib/v2/app-hax-site-details.js b/elements/app-hax/lib/v2/app-hax-site-details.js new file mode 100644 index 0000000000..2f736d74b0 --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-site-details.js @@ -0,0 +1,379 @@ +// dependencies / things imported +import { html, css } from "lit"; +import "@haxtheweb/simple-datetime/simple-datetime.js"; +import { toJS } from "mobx"; +import { store } from "./AppHaxStore.js"; +import { SimpleColors } from "@haxtheweb/simple-colors/simple-colors.js"; + +// wrapper to simplify the slug if it has additional values on it +function makeSlug(url) { + let slug = "site"; + if (url) { + let tmp = url.split("sites/"); + if (tmp.length > 1) { + slug = tmp.pop().replace("/", ""); + } + } + return slug; +} +// EXPORT (so make available to other documents that reference this file) a class, that extends LitElement +// which has the magic life-cycles and developer experience below added +export class AppHaxSiteDetails extends SimpleColors { + // a convention I enjoy so you can change the tag name in 1 place + static get tag() { + return "app-hax-site-details"; + } + + // HTMLElement life-cycle, built in; use this for setting defaults + constructor() { + super(); + this.need = "all need to succeed"; + this.details = {}; + this.siteId = ""; + this.detailOps = [ + { + name: "Copy", + op: "copySite", + icon: "icons:content-copy", + }, + { + name: "Download", + op: "downloadSite", + icon: "file-download", + }, + { + name: "Archive", + op: "archiveSite", + icon: "icons:archive", + }, + ]; + if (globalThis.HAXCMSContext && globalThis.HAXCMSContext === "php") { + this.detailOps.push({ + name: "Git", + op: "gitList", + icon: "hax:git", + }); + } + } + + // properties that you wish to use as data in HTML, CSS, and the updated life-cycle + static get properties() { + return { + ...super.properties, + details: { type: Object }, + siteId: { type: String, attribute: "site-id" }, + }; + } + + // CSS - specific to Lit + static get styles() { + return [ + super.styles, + css` + :host { + display: flex; + flex-direction: column; + justify-content: center; + font-size: 12px; + align-items: stretch; + background-color: var(--simple-colors-default-theme-grey-2); + height: 208px; + } + + .flex-container { + flex: 1; + background-color: var(--simple-colors-default-theme-grey-2); + margin: 8px; + display: flex; + flex-direction: row; + justify-content: space-around; + align-items: center; + } + .info-group { + height: 100%; + max-width: 25%; + display: flex; + flex-direction: column; + justify-content: space-around; + align-items: center; + padding: 0px; + flex: 1; + } + simple-icon-button-lite:active, + simple-icon-button-lite:hover, + simple-icon-button-lite:focus { + background-color: var(--simple-colors-default-theme-grey-4, #eeeeee); + outline: 2px solid var(--simple-colors-default-theme-grey-12); + outline-offset: 1px; + } + + .info-headings { + font-size: 12px; + } + .info-item { + font-family: "Press Start 2P", sans-serif; + display: block; + text-overflow: ellipsis; + overflow: hidden; + color: var(--simple-colors-default-theme-grey-12); + line-height: 12px; + max-width: 100%; + font-size: 12px; + } + .pre ::slotted(*) { + padding: 12px; + overflow: hidden; + text-overflow: ellipsis; + max-width: 50%; + display: inline-flex; + } + a { + text-decoration: underline; + } + .info-date { + color: var(--simple-colors-default-theme-grey-12); + line-height: 12px; + font-size: 12px; + } + + .info-icon { + --simple-icon-width: 49px; + --simple-icon-height: 49px; + --simple-icon-button-border-radius: 0px; + --simple-icon-button-border: 0px; + outline: 0; + border: 2px solid var(--simple-colors-default-theme-grey-12); + border-radius: 4px; + padding: 4px; + width: 80%; + } + .info-icon::part(button) { + outline: none; + } + @media (max-width: 640px) { + :host { + height: 140px; + } + .btn-group button { + padding: 4px; + margin: 4px 0; + } + .flex-container > div { + margin: 0px; + } + .info-headings { + font-size: 8px; + } + .info-date { + font-size: 8px; + line-height: 10px; + } + .info-icon { + --simple-icon-width: 30px; + --simple-icon-height: 30px; + padding: 2px; + border-radius: none; + } + .info-item { + font-size: 8px; + } + .flex-container { + margin: 2px; + } + .pre ::slotted(*) { + padding: 0px; + margin-top: 8px; + } + .info-group { + height: 24px; + } + } + `, + ]; + } + + // eslint-disable-next-line class-methods-use-this + siteOperation(e) { + // let elements; + store.appEl.playSound("click"); + var target = e.target; + // avoid label trigger + if (target.tagName === "DIV") { + target = target.parentNode; + } + const div = globalThis.document.createElement("div"); + const op = target.getAttribute("data-site-operation"); + const opName = target.getAttribute("data-site-operation-name"); + const siteID = target.getAttribute("data-site"); + store.activeSiteOp = op; + store.activeSiteId = siteID; + import("@haxtheweb/simple-modal/simple-modal.js").then(() => { + setTimeout(() => { + const site = toJS( + store.manifest.items.filter((item) => item.id === siteID).pop(), + ); + div.appendChild( + globalThis.document.createTextNode( + `Are you sure you want to ${op.replace("Site", "")} ${ + site.metadata.site.name + }?`, + ), + ); + // gitlist opens in a new window + if (op === "gitList") { + // php library is basis for this button, rare instance + if (globalThis.HAXCMSContext === "php") { + // open link in new window + globalThis.open( + `gitlist/${site.metadata.site.name}`, + "_blank", + "noopener noreferrer", + ); + } + } else { + const bcontainer = globalThis.document.createElement("div"); + const b = globalThis.document.createElement("button"); + b.innerText = "Confirm"; + b.classList.add("hax-modal-btn"); + b.addEventListener("click", this.confirmOperation.bind(this)); + bcontainer.appendChild(b); + const b2 = globalThis.document.createElement("button"); + b2.innerText = "Cancel"; + b2.classList.add("hax-modal-btn"); + b2.classList.add("cancel"); + b2.addEventListener("click", this.cancelOperation.bind(this)); + bcontainer.appendChild(b2); + this.dispatchEvent( + new CustomEvent("simple-modal-show", { + bubbles: true, + cancelable: true, + composed: true, + detail: { + title: `${opName} ${site.metadata.site.name}?`, + elements: { content: div, buttons: bcontainer }, + invokedBy: target, + styles: { + "--simple-modal-titlebar-background": "orange", + "--simple-modal-titlebar-color": "black", + "--simple-modal-width": "30vw", + "--simple-modal-min-width": "300px", + "--simple-modal-z-index": "100000000", + "--simple-modal-height": "20vh", + "--simple-modal-min-height": "300px", + "--simple-modal-titlebar-height": "80px", + }, + }, + }), + ); + } + }, 0); + }); + } + + cancelOperation() { + store.activeSiteOp = ""; + store.activeSiteId = null; + globalThis.dispatchEvent(new CustomEvent("simple-modal-hide")); + store.appEl.playSound("error"); + } + + async confirmOperation() { + const op = toJS(store.activeSiteOp); + const site = toJS(store.activeSite); + // @todo bother to implement these / translate to the path via switch + await store.AppHaxAPI.makeCall( + op, + { + site: { + name: site.metadata.site.name, + id: site.id, + }, + }, + true, + () => { + const activeOp = toJS(store.activeSiteOp); + // download is weird relative to the others + if (activeOp === "downloadSite") { + // cheat to download a file path + globalThis.open( + store.AppHaxAPI.lastResponse.downloadSite.data.link, + "_blank", + ); + } else { + store.refreshSiteListing(); + } + }, + ); + globalThis.dispatchEvent(new CustomEvent("simple-modal-hide")); + store.appEl.playSound("success"); + store.toast( + `${site.metadata.site.name} ${op.replace("Site", "")} successful!`, + 3000, + { + hat: "random", + }, + ); + } + + // HTML - specific to Lit + render() { + return html` +
+
+
+
created
+ +
+
+
updated
+ +
+
+
pages
+
${this.details.pages}
+
+ +
+
+ ${this.detailOps.map( + (item) => html` +
+ +
${item.name.toLowerCase()}
+
+ ${item.op != "gitList" ? "" : "View"} ${item.name} + ${item.op != "gitList" ? "Site" : "source"} +
+ `, + )} +
+ + `; + } +} +customElements.define(AppHaxSiteDetails.tag, AppHaxSiteDetails); diff --git a/elements/app-hax/lib/v2/app-hax-site-login.js b/elements/app-hax/lib/v2/app-hax-site-login.js new file mode 100644 index 0000000000..89738955f4 --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-site-login.js @@ -0,0 +1,278 @@ +import { html, css } from "lit"; +import "@haxtheweb/simple-icon/lib/simple-icons.js"; +import "@haxtheweb/simple-icon/lib/simple-icon-lite.js"; +import { SimpleColors } from "@haxtheweb/simple-colors/simple-colors.js"; +import "@haxtheweb/rpg-character/rpg-character.js"; +import { store } from "./AppHaxStore.js"; +export class AppHaxSiteLogin extends SimpleColors { + // a convention I enjoy so you can change the tag name in 1 place + static get tag() { + return "app-hax-site-login"; + } + + // HTMLElement life-cycle, built in; use this for setting defaults + constructor() { + super(); + this.windowControllers = new AbortController(); + this.username = ""; + this.password = ""; + this.errorMSG = "Enter User name"; + this.hidePassword = true; + this.hasPass = false; + } + + // properties that you wish to use as data in HTML, CSS, and the updated life-cycle + static get properties() { + return { + ...super.properties, + username: { type: String }, + password: { type: String }, + errorMSG: { type: String }, + hidePassword: { type: Boolean }, + hasPass: { type: Boolean }, + }; + } + + firstUpdated() { + super.firstUpdated(); + setTimeout(() => { + this.shadowRoot.querySelector("input").focus(); + }, 0); + } + + // updated fires every time a property defined above changes + // this allows you to react to variables changing and use javascript to perform logic + // updated(changedProperties) { + // changedProperties.forEach((oldValue, propName) => { + // }); + // } + + // CSS - specific to Lit + static get styles() { + return [ + super.styles, + css` + :host { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + } + #inputcontainer { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + } + a { + color: red; + } + + // This does not work + #errorText > p { + visibility: hidden; + background-color: lightblue; + color: red; + font-weight: bold; + } + rpg-character { + display: block; + margin: 0px; + } + .external { + text-align: center; + } + input { + font-family: "Press Start 2P", sans-serif; + font-size: 28px; + padding: 8px; + border: 4px solid black; + border-radius: 8px; + width: 75%; + } + button { + font-family: "Press Start 2P", sans-serif; + font-size: 30px; + padding: 8px; + border: 4px solid black; + border-radius: 8px; + min-width: 50%; + margin: 16px; + } + button:focus, + button:hover { + background-color: var(--simple-colors-default-theme-green-8); + color: var(--simple-colors-default-theme-grey-1); + outline: 2px solid var(--simple-colors-default-theme-grey-1); + cursor: pointer; + } + .notyou { + padding: 8px; + } + .visibility-icon { + color: var(--simple-colors-default-theme-grey-12); + background-color: var(--simple-colors-default-theme-grey-3); + border: 2px solid var(--simple-colors-default-theme-grey-12); + position: relative; + margin-top: -44px; + margin-bottom: 20px; + margin-left: 70%; + z-index: 1; + padding: 2px; + --simple-icon-width: 26px; + --simple-icon-height: 26px; + } + `, + ]; + } + + // eslint-disable-next-line class-methods-use-this + checkUsername() { + // eslint-disable-next-line prefer-destructuring + const value = this.shadowRoot.querySelector("#username").value; + this.hidePassword = false; + this.errorMSG = ""; + this.username = value; + store.appEl.playSound("click2"); + setTimeout(() => { + this.shadowRoot.querySelector("input").focus(); + }, 0); + } + + // eslint-disable-next-line class-methods-use-this + async checkPassword() { + store.appEl.playSound("click2"); + // eslint-disable-next-line prefer-destructuring + const value = this.shadowRoot.querySelector("#password").value; + // attempt login and wait for response from the jwt-login tag via + // jwt-logged-in event @see _jwtLoggedIn + globalThis.dispatchEvent( + new CustomEvent("jwt-login-login", { + composed: true, + bubbles: true, + cancelable: false, + detail: { + username: this.username, + password: value, + }, + }), + ); + } + + // eslint-disable-next-line class-methods-use-this + reset() { + this.errorMSG = ""; + this.username = ""; + this.hasPass = false; + this.hidePassword = true; + } + + nameChange() { + this.username = this.shadowRoot.querySelector("#username").value; + } + + connectedCallback() { + super.connectedCallback(); + globalThis.addEventListener("jwt-logged-in", this._jwtLoggedIn.bind(this), { + signal: this.windowControllers.signal, + }); + globalThis.addEventListener( + "jwt-login-login-failed", + this._jwtLoginFailed.bind(this), + { signal: this.windowControllers.signal }, + ); + } + + disconnectedCallback() { + this.windowControllers.abort(); + super.disconnectedCallback(); + } + // implies that it failed to connect via the login credentials + _jwtLoginFailed(e) { + this.hidePassword = true; + this.errorMSG = "Invalid Username or Password"; + store.appEl.playSound("error"); + } + _jwtLoggedIn(e) { + if (e.detail) { + store.user = { + name: this.username, + }; + store.appEl.playSound("success"); + this.dispatchEvent( + new CustomEvent("simple-modal-hide", { + bubbles: true, + cancelable: true, + detail: {}, + }), + ); + store.toast(`Welcome ${this.username}! Let's go!`, 5000, { + hat: "construction", + }); + // just to be safe + store.appEl.reset(); + } + } + + passChange(e) { + const value = this.shadowRoot.querySelector("#password").value; + if (value) { + this.hasPass = true; + } else { + this.hasPass = false; + } + } + toggleViewPass(e) { + const password = this.shadowRoot.querySelector("#password"); + const type = + password.getAttribute("type") === "password" ? "text" : "password"; + password.setAttribute("type", type); + e.target.icon = type === "text" ? "lrn:visible" : "lrn:view-off"; + } + + render() { + return html` + +

${this.errorMSG}

+
+ ${this.hidePassword + ? html` + ` + : html`
+ Hey ${this.username}! not you? +
+ + + `} +
+ +
+
+ `; + } +} +customElements.define(AppHaxSiteLogin.tag, AppHaxSiteLogin); diff --git a/elements/app-hax/lib/v2/app-hax-steps.js b/elements/app-hax/lib/v2/app-hax-steps.js new file mode 100644 index 0000000000..f5780ce397 --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-steps.js @@ -0,0 +1,1274 @@ +/* eslint-disable lit/attribute-value-entities */ +/* eslint-disable lit/binding-positions */ +/* eslint-disable import/no-unresolved */ +/* eslint-disable import/no-extraneous-dependencies */ +/* eslint-disable class-methods-use-this */ +import { html, css, unsafeCSS } from "lit"; +import { SimpleColors } from "@haxtheweb/simple-colors/simple-colors.js"; +import { autorun, toJS } from "mobx"; +import { store } from "./AppHaxStore.js"; +import { localStorageSet } from "@haxtheweb/utils/utils.js"; +import "scrollable-component/index.js"; +import "@haxtheweb/simple-icon/lib/simple-icon-lite.js"; +import { MicroFrontendRegistry } from "@haxtheweb/micro-frontend-registry/micro-frontend-registry.js"; +import { enableServices } from "@haxtheweb/micro-frontend-registry/lib/microServices.js"; +import "./app-hax-site-button.js"; +import "./app-hax-hat-progress.js"; +import "./app-hax-button.js"; + +const homeIcon = new URL("../assets/images/Home.svg", import.meta.url).href; +const disabledCircle = new URL( + "../assets/images/DisabledCircle.svg", + import.meta.url, +).href; +const transparentCircle = new URL( + "../assets/images/TransparentCircle.svg", + import.meta.url, +).href; +const enabledCircle = new URL( + "../assets/images/EnabledCircle.svg", + import.meta.url, +).href; + +const themeContext = { + collection: ["collections-theme", "bootstrap-theme"], + blog: ["haxor-slevin"], + course: ["clean-one", "clean-two", "learn-two-theme"], + website: ["polaris-flex-theme"], + training: ["training-theme"], + import: ["clean-one", "clean-two", "learn-two-theme"], +}; +export class AppHaxSteps extends SimpleColors { + static get tag() { + return "app-hax-steps"; + } + + constructor() { + super(); + this.unlockComingSoon = false; + this.unlockTerrible = false; + this.windowControllers = new AbortController(); + this.nameTyped = ""; + this.stepRoutes = []; + this._progressReady = false; + this.step = null; + this.loaded = false; + this.themeNames = []; + this.appSettings = {}; + autorun(() => { + this.appSettings = toJS(store.appSettings); + const contextKey = toJS(store.site.structure); + this.themeNames = Object.keys(this.appSettings.themes).filter( + (value) => + contextKey && + themeContext[contextKey] && + themeContext[contextKey].includes(value), + ); + }); + autorun(() => { + this.dark = toJS(store.darkMode); + }); + autorun(() => { + localStorageSet("app-hax-step", toJS(store.step)); + }); + autorun(() => { + localStorageSet("app-hax-site", toJS(store.site)); + this.step = store.stepTest(this.step); + }); + autorun(() => { + if (toJS(store.createSiteSteps) && toJS(store.location)) { + this.step = store.stepTest(this.step); + } + }); + // routes, but only the ones that have a step property + autorun(() => { + const routes = toJS(store.routes); + this.stepRoutes = routes.filter((item) => item.step); + }); + } + + static get properties() { + return { + ...super.properties, + step: { type: Number, reflect: true }, + stepRoutes: { type: Array }, + themeNames: { type: Array }, + unlockComingSoon: { + type: Boolean, + reflect: true, + attribute: "unlock-coming-soon", + }, + unlockTerrible: { + type: Boolean, + reflect: true, + attribute: "unlock-terrible", + }, + loaded: { type: Boolean, reflect: true }, + appSettings: { type: Object }, + nameTyped: { type: String }, + }; + } + + // step 1 + chooseStructure(e) { + if (!e.target.comingSoon) { + const { value } = e.target; + store.site.structure = value; + // @note for now, auto select type and theme if making a course + // we might want to revisit this in the future + if (value === "course") { + store.site.type = "own"; + store.site.theme = "clean-one"; + } + if (value === "blog") { + store.site.type = "own"; + store.site.theme = "haxor-slevin"; + } + if (value === "collection") { + store.site.type = "own"; + store.site.theme = "collections-theme"; + } + if (value === "website") { + store.site.type = "own"; + store.site.theme = "polaris-flex-theme"; + } + if (value === "training") { + store.site.type = "own"; + store.site.theme = "training-theme"; + } + store.appEl.playSound("click2"); + } + } + + // step 2 + chooseType(e) { + if (!e.target.comingSoon) { + const { type } = e.target; + store.site.type = type; + store.appEl.playSound("click2"); + } + } + // step 2, doc import + async docxImport(e) { + if (!e.target.comingSoon) { + const { type } = e.target; + import( + "@haxtheweb/file-system-broker/lib/docx-file-system-broker.js" + ).then(async (e) => { + // enable core services + enableServices(["haxcms"]); + // get the broker for docx selection + const broker = globalThis.FileSystemBroker.requestAvailability(); + const file = await broker.loadFile("docx"); + // tee up as a form for upload + const formData = new FormData(); + formData.append("method", "site"); // this is a site based importer + formData.append("type", toJS(store.site.structure)); + formData.append("upload", file); + this.setProcessingVisual(); + const response = await MicroFrontendRegistry.call( + "@haxcms/docxToSite", + formData, + ); + store.toast(`Processed!`, 300); + // must be a valid response and have at least SOME html to bother attempting + if ( + response.status == 200 && + response.data && + response.data.contents != "" + ) { + store.items = response.data.items; + if (response.data.files) { + store.itemFiles = response.data.files; + } + // invoke a file broker for a docx file + // send to the endpoint and wait + // if it comes back with content, then we engineer details off of it + this.nameTyped = response.data.filename + .replace(".docx", "") + .replace("outline", "") + .replace(/\s/g, "") + .replace(/-/g, "") + .toLowerCase(); + setTimeout(() => { + this.shadowRoot.querySelector("#sitename").value = this.nameTyped; + this.shadowRoot.querySelector("#sitename").select(); + }, 800); + store.site.type = type; + store.site.theme = "clean-one"; + store.appEl.playSound("click2"); + } else { + store.appEl.playSound("error"); + store.toast(`File did not return valid HTML structure`); + } + }); + } + } + // evolution import + async evoImport(e) { + if (!e.target.comingSoon) { + const { type } = e.target; + import("@haxtheweb/file-system-broker/file-system-broker.js").then( + async (e) => { + // enable core services + enableServices(["haxcms"]); + // get the broker for docx selection + const broker = globalThis.FileSystemBroker.requestAvailability(); + const file = await broker.loadFile("zip"); + // tee up as a form for upload + const formData = new FormData(); + formData.append("method", "site"); // this is a site based importer + formData.append("type", toJS(store.site.structure)); + formData.append("upload", file); + // local end point + stupid JWT thing + this.setProcessingVisual(); + const response = await MicroFrontendRegistry.call( + "@haxcms/evolutionToSite", + formData, + null, + null, + "?jwt=" + toJS(store.AppHaxAPI.jwt), + ); + store.toast(`Processed!`, 300); + // must be a valid response and have at least SOME html to bother attempting + if ( + response.status == 200 && + response.data && + response.data.contents != "" + ) { + store.items = response.data.items; + // invoke a file broker for a docx file + // send to the endpoint and wait + // if it comes back with content, then we engineer details off of it + this.nameTyped = response.data.filename + .replace(".zip", "") + .replace("outline", "") + .replace(/\s/g, "") + .replace(/-/g, "") + .toLowerCase(); + setTimeout(() => { + this.shadowRoot.querySelector("#sitename").value = this.nameTyped; + this.shadowRoot.querySelector("#sitename").select(); + }, 800); + store.site.type = type; + store.site.theme = "clean-one"; + store.appEl.playSound("click2"); + } else { + store.appEl.playSound("error"); + store.toast(`File did not return valid HTML structure`); + } + }, + ); + } + } + // gitbook import endpoint + async gbImport(e) { + if (!e.target.comingSoon) { + const { type } = e.target; + let gbURL = globalThis.prompt("URL for the Gitbook repo"); + enableServices(["haxcms"]); + this.setProcessingVisual(); + const response = await MicroFrontendRegistry.call( + "@haxcms/gitbookToSite", + { md: gbURL }, + ); + store.toast(`Processed!`, 300); + // must be a valid response and have at least SOME html to bother attempting + if ( + response.status == 200 && + response.data && + response.data.contents != "" + ) { + store.items = response.data.items; + if (response.data.files) { + store.itemFiles = response.data.files; + } + // invoke a file broker for a docx file + // send to the endpoint and wait + // if it comes back with content, then we engineer details off of it + this.nameTyped = response.data.filename + .replace(/\s/g, "") + .replace(/-/g, "") + .toLowerCase(); + setTimeout(() => { + this.shadowRoot.querySelector("#sitename").value = this.nameTyped; + this.shadowRoot.querySelector("#sitename").select(); + }, 800); + store.site.type = type; + store.site.theme = "clean-one"; + store.appEl.playSound("click2"); + } else { + store.appEl.playSound("error"); + store.toast(`Repo did not return valid structure`); + } + } + } + async importFromURL(e) { + const { type, prompt, callback, param } = e.target; + if (!e.target.comingSoon) { + let promptUrl = globalThis.prompt(prompt); + enableServices(["haxcms"]); + this.setProcessingVisual(); + const params = {}; + params[param] = promptUrl; + const response = await MicroFrontendRegistry.call(callback, params); + store.toast(`Processed!`, 300); + // must be a valid response and have at least SOME html to bother attempting + if ( + response.status == 200 && + response.data && + response.data.contents != "" + ) { + store.items = response.data.items; + if (response.data.files) { + store.itemFiles = response.data.files; + } + // invoke a file broker for a docx file + // send to the endpoint and wait + // if it comes back with content, then we engineer details off of it + this.nameTyped = response.data.filename + .replace(/\s/g, "") + .replace(/-/g, "") + .toLowerCase(); + setTimeout(() => { + this.shadowRoot.querySelector("#sitename").value = this.nameTyped; + this.shadowRoot.querySelector("#sitename").select(); + }, 800); + store.site.type = type; + store.site.theme = "clean-one"; + store.appEl.playSound("click2"); + } else { + store.appEl.playSound("error"); + store.toast(`Repo did not return valid structure`); + } + } + } + // notion import endpoint + async notionImport(e) { + if (!e.target.comingSoon) { + const { type } = e.target; + let notionUrl = globalThis.prompt("URL for the Github Notion repo"); + enableServices(["haxcms"]); + this.setProcessingVisual(); + const response = await MicroFrontendRegistry.call( + "@haxcms/notionToSite", + { repoUrl: notionUrl }, + ); + store.toast(`Processed!`, 300); + // must be a valid response and have at least SOME html to bother attempting + if ( + response.status == 200 && + response.data && + response.data.contents != "" + ) { + store.items = response.data.items; + if (response.data.files) { + store.itemFiles = response.data.files; + } + // invoke a file broker for a docx file + // send to the endpoint and wait + // if it comes back with content, then we engineer details off of it + this.nameTyped = response.data.filename + .replace(/\s/g, "") + .replace(/-/g, "") + .toLowerCase(); + setTimeout(() => { + this.shadowRoot.querySelector("#sitename").value = this.nameTyped; + this.shadowRoot.querySelector("#sitename").select(); + }, 800); + store.site.type = type; + store.site.theme = "clean-one"; + store.appEl.playSound("click2"); + } else { + store.appEl.playSound("error"); + store.toast(`Repo did not return valid structure`); + } + } + } + // pressbooks import endpoint + async pressbooksImport(e) { + if (!e.target.comingSoon) { + const { type } = e.target; + import( + "@haxtheweb/file-system-broker/lib/docx-file-system-broker.js" + ).then(async (e) => { + // enable core services + enableServices(["haxcms"]); + // get the broker for docx selection + const broker = globalThis.FileSystemBroker.requestAvailability(); + const file = await broker.loadFile("html"); + // tee up as a form for upload + const formData = new FormData(); + formData.append("method", "site"); // this is a site based importer + formData.append("type", toJS(store.site.structure)); + formData.append("upload", file); + this.setProcessingVisual(); + const response = await MicroFrontendRegistry.call( + "@haxcms/pressbooksToSite", + formData, + ); + store.toast(`Processed!`, 300); + // must be a valid response and have at least SOME html to bother attempting + if ( + response.status == 200 && + response.data && + response.data.contents != "" + ) { + store.items = response.data.items; + if (response.data.files) { + store.itemFiles = response.data.files; + } + // invoke a file broker for a html file + // send to the endpoint and wait + // if it comes back with content, then we engineer details off of it + this.nameTyped = response.data.filename + .replace(".html", "") + .replace("outline", "") + .replace(/\s/g, "") + .replace(/-/g, "") + .toLowerCase(); + setTimeout(() => { + this.shadowRoot.querySelector("#sitename").value = this.nameTyped; + this.shadowRoot.querySelector("#sitename").select(); + }, 800); + store.site.type = type; + store.site.theme = "clean-one"; + store.appEl.playSound("click2"); + } else { + store.appEl.playSound("error"); + store.toast(`File did not return valid HTML structure`); + } + }); + } + } + // makes guy have hat on, shows it's doing something + setProcessingVisual() { + let loadingIcon = globalThis.document.createElement("simple-icon-lite"); + loadingIcon.icon = "hax:loading"; + loadingIcon.style.setProperty("--simple-icon-height", "40px"); + loadingIcon.style.setProperty("--simple-icon-width", "40px"); + loadingIcon.style.height = "150px"; + loadingIcon.style.marginLeft = "8px"; + store.toast(`Processing`, 60000, { + hat: "construction", + slot: loadingIcon, + }); + } + // step 3 + chooseTheme(e) { + if (!e.target.comingSoon) { + const { value } = e.target; + store.site.theme = value; + store.appEl.playSound("click2"); + } + } + + // step 4 + chooseName() { + if (this.nameTyped !== "") { + const value = this.shadowRoot.querySelector("#sitename").value; + store.site.name = value; + store.appEl.playSound("click2"); + } + } + + progressReady(e) { + if (e.detail) { + this._progressReady = true; + if (this.step === 5) { + setTimeout(() => { + this.shadowRoot.querySelector("app-hax-hat-progress").process(); + }, 300); + } + } + } + + updated(changedProperties) { + if (super.updated) { + super.updated(changedProperties); + } + changedProperties.forEach((oldValue, propName) => { + // set input field to whats in store if we have it + if (this.step === 4 && propName === "step" && this.shadowRoot) { + this.shadowRoot.querySelector("#sitename").value = toJS( + store.site.name, + ); + } + // progress + if ( + this.step === 5 && + propName === "step" && + this.shadowRoot && + this._progressReady + ) { + setTimeout(() => { + this.shadowRoot.querySelector("app-hax-hat-progress").process(); + }, 600); + } + // update the store for step when it changes internal to our step flow + if (propName === "step") { + store.step = this.step; + } + if (propName === "unlockTerrible" && this[propName]) { + Object.keys(themeContext).forEach((key) => { + themeContext[key] = [ + ...themeContext[key], + "terrible-themes", + "terrible-productionz-themes", + "terrible-outlet-themes", + "terrible-best-themes", + "terrible-resume-themes", + ]; + }); + const contextKey = toJS(store.site.structure); + this.themeNames = Object.keys(this.appSettings.themes).filter( + (value) => + contextKey && + themeContext[contextKey] && + themeContext[contextKey].includes(value), + ); + } + }); + } + + connectedCallback() { + super.connectedCallback(); + globalThis.addEventListener("resize", this.maintainScroll.bind(this), { + signal: this.windowControllers.signal, + }); + globalThis.addEventListener("popstate", this.popstateListener.bind(this), { + signal: this.windowControllers.signal, + }); + } + + disconnectedCallback() { + this.windowControllers.abort(); + super.disconnectedCallback(); + } + + // see if user navigates forward or backward while in app + popstateListener(e) { + // filter out vaadin link clicks which have a state signature + if (e.type === "popstate" && e.state === null) { + // a lot going on here, just to be safe + try { + // the delay allows clicking for step to change, process, and then testing it + setTimeout(() => { + const link = e.target.document.location.pathname.split("/").pop(); + // other links we don't care about validating state + if (link.includes("createSite")) { + const step = parseInt(link.replace("createSite-step-", "")); + if (step < store.stepTest(step)) { + this.shadowRoot.querySelector("#link-step-" + step).click(); + } else if (step > store.stepTest(step)) { + store.toast(`Please select an option`); + this.step = store.stepTest(step); + // forces state by maintaining where we are + this.shadowRoot.querySelector("#link-step-" + this.step).click(); + } + } + }, 0); + } catch (e) {} + } + } + + // account for resizing + maintainScroll() { + if (this.shadowRoot && this.step) { + this.scrollToThing(`#step-${this.step}`, { + behavior: "instant", + block: "start", + inline: "nearest", + }); + // account for an animated window drag... stupid. + setTimeout(() => { + this.scrollToThing(`#step-${this.step}`, { + behavior: "instant", + block: "start", + inline: "nearest", + }); + }, 100); + } + } + + firstUpdated(changedProperties) { + if (super.firstUpdated) { + super.firstUpdated(changedProperties); + } + setTimeout(() => { + // ensure paint issues not a factor for null step + if (this.step === null) { + this.step = 1; + } + this.scrollToThing(`#step-${this.step}`, { + behavior: "instant", + block: "start", + inline: "nearest", + }); + }, 100); + + autorun(() => { + // verify we are in the site creation process + if (toJS(store.createSiteSteps) && toJS(store.appReady)) { + const location = toJS(store.location); + if (location.route && location.route.step && location.route.name) { + // account for an animated window drag... stupid. + setTimeout(() => { + this.scrollToThing("#".concat(location.route.name), { + behavior: "smooth", + block: "start", + inline: "nearest", + }); + /// just for step 4 since it has an input + if (location.route.step === 4 && store.stepTest(4) === 4) { + setTimeout(() => { + this.shadowRoot.querySelector("#sitename").focus(); + this.scrollToThing(`#step-4`, { + behavior: "instant", + block: "start", + inline: "nearest", + }); + }, 800); + } + }, 300); // this delay helps w/ initial paint timing but also user perception + // there's a desire to have a delay especialy when tapping things of + // about 300ms + } + } + }); + autorun(() => { + if ( + this.shadowRoot && + toJS(store.createSiteSteps) && + toJS(store.appReady) + ) { + const activeItem = toJS(store.activeItem); + if ( + activeItem && + activeItem.name && + activeItem.step && + !this.__overrideProgression + ) { + this.shadowRoot + .querySelector("#link-".concat(activeItem.name)) + .click(); + } + } + }); + } + + /** + * Yet another reason Apple doesn't let us have nice things. + * This detects the NONSTANDARD BS VERSION OF SCROLLINTOVIEW + * and then ensures that it incorrectly calls to scroll into view + * WITHOUT the wonderful params that ALL OTHER BROWSERS ACCEPT + * AND MAKE OUR LIVES SO WONDERFUL TO SCROLL TO THINGS SMOOTHLY + */ + scrollToThing(sel, props) { + const isSafari = globalThis.safari !== undefined; + if ( + this.shadowRoot.querySelector(".carousel-with-snapping-item.active-step") + ) { + this.shadowRoot + .querySelector(".carousel-with-snapping-item.active-step") + .classList.remove("active-step"); + } + if (isSafari) { + this.shadowRoot.querySelector(sel).scrollIntoView(); + } else { + this.shadowRoot.querySelector(sel).scrollIntoView(props); + } + this.shadowRoot.querySelector(sel).classList.add("active-step"); + } + + static get styles() { + return [ + super.styles, + css` + :host { + display: block; + } + scrollable-component { + --scrollbar-width: 0px; + --scrollbar-height: 0px; + --scrollbar-padding: 0; + --viewport-overflow-x: hidden; + overflow: hidden; + } + #grid-container { + display: grid; + grid-template-columns: 200px 200px 200px; + background: transparent; + } + .carousel-with-snapping-track { + display: grid; + grid-auto-flow: column; + grid-gap: 30px; + } + .carousel-with-snapping-item { + display: flex; + flex-direction: column; + align-items: center; + justify-content: normal; + scroll-snap-align: center; + scroll-snap-stop: always; + scrollbar-gutter: stable; + width: var(--viewport-width); + font-size: 1.5rem; + text-align: center; + overflow-x: hidden; + max-height: 60vh; + padding-top: 1vh; + } + #step-links { + padding: 0; + margin: 0; + } + ul, + li { + list-style: none; + } + li { + vertical-align: middle; + display: inline-flex; + margin: 5px; + } + li.step { + border-radius: 50%; + background-color: transparent; + } + li a { + font-size: 12px; + color: var(--simple-colors-default-theme-grey-12, white); + text-decoration: none; + padding: 5px; + width: 20px; + height: 20px; + line-height: 20px; + margin: 0; + display: block; + border: 0; + border-radius: 50%; + background-repeat: no-repeat; + background-size: 30px 30px; + background-color: var(--simple-colors-default-theme-grey-1, white); + background-image: url("${unsafeCSS(enabledCircle)}"); + transition: + 0.3s ease-in-out background, + 0.3s ease-in-out color; + transition-delay: 0.6s, 0.3s; + } + li a[disabled] { + background-image: url("${unsafeCSS(disabledCircle)}"); + pointer-events: none; + color: var(--simple-colors-default-theme-grey-7, grey); + user-select: none; + } + li[disabled] { + background-color: grey; + } + li.active-step a { + background-color: orange; + background-image: url("${unsafeCSS(transparentCircle)}"); + } + app-hax-button { + padding: 10px 0px 10px 0px; + background: transparent; + } + #theme-container { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + } + img { + pointer-events: none; + } + #themeContainer { + width: 70vw; + height: 55vh; + } + .theme-button { + background-color: transparent; + color: var(--simple-colors-default-theme-grey-12, white); + border: none; + margin: 8px; + padding: 8px; + width: 245px; + } + + .theme-button div { + font-family: "Press Start 2P", sans-serif; + font-size: 14px; + margin-top: 12px; + } + .theme-button:focus, + .theme-button:hover { + outline: 4px solid var(--app-hax-accent-color, var(--accent-color)); + outline-offset: 4px; + background-color: transparent; + border: none; + cursor: pointer; + } + #sitename { + font-family: "Press Start 2P", sans-serif; + font-size: 32px; + padding: 8px; + width: 40vw; + } + #homebtn { + --simple-icon-height: 30px; + --simple-icon-width: 30px; + border-radius: 50%; + cursor: pointer; + background-color: var(--simple-colors-default-theme-grey-1, white); + } + .homelnk { + background-image: none; + display: flex; + padding: 0; + margin: 0; + height: 30px; + width: 30px; + } + app-hax-site-button { + justify-content: center; + --app-hax-site-button-width: 35vw; + --app-hax-site-button-min-width: 240px; + } + app-hax-hat-progress { + height: 400px; + width: 400px; + display: block; + } + + @media (max-width: 800px) { + .theme-button { + width: unset; + padding: 0; + } + .theme-button div { + font-size: 12px; + margin-top: 8px; + } + .theme-button img { + height: 70px; + } + app-hax-site-button { + width: 320px; + max-width: 60vw; + --app-hax-site-button-font-size: 2.5vw; + } + #sitename { + width: 70vw; + font-size: 20px; + } + #grid-container { + grid-template-columns: 150px 150px 150px; + } + } + @media (max-height: 600px) { + .carousel-with-snapping-item { + padding-top: 4px; + max-height: 57vh; + } + #sitename { + width: 40vw; + font-size: 14px; + } + app-hax-hat-progress { + transform: scale(0.5); + margin-top: -18vh; + } + } + @media (max-width: 500px) { + app-hax-hat-progress { + transform: scale(0.5); + margin-top: -15vh; + } + } + @media (max-height: 400px) { + .carousel-with-snapping-item { + padding-top: 4px; + max-height: 40vh; + } + app-hax-hat-progress { + transform: scale(0.3); + } + .carousel-with-snapping-item.active-step app-hax-hat-progress { + position: fixed; + top: 20%; + left: 20%; + } + } + `, + ]; + } + + progressFinished(e) { + if (e.detail) { + this.loaded = true; + store.appEl.playSound("success"); + // focus the button for going to the site + e.target.shadowRoot.querySelector(".game").focus(); + this.scrollToThing(`#step-${this.step}`, { + behavior: "instant", + block: "start", + inline: "nearest", + }); + } + } + + typeKey() { + this.nameTyped = this.shadowRoot.querySelector("#sitename").value; + } + keydown(e) { + // some trapping for common characters that make us sad + if ( + [ + " ", + "/", + "\\", + "&", + "#", + "?", + "+", + "=", + "{", + "}", + "|", + "^", + "~", + "[", + "]", + "`", + '"', + "'", + ].includes(e.key) + ) { + store.appEl.playSound("error"); + store.toast(`"${e.key}" is not allowed. Use - or _`); + e.preventDefault(); + } else if (e.key === "Enter") { + this.chooseName(); + } else if ( + ["ArrowUp", "ArrowRight", "ArrowDown", "ArrowLeft"].includes(e.key) + ) { + // do nothing, directional keys for modifying word + } else { + store.appEl.playSound("click"); + } + } + + stepLinkClick(e) { + const clickedStep = parseInt(e.target.getAttribute("data-step"), 10); + if (this.step < clickedStep) { + e.preventDefault(); + } else if (e.target.getAttribute("data-step") === null) { + store.createSiteSteps = false; + store.appMode = "home"; + this.nameTyped = ""; + store.siteReady = false; + store.site.structure = null; + store.site.type = null; + store.site.theme = null; + store.site.name = null; + } + // means user went backwards + else if (this.step > clickedStep) { + this.nameTyped = ""; + store.siteReady = false; + if (clickedStep === 1) { + store.site.structure = null; + store.site.type = null; + store.site.theme = null; + store.site.name = null; + } else if (clickedStep === 2) { + store.site.type = null; + store.site.theme = null; + store.site.name = null; + } else if (clickedStep === 3) { + store.site.theme = null; + store.site.name = null; + } else if (clickedStep === 4) { + store.site.name = null; + } + this.step = clickedStep; + } + } + + renderTypes(step) { + const structure = toJS(store.site.structure); + var template = html``; + switch (structure) { + case "collection": + template = html` + + + `; + break; + default: + case "course": + template = html` + `; + break; + case "website": + template = html` `; + break; + case "training": + template = html` `; + break; + case "blog": + template = html` `; + break; + case "import": + template = html` + + + + + + + `; + break; + } + return template; + } + + render() { + return html` +
+ + + + +
+ `; + } +} +customElements.define(AppHaxSteps.tag, AppHaxSteps); diff --git a/elements/app-hax/lib/v2/app-hax-toast.js b/elements/app-hax/lib/v2/app-hax-toast.js new file mode 100644 index 0000000000..814abcdb3a --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-toast.js @@ -0,0 +1,60 @@ +import { autorun, toJS } from "mobx"; +import { store } from "./AppHaxStore.js"; +import { RPGCharacterToast } from "../rpg-character-toast/rpg-character-toast.js"; + +export class AppHaxToast extends RPGCharacterToast { + static get tag() { + return "app-hax-toast"; + } + + constructor() { + super(); + this.windowControllers = new AbortController(); + autorun(() => { + this.userName = toJS(store.user.name); + }); + autorun(() => { + this.darkMode = toJS(store.darkMode); + }); + } + + connectedCallback() { + super.connectedCallback(); + globalThis.addEventListener( + "haxcms-toast-hide", + this.hideSimpleToast.bind(this), + { signal: this.windowControllers.signal }, + ); + + globalThis.addEventListener( + "haxcms-toast-show", + this.showSimpleToast.bind(this), + { signal: this.windowControllers.signal }, + ); + } + + hideSimpleToast(e) { + this.hide(); + } + + /** + * life cycle, element is removed from the DOM + */ + disconnectedCallback() { + this.windowControllers.abort(); + super.disconnectedCallback(); + } +} +customElements.define(AppHaxToast.tag, AppHaxToast); +globalThis.AppHaxToast = globalThis.AppHaxToast || {}; + +globalThis.AppHaxToast.requestAvailability = () => { + if (!globalThis.AppHaxToast.instance) { + globalThis.AppHaxToast.instance = globalThis.document.createElement( + AppHaxToast.tag, + ); + globalThis.document.body.appendChild(globalThis.AppHaxToast.instance); + } + return globalThis.AppHaxToast.instance; +}; +export const AppHaxToastInstance = globalThis.AppHaxToast.requestAvailability(); diff --git a/elements/app-hax/lib/v2/app-hax-top-bar.js b/elements/app-hax/lib/v2/app-hax-top-bar.js new file mode 100644 index 0000000000..300145aa56 --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-top-bar.js @@ -0,0 +1,130 @@ +// dependencies / things imported +import { LitElement, html, css } from "lit"; +import "./app-hax-wired-toggle.js"; +import { SimpleTourFinder } from "@haxtheweb/simple-popover/lib/SimpleTourFinder.js"; + +// top bar of the UI +export class AppHaxTopBar extends LitElement { + // a convention I enjoy so you can change the tag name in 1 place + static get tag() { + return "app-hax-top-bar"; + } + + constructor() { + super(); + this.editMode = false; + } + + static get properties() { + return { + editMode: { + type: Boolean, + reflect: true, + attribute: "edit-mode", + }, + }; + } + + static get styles() { + return css` + :host { + --bg-color: var(--app-hax-background-color); + --accent-color: var(--app-hax-accent-color); + --top-bar-height: 48px; + display: block; + height: var(--top-bar-height); + } + + /* @media (prefers-color-scheme: dark) { + :root { + --accent-color: white; + color: var(--accent-color); + + } + + :host { + background-color: black; + } + } */ + + .topBar { + overflow: hidden; + background-color: var(--bg-color); + color: var(--accent-color); + height: var(--top-bar-height); + text-align: center; + vertical-align: middle; + border-bottom: 3px solid var(--app-hax-accent-color); + display: grid; + grid-template-columns: 32.5% 35% 32.5%; + transition: border-bottom 0.6s ease-in-out; + } + + :host([edit-mode]) .topBar { + border-bottom: 6px solid black; + } + + /* .topBar > div { + background-color: rgba(255, 255, 255, 0.8); + border: 1px solid black; + } */ + + .topBar .left { + text-align: left; + height: var(--top-bar-height); + vertical-align: text-top; + } + + .topBar .center { + text-align: center; + height: var(--top-bar-height); + vertical-align: text-top; + } + + .topBar .right { + text-align: right; + height: var(--top-bar-height); + vertical-align: text-top; + } + @media (max-width: 640px) { + .topBar .left { + opacity: 0; + pointer-events: none; + } + .topBar .center { + text-align: left; + } + .topBar .right { + text-align: left; + } + #home { + display: none; + } + app-hax-search-bar { + display: none; + } + .topBar { + grid-template-columns: 0% 35% 65%; + display: inline-grid; + } + } + `; + } + + render() { + return html` +
+
+ +
+
+ +
+
+ +
+
+ `; + } +} +customElements.define(AppHaxTopBar.tag, AppHaxTopBar); diff --git a/elements/app-hax/lib/v2/app-hax-user-menu-button.js b/elements/app-hax/lib/v2/app-hax-user-menu-button.js new file mode 100644 index 0000000000..a3870224ac --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-user-menu-button.js @@ -0,0 +1,70 @@ +// TODO: Text-overflow-ellipses + +// dependencies / things imported +import { LitElement, html, css } from "lit"; + +export class AppHaxUserMenuButton extends LitElement { + // a convention I enjoy so you can change the tag name in 1 place + static get tag() { + return "app-hax-user-menu-button"; + } + + constructor() { + super(); + this.icon = "account-circle"; + this.label = "Default"; + } + + static get properties() { + return { + icon: { type: String }, + label: { type: String }, + }; + } + + static get styles() { + return css` + :host { + font-family: "Press Start 2P", sans-serif; + text-align: center; + width: 100%; + --background-color: var(--app-hax-background-color); + --accent-color: var(--app-hax-accent-color); + } + + .menu-button { + display: block; + width: 100%; + border: 2px solid var(--accent-color); + margin: 0; + padding: 8px; + font-size: 16px; + text-align: left; + color: var(--accent-color); + background-color: var(--background-color); + cursor: pointer; + } + + .menu-button:hover, + .menu-button:active, + .menu-button:focus { + background-color: var(--accent-color); + color: var(--background-color); + } + + .icon { + padding-right: 16px; + } + `; + } + + render() { + return html` + + `; + } +} +customElements.define(AppHaxUserMenuButton.tag, AppHaxUserMenuButton); diff --git a/elements/app-hax/lib/v2/app-hax-user-menu.js b/elements/app-hax/lib/v2/app-hax-user-menu.js new file mode 100644 index 0000000000..8b03e726e3 --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-user-menu.js @@ -0,0 +1,110 @@ +// TODO: Create app-hax-user-menu-button to be tossed into this +// TODO: Create prefix and suffix sections for sound/light toggles and other shtuff + +// dependencies / things imported +import { LitElement, html, css } from "lit"; + +export class AppHaxUserMenu extends LitElement { + // a convention I enjoy so you can change the tag name in 1 place + static get tag() { + return "app-hax-user-menu"; + } + + constructor() { + super(); + this.isOpen = false; + this.icon = "account-circle"; + } + + static get properties() { + return { + isOpen: { type: Boolean, reflect: true, attribute: "is-open" }, + icon: { type: String, reflect: true }, + }; + } + + static get styles() { + return css` + :host { + font-family: "Press Start 2P", sans-serif; + text-align: center; + display: inline-block; + margin: 0px; + padding: 0px; + } + + .entireComponent { + max-height: 48px; + } + + .menuToggle { + cursor: pointer; + max-height: 48px; + } + + .user-menu { + display: none; + } + + .user-menu.open { + display: block; + top: 50px; + right: 0px; + position: absolute; + border: 1px solid var(--app-hax-accent-color); + background-color: var(--app-hax-background-color); + } + + .user-menu.open ::slotted(*) { + display: block; + width: 100%; + margin: 0; + font-size: 16px; + text-align: left; + font-family: "Press Start 2P", sans-serif; + color: var(--app-hax-accent-color); + background-color: var(--app-hax-background-color); + } + + .user-menu.open .main-menu ::slotted(*:hover), + .user-menu.open .main-menu ::slotted(*:active), + .user-menu.open .main-menu ::slotted(*:focus) { + background-color: var(--app-hax-background-color-active); + color: var(--app-hax-background-color); + } + + .user-menu ::slotted(button) { + cursor: pointer; + } + + .user-menu ::slotted(*) simple-icon-lite { + padding-right: 16px; + } + `; + } + + render() { + return html` +
+ + +
+
+ +
+ +
+ +
+
+
+ `; + } +} +customElements.define(AppHaxUserMenu.tag, AppHaxUserMenu); diff --git a/elements/app-hax/lib/v2/app-hax-wired-toggle.js b/elements/app-hax/lib/v2/app-hax-wired-toggle.js new file mode 100644 index 0000000000..5d3b2d486e --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-wired-toggle.js @@ -0,0 +1,47 @@ +import { autorun, toJS } from "mobx"; +import { html } from "lit"; +import { store } from "./AppHaxStore.js"; +import { WiredDarkmodeToggle } from "../wired-darkmode-toggle/wired-darkmode-toggle.js"; +import { SimpleTourFinder } from "@haxtheweb/simple-popover/lib/SimpleTourFinder.js"; + +export class AppHAXWiredToggle extends SimpleTourFinder(WiredDarkmodeToggle) { + constructor() { + super(); + this.tourName = "hax"; + autorun(() => { + this.checked = toJS(store.darkMode); + }); + } + + static get tag() { + return "app-hax-wired-toggle"; + } + + updated(changedProperties) { + if (super.updated) { + super.updated(changedProperties); + } + changedProperties.forEach((oldValue, propName) => { + if (propName === "checked" && oldValue !== undefined) { + store.darkMode = this[propName]; + store.appEl.playSound("click"); + } + }); + } + render() { + return html` +
+ ${super.render()} +
+ You can toggle your user interface between "light" and "dark" for you + viewing enjoyment. +
+
+ `; + } +} +customElements.define(AppHAXWiredToggle.tag, AppHAXWiredToggle); From 96fd472b2bdb846a902315d9e883792a7eb883a1 Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Mon, 10 Feb 2025 14:09:28 -0500 Subject: [PATCH 002/166] initial commit --- elements/app-hax/lib/v2/AppHaxBackendAPI.js | 259 ++++ elements/app-hax/lib/v2/AppHaxRouter.js | 81 ++ elements/app-hax/lib/v2/AppHaxStore.js | 320 +++++ elements/app-hax/lib/v2/app-hax-button.js | 282 ++++ .../app-hax/lib/v2/app-hax-hat-progress.js | 232 +++ elements/app-hax/lib/v2/app-hax-label.js | 94 ++ elements/app-hax/lib/v2/app-hax-search-bar.js | 155 ++ .../app-hax/lib/v2/app-hax-search-results.js | 196 +++ elements/app-hax/lib/v2/app-hax-site-bar.js | 208 +++ .../app-hax/lib/v2/app-hax-site-button.js | 157 ++ .../app-hax/lib/v2/app-hax-site-details.js | 379 +++++ elements/app-hax/lib/v2/app-hax-site-login.js | 278 ++++ elements/app-hax/lib/v2/app-hax-steps.js | 1274 +++++++++++++++++ elements/app-hax/lib/v2/app-hax-toast.js | 60 + elements/app-hax/lib/v2/app-hax-top-bar.js | 130 ++ .../lib/v2/app-hax-user-menu-button.js | 70 + elements/app-hax/lib/v2/app-hax-user-menu.js | 110 ++ .../app-hax/lib/v2/app-hax-wired-toggle.js | 47 + 18 files changed, 4332 insertions(+) create mode 100644 elements/app-hax/lib/v2/AppHaxBackendAPI.js create mode 100644 elements/app-hax/lib/v2/AppHaxRouter.js create mode 100644 elements/app-hax/lib/v2/AppHaxStore.js create mode 100644 elements/app-hax/lib/v2/app-hax-button.js create mode 100644 elements/app-hax/lib/v2/app-hax-hat-progress.js create mode 100644 elements/app-hax/lib/v2/app-hax-label.js create mode 100644 elements/app-hax/lib/v2/app-hax-search-bar.js create mode 100644 elements/app-hax/lib/v2/app-hax-search-results.js create mode 100644 elements/app-hax/lib/v2/app-hax-site-bar.js create mode 100644 elements/app-hax/lib/v2/app-hax-site-button.js create mode 100644 elements/app-hax/lib/v2/app-hax-site-details.js create mode 100644 elements/app-hax/lib/v2/app-hax-site-login.js create mode 100644 elements/app-hax/lib/v2/app-hax-steps.js create mode 100644 elements/app-hax/lib/v2/app-hax-toast.js create mode 100644 elements/app-hax/lib/v2/app-hax-top-bar.js create mode 100644 elements/app-hax/lib/v2/app-hax-user-menu-button.js create mode 100644 elements/app-hax/lib/v2/app-hax-user-menu.js create mode 100644 elements/app-hax/lib/v2/app-hax-wired-toggle.js diff --git a/elements/app-hax/lib/v2/AppHaxBackendAPI.js b/elements/app-hax/lib/v2/AppHaxBackendAPI.js new file mode 100644 index 0000000000..2adea8defc --- /dev/null +++ b/elements/app-hax/lib/v2/AppHaxBackendAPI.js @@ -0,0 +1,259 @@ +import { LitElement, html } from "lit"; +import { localStorageGet } from "@haxtheweb/utils/utils.js"; +import "@haxtheweb/jwt-login/jwt-login.js"; +import { toJS, autorun } from "mobx"; +import { store } from "./AppHaxStore.js"; +import { SimpleColorsSharedStylesGlobal } from "@haxtheweb/simple-colors-shared-styles/simple-colors-shared-styles.js"; +import { SimpleIconIconsetsManifest } from "@haxtheweb/simple-icon/lib/simple-iconset-manifest.js"; +// this element will manage all connectivity to the backend +// this way everything is forced to request through calls to this +// so that it doesn't get messy down below in state +export class AppHaxBackendAPI extends LitElement { + static get tag() { + return "app-hax-backend-api"; + } + + constructor() { + super(); + this.jwt = localStorageGet("jwt", null); + this.method = + window && globalThis.appSettings && globalThis.appSettings.demo + ? "GET" + : "POST"; + this.basePath = "/"; + this.lastResponse = {}; + this.appSettings = {}; + autorun(() => { + this.appSettings = toJS(store.appSettings); + // allow setting in session driven environments + if (this.appSettings.method) { + this.method = this.appSettings.method; + } + if (this.appSettings.jwt) { + this.jwt = this.appSettings.jwt; + } + }); + autorun(() => { + this.token = toJS(store.token); + }); + } + + static get properties() { + return { + jwt: { type: String }, + basePath: { type: String, attribute: "base-path" }, + appSettings: { type: Object }, + method: { type: String }, + token: { type: String }, + }; + } + + render() { + return html``; + } + + // failed to get valid JWT, wipe current + jwtFailed(e) { + this.jwt = null; + this.token = null; + } + // event meaning we either got or removed the jwt + async jwtChanged(e) { + this.jwt = e.detail.value; + // sanity check we actually got a response + // this fires every time our JWT changes so it can update even after already logging in + // like hitting refresh or coming back to the app + if (!this.__loopBlock && this.jwt) { + this.__loopBlock = true; + const userData = await this.makeCall("getUserDataPath"); + if (userData && userData.data) { + store.user = { + name: userData.data.userName, + }; + this.__loopBlock = false; + } + } + } + + async makeCall(call, data = {}, save = false, callback = false) { + if (this.appSettings && this.appSettings[call]) { + var urlRequest = `${this.basePath}${this.appSettings[call]}`; + var options = { + method: this.method, + }; + if (this.jwt) { + data.jwt = this.jwt; + } + if (this.token) { + data.token = this.token; + } + // encode in search params or body of the request + if (this.method === "GET") { + urlRequest += "?" + new URLSearchParams(data).toString(); + } else { + options.body = JSON.stringify(data); + } + const response = await fetch(`${urlRequest}`, options).then( + (response) => { + if (response.ok) { + return response.json(); + } else if (response.status === 401) { + // call not allowed, log out bc unauthorized + globalThis.dispatchEvent( + new CustomEvent("jwt-login-logout", { + composed: true, + bubbles: true, + cancelable: false, + detail: true, + }), + ); + } + // we got a miss, logout cause something is wrong + else if (response.status === 404) { + // call not allowed, log out bc unauthorized + globalThis.dispatchEvent( + new CustomEvent("jwt-login-logout", { + composed: true, + bubbles: true, + cancelable: false, + detail: true, + }), + ); + } else if (response.status === 403) { + // if this was a 403 it should be because of a bad jwt + // or out of date one. let's kick off a call to get a new one + // hopefully from the timing token, knowing this ALSO could kick + // over here. + globalThis.dispatchEvent( + new CustomEvent("jwt-login-refresh-token", { + composed: true, + bubbles: true, + cancelable: false, + detail: { + element: { + obj: this, + callback: "refreshRequest", + params: [call, data, save, callback], + }, + }, + }), + ); + } + return {}; + }, + ); + // ability to save the output if this is being done as a bg task + // that way we can get access to the result later on + if (save) { + this.lastResponse[call] = response; + } + if (callback) { + callback(); + } + return response; + } + } + + /** + * Attempt to salvage the request that was kicked off + * when our JWT needed refreshed + */ + refreshRequest(jwt, response) { + const { call, data, save, callback } = response; + // force the jwt to be the updated jwt + // this helps avoid any possible event timing issue + if (jwt) { + this.jwt = jwt; + this.makeCall(call, data, save, callback); + } + } + + // set instance of API in store + firstUpdated(changedProperties) { + if (super.firstUpdated) { + super.firstUpdated(changedProperties); + } + // set store refernece to this singleton + store.AppHaxAPI = this; + // site creation roped into the promise list + // after knowing our data structure since we'll definitely call this + store.newSitePromiseList = [ + ...store.newSitePromiseList, + async () => + await this.makeCall("createSite", this._formatSitePostData(), true), + ]; + } + // just easier to read here + _formatSitePostData() { + const site = toJS(store.site); + // html contents if we are starting from a file import, otherwise its null + const items = toJS(store.items); + const itemFiles = toJS(store.itemFiles); + const colors = Object.keys(SimpleColorsSharedStylesGlobal.colors); + const buildData = { + site: { + name: site.name, + description: `${site.type} ${site.structure}`, + theme: site.theme, + }, + build: { + type: site.type, + structure: site.structure, + items: items, + files: itemFiles, + }, + theme: { + // select a random color + color: colors[Math.floor(Math.random() * colors.length)], + // select a random av icon + icon: `${SimpleIconIconsetsManifest[0].name}:${ + SimpleIconIconsetsManifest[0].icons[ + Math.floor( + Math.random() * SimpleIconIconsetsManifest[0].icons.length, + ) + ] + }`, + }, + }; + return buildData; + } + + updated(changedProperties) { + if (super.updated) { + super.updated(changedProperties); + } + changedProperties.forEach((oldValue, propName) => { + if (propName === "jwt") { + store.jwt = this[propName]; + } + if (propName === "token") { + store.token = this[propName]; + } + }); + } +} + +globalThis.AppHaxAPI = globalThis.AppHaxAPI || {}; + +globalThis.AppHaxAPI.requestAvailability = () => { + if (!globalThis.AppHaxAPI.instance) { + globalThis.AppHaxAPI.instance = globalThis.document.createElement( + AppHaxBackendAPI.tag, + ); + globalThis.document.body.appendChild(globalThis.AppHaxAPI.instance); + } + return globalThis.AppHaxAPI.instance; +}; +export const AppHaxAPI = globalThis.AppHaxAPI.requestAvailability(); + +customElements.define(AppHaxBackendAPI.tag, AppHaxBackendAPI); diff --git a/elements/app-hax/lib/v2/AppHaxRouter.js b/elements/app-hax/lib/v2/AppHaxRouter.js new file mode 100644 index 0000000000..169c3758fa --- /dev/null +++ b/elements/app-hax/lib/v2/AppHaxRouter.js @@ -0,0 +1,81 @@ +import { Router } from "@vaadin/router"; +import { autorun, toJS } from "mobx"; +import { store } from "./AppHaxStore.js"; + +/** + * `app-hax-router` + */ +export class AppHaxRouter extends HTMLElement { + /** + * Store the tag name to make it easier to obtain directly. + */ + + static get tag() { + return "app-hax-router"; + } + /** + * ready life cycle + */ + + constructor() { + super(); + // create router + const options = {}; + if (this.baseURI) { + options.baseUrl = this.baseURI; + } + this.windowControllers = new AbortController(); + this.router = new Router(this, options); + autorun(() => { + this._updateRouter(toJS(store.routes)); + }); + autorun(() => { + const manifest = toJS(store.manifest); + const baseURI = toJS(store.AppHaxAPI.basePath); + if (manifest && manifest.items && manifest.items.length > 0) { + const siteItemRoutes = manifest.items.map((i) => { + return { + path: i.slug.replace(baseURI, ""), // replacement of the basePath ensures routes match in haxiam / subdirs + slug: i.slug, + name: i.id, + component: `fake-${i.id}-e`, + }; + }); + store.routes = [...siteItemRoutes].concat(store.baseRoutes); + } + }); + } + + connectedCallback() { + globalThis.addEventListener( + "vaadin-router-location-changed", + this._routerLocationChanged.bind(this), + { signal: this.windowControllers.signal }, + ); + } + /** + * Detached life cycle + */ + + disconnectedCallback() { + this.windowControllers.abort(); + } + + /** + * Update the router based on a manifest. + */ + _updateRouter(routerItems) { + this.router.setRoutes([...routerItems]); + } + /** + * React to page changes in the vaadin router and convert it + * to a change in the mobx store. + * @param {event} e + */ + + // eslint-disable-next-line class-methods-use-this + _routerLocationChanged(e) { + store.location = e.detail.location; + } +} +customElements.define(AppHaxRouter.tag, AppHaxRouter); diff --git a/elements/app-hax/lib/v2/AppHaxStore.js b/elements/app-hax/lib/v2/AppHaxStore.js new file mode 100644 index 0000000000..90f7717fdb --- /dev/null +++ b/elements/app-hax/lib/v2/AppHaxStore.js @@ -0,0 +1,320 @@ +/* eslint-disable max-classes-per-file */ +import { localStorageGet, localStorageSet } from "@haxtheweb/utils/utils.js"; +import { observable, makeObservable, computed, configure } from "mobx"; +import { DeviceDetails } from "@haxtheweb/replace-tag/lib/PerformanceDetect.js"; +configure({ enforceActions: false }); // strict mode off + +class Store { + constructor() { + this.badDevice = null; + this.evaluateBadDevice(); + this.location = null; + this.token = + globalThis.appSettings && globalThis.appSettings.token + ? globalThis.appSettings.token + : null; + this.version = "0.0.0"; + this.items = null; + this.itemFiles = null; + this.refreshSiteList = true; + this.createSiteSteps = false; + fetch(new URL("../../../haxcms-elements/package.json", import.meta.url)) + .then((response) => response.json()) + .then((obj) => (this.version = obj.version)); + this.appSettings = globalThis.appSettings || {}; + // defer to local if we have it for JWT + if (this.appSettings.jwt) { + localStorageSet("jwt", this.appSettings.jwt); + } + this.jwt = localStorageGet("jwt", null); + // placeholder for when the actual API Backend gets plugged in here + this.AppHaxAPI = {}; + this.newSitePromiseList = [ + () => import("@haxtheweb/i18n-manager/lib/I18NMixin.js"), + () => import("@haxtheweb/wc-autoload/wc-autoload.js"), + () => import("@haxtheweb/replace-tag/replace-tag.js"), + () => import("@haxtheweb/utils/utils.js"), + () => import("@haxtheweb/grid-plate/grid-plate.js"), + () => import("@haxtheweb/simple-fields/simple-fields.js"), + () => import("mobx/dist/mobx.esm.js"), + () => import("@haxtheweb/h-a-x/h-a-x.js"), + () => import("@haxtheweb/haxcms-elements/lib/core/haxcms-site-store.js"), + () => import("@haxtheweb/haxcms-elements/lib/core/haxcms-site-router.js"), + () => + import("@haxtheweb/haxcms-elements/lib/core/haxcms-site-builder.js"), + () => + import("@haxtheweb/haxcms-elements/lib/core/HAXCMSLitElementTheme.js"), + () => import("@haxtheweb/haxcms-elements/lib/core/haxcms-site-editor.js"), + () => + import("@haxtheweb/haxcms-elements/lib/core/haxcms-editor-builder.js"), + () => + import("@haxtheweb/haxcms-elements/lib/core/haxcms-site-editor-ui.js"), + ]; + this.appEl = null; + this.appReady = false; + this.soundStatus = localStorageGet("app-hax-soundStatus", true); + // If user is new, make sure they are on step 1 + this.appMode = "search"; + this.activeSiteOp = null; + this.activeSiteId = null; + this.baseRoutes = [ + { + path: "createSite-step-1", + component: "fake", + step: 1, + name: "step-1", + label: "New Journey", + statement: "What sort of journey is it?", + title: "Step 1: Create", + }, + { + path: "createSite-step-2", + component: "fake", + step: 2, + name: "step-2", + label: "Structure", + statement: "How is the :structure organized?", + title: "Step 2: Structure", + }, + { + path: "createSite-step-3", + component: "fake", + step: 3, + name: "step-3", + label: "Theme select", + statement: "What your :structure feels like?", + title: "Step 3: Theme", + }, + { + path: "createSite-step-4", + component: "fake", + step: 4, + name: "step-4", + label: "Name", + statement: "What do you want to call your site?", + title: "Step 4: Name", + }, + { + path: "createSite-step-5", + component: "fake", + step: 5, + name: "step-5", + label: "Building..", + statement: "Getting your :structure ready to launch", + title: "Step 5: Building site", + }, + { + path: "home", + component: "fake", + name: "home", + label: "Welcome back", + statement: "Let's go on a HAX Journey", + title: "Home", + }, + { + path: "index.html", + component: "fake", + name: "home", + label: "Welcome back", + statement: "Let's go on a HAX Journey", + title: "Home", + }, + { + path: "index.php", + component: "fake", + name: "home", + label: "Welcome back", + statement: "Let's go on a HAX Journey", + title: "Home", + }, + { + path: "search", + component: "fake", + name: "search", + label: "Search", + statement: "Discover active adventures", + title: "Search sites", + }, + { + path: "/", + component: "fake", + name: "welcome", + label: "Welcome", + statement: "Let's build something awesome!", + title: "Home", + }, + { + path: "/(.*)", + component: "fake", + name: "404", + label: "404 :[", + statement: "it's not you.. it's me", + title: "FoUr Oh FoUr", + }, + ]; + this.routes = this.baseRoutes; + this.siteReady = false; + this.manifest = {}; + this.searchTerm = ""; + this.user = { + name: "", + }; + this.site = !localStorageGet("app-hax-site") + ? { structure: null, type: null, theme: null, name: null } + : localStorageGet("app-hax-site"); + this.step = this.stepTest(null); + this.darkMode = !localStorageGet("app-hax-darkMode") + ? false + : localStorageGet("app-hax-darkMode"); + + makeObservable(this, { + // internal state for routing + location: observable.ref, // router location in url + routes: observable, // routes that are valid + // internal state requirements + appSettings: observable, // endpoint connections to the backend app + appReady: observable, // all ready to paint + appMode: observable, // mode the app is in. search, create, etc + createSiteSteps: observable, // if we're making a site or in another part of app + step: observable, // step that we're on in our build + site: observable, // information about the site being created + newSitePromiseList: observable, + items: observable, // site items / structure from a docx micro if option selected + itemFiles: observable, // files related to the items to be imported from another site format + version: observable, // version of haxcms FRONTEND as per package.json + // user related data + jwt: observable, // JSON web token + token: observable, // XSS prevention token + manifest: observable, // sites the user has access to + user: observable, // user object like name after login + // user preferences + searchTerm: observable, // current search term for filtering own list of sites + darkMode: observable, // dark mode pref + soundStatus: observable, // toggle sounds on and off + activeItem: computed, // active item is route + isNewUser: computed, // if they are new so we can auto kick to createSiteSteps if needed + isLoggedIn: computed, // basic bool for logged in + badDevice: observable, // if we have a terrible device or not based on detected speeds + activeSiteOp: observable, // active operation for sites if working with them + activeSiteId: observable, // active Item if working w/ sites + activeSite: computed, // activeSite from ID + siteReady: observable, // implied that we had a site and then it got built and we can leave app + refreshSiteList: observable, // used to force state to refresh sitelisting + }); + } + setPageTitle(title) { + if (globalThis.document.querySelector("title")) { + globalThis.document.querySelector("title").innerText = `HAX: ${title}`; + } + } + // refresh + refreshSiteListing() { + this.refreshSiteList = false; + // @todo this causes a reactive feedbackloop in + this.refreshSiteList = true; + } + // filter to just get data about THIS site + get activeSite() { + if (this.activeSiteId && this.manifest && this.manifest.items) { + const sites = this.manifest.items.filter( + (item) => item.id === this.activeSiteId, + ); + if (sites.length === 1) { + return sites.pop(); + } + return null; + } + } + // see if this device is poor + async evaluateBadDevice() { + this.badDevice = await DeviceDetails.badDevice(); + if (this.badDevice === true) { + this.soundStatus = false; + } + } + // validate if they are on the right step via state + // otherwise we need to force them to the correct step + stepTest(current) { + if (this.site.structure === null && current !== 1) { + return 1; + } else if ( + this.site.structure !== null && + this.site.type === null && + current !== 2 + ) { + return 2; + } else if ( + this.site.structure !== null && + this.site.type !== null && + this.site.theme === null && + current !== 3 + ) { + return 3; + } else if ( + this.site.structure !== null && + this.site.type !== null && + this.site.theme !== null && + this.site.name === null && + current !== 4 + ) { + return 4; + } else if ( + this.site.structure !== null && + this.site.type !== null && + this.site.theme !== null && + this.site.name !== null + ) { + return 5; + } + return current; + } + + get isLoggedIn() { + if (this.appReady && this.AppHaxAPI) { + return this.jwt !== "null" && this.jwt; + } + } + + get isNewUser() { + if (this.manifest && this.manifest.items) { + return this.manifest.items.length === 0; + } + } + + // site{ structure, type, theme } (course, portfolio, buz, colors) + get activeItem() { + if (this.routes.length > 0 && this.location && this.location.route) { + if (this.createSiteSteps) { + const routeItem = this.routes.find((item) => { + if (item.step === undefined || item.step !== this.step) { + return false; + } + return true; + }); + return routeItem; + } else { + return this.location.route; + } + } + } + + // centralize toast messages + toast(msg, duration = 3000, extras = {}) { + globalThis.dispatchEvent( + new CustomEvent("haxcms-toast-show", { + bubbles: true, + cancelable: true, + composed: true, + detail: { + text: msg, + duration: duration, + ...extras, + }, + }), + ); + } +} +/** + * Central store + */ +export const store = new Store(); diff --git a/elements/app-hax/lib/v2/app-hax-button.js b/elements/app-hax/lib/v2/app-hax-button.js new file mode 100644 index 0000000000..f20af41f16 --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-button.js @@ -0,0 +1,282 @@ +import "@haxtheweb/simple-icon/lib/simple-icon-lite.js"; +import "@haxtheweb/hax-iconset/lib/simple-hax-iconset.js"; +import "wired-elements/lib/wired-button.js"; +import { html, css, LitElement } from "lit"; +const postIt = new URL("../assets/images/PostIt.svg", import.meta.url).href; +const betaPostIt = new URL("../assets/images/BetaPostIt.svg", import.meta.url) + .href; + +export class AppHaxButton extends LitElement { + // a convention I enjoy so you can change the tag name in 1 place + static get tag() { + return "app-hax-button"; + } + + constructor() { + super(); + this.icon = "save"; + this.type = null; + this.value = null; + this.disabled = false; + this.elevation = 2; + this.active = false; + this.comingSoon = false; + this.prompt = null; + this.callback = null; + this.param = null; + this.beta = false; + this.addEventListener("click", this._handleClick); + this.addEventListener("click", this._handleClick); + this.addEventListener("focus", this._handleFocus); + this.addEventListener("blur", this._handleBlur); + this.addEventListener("mouseover", this._handleFocus); + this.addEventListener("mouseout", this._handleBlur); + } + + _handleFocus() { + if (!this.disabled && !this.comingSoon) { + this.active = true; + this.elevation = "4"; + } + } + + _handleBlur() { + if (!this.disabled && !this.comingSoon) { + this.active = false; + this.elevation = "2"; + } + } + + _handleClick() { + if (!this.disabled && !this.comingSoon) { + this.shadowRoot.querySelector(".haxButton").blur(); + } + } + + static get properties() { + return { + icon: { type: String }, + type: { type: String, reflect: true }, + disabled: { type: Boolean, reflect: true }, + elevation: { type: Number }, + active: { type: Boolean, reflect: true }, + comingSoon: { type: Boolean, reflect: true, attribute: "coming-soon" }, + beta: { type: Boolean, reflect: true }, + prompt: { type: String }, + callback: { type: String }, + param: { type: String }, + }; + } + + firstUpdated(changedProperties) { + if (super.firstUpdated) { + super.firstUpdated(changedProperties); + } + changedProperties.forEach((oldValue, propName) => { + if (propName === "type") { + switch (this.type) { + case "technology": + this.icon = "hardware:desktop-mac"; + this.value = "technology"; + break; + case "business": + this.icon = "maps:local-atm"; + this.value = "business"; + break; + case "art": + this.icon = "image:palette"; + this.value = "art"; + break; + case "6w": + this.icon = "hax:messages-6"; + this.value = "6 Week"; + break; + case "15w": + this.icon = "social:school"; + this.value = "15 Week"; + break; + case "training": + this.icon = "hax:bricks"; + this.value = "Training"; + break; + case "docx import": + this.icon = "hax:file-docx"; + this.value = "docx"; + break; + case "docx": + this.icon = "hax:file-docx"; + this.value = "docx"; + break; + case "evolution": + this.icon = "communication:business"; + this.value = "evo"; + break; + case "pressbooks": + this.icon = "hax:wordpress"; + this.value = "pressbooks"; + break; + case "gitbook": + this.icon = "mdi-social:github-circle"; + this.value = "gitbook"; + break; + case "elms:ln": + this.icon = "lrn:network"; + this.value = "elmsln"; + break; + case "haxcms": + this.icon = "hax:hax2022"; + this.value = "haxcms"; + break; + case "notion": + this.icon = "book"; + this.value = "notion"; + break; + case "html": + this.icon = "icons:code"; + this.value = "HTML"; + break; + case "Blog": + this.icon = "social:public"; + this.value = "Blog"; + break; + default: + this.icon = "image:photo-filter"; + this.value = "own"; + this.type = "Create Your Own"; + break; + } + } + }); + } + + static get styles() { + return [ + css` + :host { + display: block; + --background-color: transparent; + --background-color-active: white; + font-family: "Press Start 2P", sans-serif; + } + :host([coming-soon]) .haxButton { + pointer-events: none; + background-color: var(--simple-colors-default-theme-grey-6); + } + :host([active]) .haxButton { + color: var( + --app-hax-background-color, + var(--background-color-active) + ); + background-color: var(--app-hax-accent-color, var(--accent-color)); + } + :host([active]) simple-icon-lite { + --simple-icon-color: var( + --app-hax-background-color, + var(--background-color-active) + ); + } + :host([active]) .type { + background-color: var(--app-hax-accent-color, var(--accent-color)); + color: var( + --app-hax-background-color, + var(--background-color-active) + ); + } + + #container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-around; + width: 132px; + height: 112px; + } + .coming-soon { + display: block; + height: 114px; + width: 140px; + z-index: 1; + position: absolute; + margin-top: -75px; + } + .beta { + display: block; + height: 100px; + width: 120px; + z-index: 1; + position: absolute; + top: 0; + left: 0; + margin-left: -50px; + margin-top: -10px; + } + .haxButton { + background-color: var( + --app-hax-background-color, + var(--background-color) + ); + color: var(--app-hax-accent-color, var(--accent-color)); + display: inline-flex; + } + simple-icon-lite { + --simple-icon-width: 60px; + --simple-icon-height: 60px; + --simple-icon-color: var(--app-hax-accent-color, var(--accent-color)); + } + .type { + font-size: 10px; + color: var(--app-hax-accent-color, var(--accent-color)); + } + @media (max-width: 800px) { + #container { + width: 100px; + height: 75px; + } + + .beta, + .coming-soon { + margin-top: -50px; + height: 114px; + width: 100px; + } + } + `, + ]; + } + + render() { + return html` + +
+ +
${this.type}
+
+ ${this.comingSoon + ? html`Feature coming soon` + : ``} + ${this.beta + ? html`Feature in beta` + : ``} +
+ `; + } +} +customElements.define(AppHaxButton.tag, AppHaxButton); diff --git a/elements/app-hax/lib/v2/app-hax-hat-progress.js b/elements/app-hax/lib/v2/app-hax-hat-progress.js new file mode 100644 index 0000000000..0b71287949 --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-hat-progress.js @@ -0,0 +1,232 @@ +import { html, css } from "lit"; +import { SimpleColors } from "@haxtheweb/simple-colors/simple-colors.js"; +import { autorun, toJS } from "mobx"; +import { store } from "./AppHaxStore.js"; +import "@haxtheweb/promise-progress/promise-progress.js"; + +export class AppHaxHatProgress extends SimpleColors { + static get tag() { + return "app-hax-hat-progress"; + } + + constructor() { + super(); + this.promises = []; + this.max = 100; + autorun(() => { + this.promises = toJS(store.newSitePromiseList); + }); + autorun(() => { + this.dark = toJS(store.darkMode); + }); + } + + static get properties() { + return { + ...super.properties, + promises: { type: Array }, + }; + } + + process() { + this.shadowRoot.querySelector("#progress2").process(); + } + + firstUpdated(changedProperties) { + if (super.firstUpdated) { + super.firstUpdated(changedProperties); + } + this.dispatchEvent(new CustomEvent("progress-ready", { detail: true })); + + setTimeout(() => { + this.shadowRoot + .querySelector("#progress2") + .addEventListener("value-changed", (e) => { + this.shadowRoot.querySelector("#value").textContent = e.detail.value; + }); + this.shadowRoot + .querySelector("#progress2") + .addEventListener("max-changed", (e) => { + this.max = e.detail.value; + }); + this.shadowRoot + .querySelector("#progress2") + .addEventListener("promise-progress-finished", (e) => { + if (e.detail.value) { + // this will seem like magic... but our createSite + // Promise has a special flag on the function that + // saves the result in an object relative to our API broker + // this way if we ask it for the last thing it created + // the response is there even though we kicked it off previously + // we more or less assume it completed bc the Promises all resolved + // and it was our 1st Promise we asked to issue! + + // state clean up incase activated twice + if (this.shadowRoot.querySelector(".game")) { + this.shadowRoot.querySelector(".game").remove(); + } + + const createResponse = store.AppHaxAPI.lastResponse.createSite.data; + const text = globalThis.document.createElement("button"); + this.shadowRoot.querySelector("#value").textContent = this.max; + text.textContent = "Let's go!"; + text.classList.add("game"); + text.addEventListener("pointerdown", () => { + store.appEl.playSound("click"); + }); + text.addEventListener("click", () => { + store.appEl.reset(); + setTimeout(() => { + globalThis.location = createResponse.slug.replace( + "index.html", + "", + ); + }, 0); + }); + this.shadowRoot + .querySelector("#progress2") + .parentNode.appendChild(text); + // show you saying you got this! + store.toast( + `${createResponse.title ? createResponse.title : ""} ready!`, + 1500, + { + hat: "random", + }, + ); + store.setPageTitle( + `${createResponse.title ? createResponse.title : ""} ready!`, + ); + setTimeout(() => { + store.toast(`redirecting in 3..`, 10000, { + hat: "random", + walking: true, + }); + store.setPageTitle("Redirecting in 3.."); + setTimeout(() => { + store.toast(`redirecting in 2..`, 10000, { + hat: "random", + walking: true, + }); + store.setPageTitle("Redirecting in 2.."); + setTimeout(() => { + store.toast(`redirecting in 1..`, 10000, { + hat: "random", + walking: true, + }); + store.setPageTitle("Redirecting in 1.."); + store.appEl.reset(); + setTimeout(() => { + store.setPageTitle(`Enjoy!`); + globalThis.location = createResponse.slug.replace( + "index.html", + "", + ); + }, 1000); + }, 1000); + }, 1000); + }, 1800); + this.dispatchEvent( + new CustomEvent("promise-progress-finished", { + composed: true, + bubbles: true, + cancelable: true, + detail: true, + }), + ); + } + }); + }, 0); + } + + static get styles() { + return [ + super.styles, + css` + :host { + display: block; + height: 400px; + width: 400px; + } + img { + width: 400px; + height: 400px; + pointer-events: none; + } + .progress { + margin: -148px 0 0 10px; + z-index: -1; + } + .progress::part(progress) { + height: 100px; + width: 338px; + margin-top: -1px 0 0 -4px; + } + + .progress::part(progress)::-moz-progress-bar { + background-color: red; + height: 50px; + margin: 24px 0 0 0; + border: none; + } + + .count { + color: var(--simple-colors-default-theme-grey-1, white); + font-family: "Press Start 2P", sans-serif; + width: 350px; + text-align: center; + position: relative; + display: block; + font-size: 30px; + margin-top: -250px; + margin-left: 30px; + } + .game { + font-family: "Press Start 2P", sans-serif; + font-size: 28px; + font-weight: bold; + text-align: center; + width: 310px; + background-color: var(--simple-colors-default-theme-red-7, red); + color: var(--simple-colors-default-theme-grey-1, white); + border: 0px; + height: 54px; + display: block; + position: relative; + margin: 138px 0px 0px 52px; + padding: 0; + box-sizing: border-box; + } + .game:focus, + .game:hover { + cursor: pointer; + background-color: var(--simple-colors-default-theme-red-8); + color: var(--simple-colors-default-theme-grey-2); + } + .game:active { + cursor: progress; + background-color: var(--simple-colors-default-theme-red-10); + color: var(--simple-colors-default-theme-grey-5); + } + `, + ]; + } + + render() { + return html` + + +
0%
+ `; + } +} +customElements.define(AppHaxHatProgress.tag, AppHaxHatProgress); diff --git a/elements/app-hax/lib/v2/app-hax-label.js b/elements/app-hax/lib/v2/app-hax-label.js new file mode 100644 index 0000000000..320fdfb4e6 --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-label.js @@ -0,0 +1,94 @@ +// dependencies / things imported +import { LitElement, html, css } from "lit"; + +export class AppHaxLabel extends LitElement { + // a convention I enjoy so you can change the tag name in 1 place + static get tag() { + return "app-hax-label"; + } + + constructor() { + super(); + this.title = "Welcome"; + this.subtitle = "Start your journey now!"; + } + + static get properties() { + return { + title: { type: String }, + subtitle: { type: String }, + }; + } + + // TODO: If scaling is weird with font-sizes, try using clamp() (https://css-tricks.com/linearly-scale-font-size-with-css-clamp-based-on-the-viewport/) + static get styles() { + return css` + :host { + font-family: "Press Start 2P", sans-serif; + text-align: center; + } + + .title { + -webkit-text-stroke: 1px + var(--app-hax-accent-color, var(--accent-color)); + -webkit-text-fill-color: var( + --app-hax-background-color, + var(--background-color) + ); + font-weight: normal; + font-size: 3.5vw; + display: inline-flex; + align-items: center; + } + + .subtitle { + color: var(--app-hax-accent-color, var(--accent-color)); + font-weight: normal; + margin-top: 2px; + font-size: 20px; + } + @media (max-width: 700px) { + .subtitle { + font-size: 12px; + } + } + + .bracket { + font-size: 8vw; + font-weight: normal; + vertical-align: middle; + -webkit-text-stroke: 0px; + -webkit-text-fill-color: var( + --app-hax-accent-color, + var(--accent-color) + ); + } + @media (max-height: 500px) { + .title { + -webkit-text-stroke: unset; + -webkit-text-fill-color: unset; + } + .bracket { + font-size: 4vw; + margin: 0; + padding: 0; + } + } + `; + } + + render() { + return html` +
+
+ <${this.title}> +
+
+ ${this.subtitle} +
+
+ `; + } +} +customElements.define(AppHaxLabel.tag, AppHaxLabel); diff --git a/elements/app-hax/lib/v2/app-hax-search-bar.js b/elements/app-hax/lib/v2/app-hax-search-bar.js new file mode 100644 index 0000000000..c3036f8c76 --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-search-bar.js @@ -0,0 +1,155 @@ +/* eslint-disable no-return-assign */ +import { LitElement, html, css } from "lit"; +import "@haxtheweb/simple-tooltip/simple-tooltip.js"; +import { store } from "./AppHaxStore.js"; + +export class AppHaxSearchBar extends LitElement { + // a convention I enjoy so you can change the tag name in 1 place + static get tag() { + return "app-hax-search-bar"; + } + + constructor() { + super(); + this.searchTerm = ""; + this.disabled = false; + this.showSearch = false; + } + + // Site.json is coming from + + static get properties() { + return { + searchTerm: { type: String }, + showSearch: { type: Boolean, reflect: true, attribute: "show-search" }, + disabled: { type: Boolean, reflect: true }, + }; + } + + updated(changedProperties) { + changedProperties.forEach((oldValue, propName) => { + if (propName === "searchItems") { + this.displayItems = [...this.searchItems]; + } else if (propName === "searchTerm") { + store.searchTerm = this.searchTerm; + } else if (propName === "showSearch" && oldValue !== undefined) { + if (this[propName] === false) { + this.searchTerm = ""; + } + } + }); + } + + static get styles() { + return [ + css` + :host { + overflow: hidden; + } + input { + visibility: none; + opacity: 0; + width: 0; + transition: all ease-in-out 0.3s; + padding: 4px; + font-family: "Press Start 2P", sans-serif; + font-size: 20px; + margin: 2px 0 0 16px; + } + :host([show-search]) input { + visibility: visible; + opacity: 1; + width: 250px; + max-width: 25vw; + } + @media (max-width: 780px) { + :host([show-search]) input { + width: 250px; + max-width: 20vw; + } + } + @media (max-width: 600px) { + :host([show-search]) input { + width: 200px; + max-width: 20vw; + } + } + + simple-toolbar-button[disabled] { + background-color: #cccccc; + pointer-events: none; + cursor: help; + } + simple-toolbar-button { + min-width: 48px; + margin: 0; + --simple-toolbar-border-color: #dddddddd; + height: 48px; + --simple-toolbar-button-disabled-border-color: transparent; + --simple-toolbar-button-disabled-opacity: 0.3; + --simple-toolbar-button-padding: 3px 6px; + --simple-toolbar-border-radius: 0; + } + simple-toolbar-button:hover, + simple-toolbar-button:active, + simple-toolbar-button:focus { + background-color: var(--hax-ui-background-color-accent); + color: var(--hax-ui-color); + } + simple-toolbar-button:hover, + simple-toolbar-button:active, + simple-toolbar-button:focus { + --simple-toolbar-border-color: var(--hax-ui-color-accent); + } + `, + ]; + } + testKeydown(e) { + if (e.key === "Escape" || e.key === "Enter") { + this.toggleSearch(); + } + } + // eslint-disable-next-line class-methods-use-this + search() { + store.appEl.playSound("click"); + this.searchTerm = this.shadowRoot.querySelector("#searchField").value; + } + + render() { + return html` + + Toggle Search + + `; + } + + toggleSearch() { + if (!this.disabled) { + this.shadowRoot.querySelector("#searchField").value = ""; + store.appEl.playSound("click"); + this.showSearch = !this.showSearch; + setTimeout(() => { + this.shadowRoot.querySelector("#searchField").focus(); + }, 300); + } + } +} +customElements.define(AppHaxSearchBar.tag, AppHaxSearchBar); diff --git a/elements/app-hax/lib/v2/app-hax-search-results.js b/elements/app-hax/lib/v2/app-hax-search-results.js new file mode 100644 index 0000000000..329a663296 --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-search-results.js @@ -0,0 +1,196 @@ +/* eslint-disable no-return-assign */ +import { SimpleColors } from "@haxtheweb/simple-colors/simple-colors.js"; +import { html, css } from "lit"; +import { autorun, toJS } from "mobx"; +import { varGet } from "@haxtheweb/utils/utils.js"; +import { store } from "./AppHaxStore.js"; +import "./app-hax-site-bar.js"; +import "./app-hax-site-details.js"; + +export class AppHaxSearchResults extends SimpleColors { + // a convention I enjoy so you can change the tag name in 1 place + static get tag() { + return "app-hax-search-results"; + } + + constructor() { + super(); + this.searchItems = []; + this.displayItems = []; + this.searchTerm = ""; + this.dark = false; + autorun(() => { + this.searchTerm = toJS(store.searchTerm); + }); + autorun(() => { + this.dark = toJS(store.darkMode); + }); + autorun(() => { + const manifest = toJS(store.manifest); + if (manifest && manifest.items) { + this.searchItems = manifest.items; + this.displayItems = [...this.searchItems]; + } + }); + } + + // Site.json is coming from + + static get properties() { + return { + ...super.properties, + searchTerm: { type: String, reflect: true }, + searchItems: { type: Array }, + displayItems: { type: Array }, + }; + } + + updated(changedProperties) { + if (super.updated) { + super.updated(changedProperties); + } + changedProperties.forEach((oldValue, propName) => { + if (propName === "searchTerm") { + this.displayItems = this.searchItems.filter((word) => { + if ( + word.title.toLowerCase().includes(this.searchTerm.toLowerCase()) || + word.description + .toLowerCase() + .includes(this.searchTerm.toLowerCase()) || + word.author.toLowerCase().includes(this.searchTerm.toLowerCase()) || + word.slug.toLowerCase().includes(this.searchTerm.toLowerCase()) + ) { + return true; + } + return false; + }); + } + }); + } + + static get styles() { + return [ + super.styles, + css` + :host { + overflow: hidden; + } + ul, + li { + margin: 0; + padding: 0; + list-style: none; + } + app-hax-site-bar { + margin: 8px 0; + } + .description { + max-height: 64px; + overflow: hidden; + max-width: 80%; + text-overflow: ellipsis; + word-break: break-all; + } + + @media (max-width: 800px) { + app-hax-site-bar { + --main-banner-width: 60vw; + } + .description { + max-height: 24px; + font-size: 8px; + font-family: sans-serif; + } + } + @media (max-width: 640px) { + app-hax-site-bar a { + font-size: 14px; + } + app-hax-site-bar { + --main-banner-width: 70vw; + } + } + span[slot="band"] { + height: 48px; + overflow: hidden; + text-overflow: ellipsis; + margin-bottom: 8px; + } + :host([dark]) #noResult { + color: var(--ddd-theme-default-coalyGray); + } + `, + ]; + } + render() { + return html` + + `; + } + + getItemDetails(item) { + const details = { + created: varGet(item, "metadata.site.created", new Date() / 1000), + updated: varGet(item, "metadata.site.updated", new Date() / 1000), + pages: varGet(item, "metadata.pageCount", 0), + url: item.slug, + }; + return details; + } + + openedChanged(e) { + store.appEl.playSound("click"); + if (!e.detail.value) { + this.shadowRoot + .querySelector("app-hax-site-details") + .setAttribute("tabindex", "-1"); + } else { + this.shadowRoot + .querySelector("app-hax-site-details") + .removeAttribute("tabindex"); + } + } +} +customElements.define(AppHaxSearchResults.tag, AppHaxSearchResults); diff --git a/elements/app-hax/lib/v2/app-hax-site-bar.js b/elements/app-hax/lib/v2/app-hax-site-bar.js new file mode 100644 index 0000000000..587932b03b --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-site-bar.js @@ -0,0 +1,208 @@ +/* eslint-disable no-console */ +// dependencies / things imported +import { html, css, unsafeCSS } from "lit"; +import "@haxtheweb/simple-icon/lib/simple-icons.js"; +import "@haxtheweb/simple-icon/lib/simple-icon-button-lite"; +import { SimpleColors } from "@haxtheweb/simple-colors/simple-colors.js"; +import "@haxtheweb/simple-tooltip/simple-tooltip.js"; +import { animate } from "@lit-labs/motion"; + +const DropDownBorder = new URL( + "../assets/images/DropDownBorder.svg", + import.meta.url, +); +// EXPORT (so make available to other documents that reference this file) a class, that extends LitElement +// which has the magic life-cycles and developer experience below added +export class AppHaxSiteBars extends SimpleColors { + // a convention I enjoy so you can change the tag name in 1 place + static get tag() { + return "app-hax-site-bar"; + } + + // HTMLElement life-cycle, built in; use this for setting defaults + constructor() { + super(); + this.icon = "link"; + this.opened = false; + this.inprogress = false; + this.iconLink = "/"; + this.textInfo = {}; + this.siteId = ""; + } + + // properties that you wish to use as data in HTML, CSS, and the updated life-cycle + static get properties() { + return { + ...super.properties, + opened: { type: Boolean, reflect: true }, + icon: { type: String }, + inprogress: { type: Boolean, reflect: true }, + iconLink: { type: String, attribute: "icon-link" }, + textInfo: { type: Object }, + siteId: { type: String, reflect: true, attribute: "site-id" }, + }; + } + + // updated fires every time a property defined above changes + // this allows you to react to variables changing and use javascript to perform logic + updated(changedProperties) { + if (super.updated) { + super.updated(changedProperties); + } + changedProperties.forEach((oldValue, propName) => { + if (propName === "opened" && oldValue !== undefined) { + this.dispatchEvent( + new CustomEvent(`${propName}-changed`, { + detail: { + value: this[propName], + }, + }), + ); + } + }); + } + + // CSS - specific to Lit + static get styles() { + return [ + super.styles, + css` + :host { + --main-banner-width: 513px; + --main-banner-height: 60px; + --band-banner-height: 208px; + display: inline-block; + background-color: var(--simple-colors-default-theme-accent-3); + color: var(--simple-colors-default-theme-grey-12); + border-color: var(--simple-colors-default-theme-accent-4); + border-style: solid; + border-width: 5px 10px 5px 10px; + } + + #labels { + display: block; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + } + #labels ::slotted(*) { + font-family: "Press Start 2P", sans-serif; + font-size: 25px; + } + #labels ::slotted(a) { + color: var(--simple-colors-default-theme-accent-11); + padding: 8px 0; + display: block; + } + #labels ::slotted(a:focus), + #labels ::slotted(a:hover) { + color: var(--simple-colors-default-theme-accent-3); + background-color: var(--simple-colors-default-theme-accent-11); + } + + :host([opened]) { + background-color: var(--simple-colors-default-theme-accent-3); + } + #mainCard { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + width: var(--main-banner-width); + height: var(--main-banner-height); + padding: 2px 4px; + } + + #band-container { + display: block; + visibility: hidden; + height: 1px; + width: var(--main-banner-width); + } + + :host([opened]) #band-container { + height: var(--band-banner-height); + visibility: visible; + } + a { + flex: 1; + } + #labels { + flex: 6; + overflow: hidden; + text-overflow: ellipsis; + } + #icon { + --simple-icon-width: 49px; + --simple-icon-height: 49px; + color: var(--simple-colors-default-theme-accent-11); + } + #icon:hover, + #icon:focus, + #icon:active { + color: var(--simple-colors-default-theme-accent-3); + background-color: var(--simple-colors-default-theme-accent-11); + } + #dots { + --simple-icon-width: 49px; + --simple-icon-height: 49px; + color: var(--simple-colors-default-theme-grey-12); + background-image: url(${unsafeCSS(DropDownBorder)}); + background-repeat: no-repeat; + background-position: center; + } + @media (max-width: 640px) { + :host { + --main-banner-height: 40px; + --band-banner-height: 140px; + } + #icon, + #dots { + --simple-icon-width: 30px; + --simple-icon-height: 30px; + } + #mainCard { + padding: 0; + } + } + `, + ]; + } + + __clickButton() { + this.opened = !this.opened; + } + + // HTML - specific to Lit + render() { + return html` +
+ + + +
+ +
+ +
+
+ +
+ Access site + More options + `; + } + + // HAX specific callback + // This teaches HAX how to edit and work with your web component + /** + * haxProperties integration via file reference + */ +} +customElements.define(AppHaxSiteBars.tag, AppHaxSiteBars); diff --git a/elements/app-hax/lib/v2/app-hax-site-button.js b/elements/app-hax/lib/v2/app-hax-site-button.js new file mode 100644 index 0000000000..ea28009a88 --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-site-button.js @@ -0,0 +1,157 @@ +/* eslint-disable no-console */ +// dependencies / things imported +import { html, css } from "lit"; +import "@haxtheweb/simple-icon/lib/simple-icons.js"; +import "@haxtheweb/simple-icon/lib/simple-icon-lite.js"; +import { SimpleColors } from "@haxtheweb/simple-colors/simple-colors.js"; +import "wired-elements/lib/wired-button.js"; + +const postIt = new URL("../assets/images/PostIt.svg", import.meta.url).href; + +// EXPORT (so make available to other documents that reference this file) a class, that extends LitElement +// which has the magic life-cycles and developer experience below added +export class AppHaxSiteButton extends SimpleColors { + // a convention I enjoy so you can change the tag name in 1 place + static get tag() { + return "app-hax-site-button"; + } + + // HTMLElement life-cycle, built in; use this for setting defaults + constructor() { + super(); + this.label = null; + this.value = null; + this.disabled = false; + this.elevation = "3"; + this.active = false; + this.comingSoon = false; + this.addEventListener("click", this._handleClick); + this.addEventListener("focus", this._handleFocus); + this.addEventListener("blur", this._handleBlur); + this.addEventListener("mouseover", this._handleFocus); + this.addEventListener("mouseout", this._handleBlur); + } + + // properties that you wish to use as data in HTML, CSS, and the updated life-cycle + static get properties() { + return { + label: { type: String }, + value: { type: String }, + disabled: { type: Boolean, reflect: true }, + elevation: { type: Number }, + active: { type: Boolean, reflect: true }, + comingSoon: { type: Boolean, reflect: true, attribute: "coming-soon" }, + }; + } + + // CSS - specific to Lit + static get styles() { + return css` + :host { + --background-color: transparent; + --background-color-active: white; + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + font-family: "Press Start 2P", sans-serif; + width: fit-content; + margin: 20px 0; + } + :host([coming-soon]) .haxButton { + pointer-events: none; + background-color: var(--simple-colors-default-theme-grey-6); + } + @media (max-width: 800px) { + :host { + width: 320px; + } + } + :host([active]) .haxButton { + color: var(--app-hax-background-color, var(--background-color-active)); + background-color: var(--app-hax-accent-color, var(--accent-color)); + } + .haxButton { + background-color: var( + --app-hax-background-color, + var(--background-color) + ); + color: var(--app-hax-accent-color, var(--accent-color)); + font-size: var(--app-hax-site-button-font-size, 26px); + } + .contents { + display: flex; + justify-content: right; + } + .label { + width: var(--app-hax-site-button-width, auto); + min-width: var(--app-hax-site-button-min-width, auto); + height: var(--app-hax-site-button-height, auto); + display: inline-flex; + } + .coming-soon { + display: block; + height: 90px; + width: 110px; + z-index: 1; + position: absolute; + margin-right: -25px; + margin-top: -25px; + } + `; + } + + _handleFocus() { + if (!this.disabled && !this.comingSoon) { + this.active = true; + this.elevation = "5"; + } + } + + _handleBlur() { + if (!this.disabled && !this.comingSoon) { + this.active = false; + this.elevation = "3"; + } + } + + _handleClick() { + if (!this.disabled && !this.comingSoon) { + this.shadowRoot.querySelector(".haxButton").blur(); + } + } + + // HTML - specific to Lit + render() { + return html` + +
+ ${this.label} + ${this.comingSoon + ? html`Feature coming soon` + : ``} +
+
+ `; + } + + // HAX specific callback + // This teaches HAX how to edit and work with your web component + /** + * haxProperties integration via file reference + */ +} + +customElements.define(AppHaxSiteButton.tag, AppHaxSiteButton); diff --git a/elements/app-hax/lib/v2/app-hax-site-details.js b/elements/app-hax/lib/v2/app-hax-site-details.js new file mode 100644 index 0000000000..2f736d74b0 --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-site-details.js @@ -0,0 +1,379 @@ +// dependencies / things imported +import { html, css } from "lit"; +import "@haxtheweb/simple-datetime/simple-datetime.js"; +import { toJS } from "mobx"; +import { store } from "./AppHaxStore.js"; +import { SimpleColors } from "@haxtheweb/simple-colors/simple-colors.js"; + +// wrapper to simplify the slug if it has additional values on it +function makeSlug(url) { + let slug = "site"; + if (url) { + let tmp = url.split("sites/"); + if (tmp.length > 1) { + slug = tmp.pop().replace("/", ""); + } + } + return slug; +} +// EXPORT (so make available to other documents that reference this file) a class, that extends LitElement +// which has the magic life-cycles and developer experience below added +export class AppHaxSiteDetails extends SimpleColors { + // a convention I enjoy so you can change the tag name in 1 place + static get tag() { + return "app-hax-site-details"; + } + + // HTMLElement life-cycle, built in; use this for setting defaults + constructor() { + super(); + this.need = "all need to succeed"; + this.details = {}; + this.siteId = ""; + this.detailOps = [ + { + name: "Copy", + op: "copySite", + icon: "icons:content-copy", + }, + { + name: "Download", + op: "downloadSite", + icon: "file-download", + }, + { + name: "Archive", + op: "archiveSite", + icon: "icons:archive", + }, + ]; + if (globalThis.HAXCMSContext && globalThis.HAXCMSContext === "php") { + this.detailOps.push({ + name: "Git", + op: "gitList", + icon: "hax:git", + }); + } + } + + // properties that you wish to use as data in HTML, CSS, and the updated life-cycle + static get properties() { + return { + ...super.properties, + details: { type: Object }, + siteId: { type: String, attribute: "site-id" }, + }; + } + + // CSS - specific to Lit + static get styles() { + return [ + super.styles, + css` + :host { + display: flex; + flex-direction: column; + justify-content: center; + font-size: 12px; + align-items: stretch; + background-color: var(--simple-colors-default-theme-grey-2); + height: 208px; + } + + .flex-container { + flex: 1; + background-color: var(--simple-colors-default-theme-grey-2); + margin: 8px; + display: flex; + flex-direction: row; + justify-content: space-around; + align-items: center; + } + .info-group { + height: 100%; + max-width: 25%; + display: flex; + flex-direction: column; + justify-content: space-around; + align-items: center; + padding: 0px; + flex: 1; + } + simple-icon-button-lite:active, + simple-icon-button-lite:hover, + simple-icon-button-lite:focus { + background-color: var(--simple-colors-default-theme-grey-4, #eeeeee); + outline: 2px solid var(--simple-colors-default-theme-grey-12); + outline-offset: 1px; + } + + .info-headings { + font-size: 12px; + } + .info-item { + font-family: "Press Start 2P", sans-serif; + display: block; + text-overflow: ellipsis; + overflow: hidden; + color: var(--simple-colors-default-theme-grey-12); + line-height: 12px; + max-width: 100%; + font-size: 12px; + } + .pre ::slotted(*) { + padding: 12px; + overflow: hidden; + text-overflow: ellipsis; + max-width: 50%; + display: inline-flex; + } + a { + text-decoration: underline; + } + .info-date { + color: var(--simple-colors-default-theme-grey-12); + line-height: 12px; + font-size: 12px; + } + + .info-icon { + --simple-icon-width: 49px; + --simple-icon-height: 49px; + --simple-icon-button-border-radius: 0px; + --simple-icon-button-border: 0px; + outline: 0; + border: 2px solid var(--simple-colors-default-theme-grey-12); + border-radius: 4px; + padding: 4px; + width: 80%; + } + .info-icon::part(button) { + outline: none; + } + @media (max-width: 640px) { + :host { + height: 140px; + } + .btn-group button { + padding: 4px; + margin: 4px 0; + } + .flex-container > div { + margin: 0px; + } + .info-headings { + font-size: 8px; + } + .info-date { + font-size: 8px; + line-height: 10px; + } + .info-icon { + --simple-icon-width: 30px; + --simple-icon-height: 30px; + padding: 2px; + border-radius: none; + } + .info-item { + font-size: 8px; + } + .flex-container { + margin: 2px; + } + .pre ::slotted(*) { + padding: 0px; + margin-top: 8px; + } + .info-group { + height: 24px; + } + } + `, + ]; + } + + // eslint-disable-next-line class-methods-use-this + siteOperation(e) { + // let elements; + store.appEl.playSound("click"); + var target = e.target; + // avoid label trigger + if (target.tagName === "DIV") { + target = target.parentNode; + } + const div = globalThis.document.createElement("div"); + const op = target.getAttribute("data-site-operation"); + const opName = target.getAttribute("data-site-operation-name"); + const siteID = target.getAttribute("data-site"); + store.activeSiteOp = op; + store.activeSiteId = siteID; + import("@haxtheweb/simple-modal/simple-modal.js").then(() => { + setTimeout(() => { + const site = toJS( + store.manifest.items.filter((item) => item.id === siteID).pop(), + ); + div.appendChild( + globalThis.document.createTextNode( + `Are you sure you want to ${op.replace("Site", "")} ${ + site.metadata.site.name + }?`, + ), + ); + // gitlist opens in a new window + if (op === "gitList") { + // php library is basis for this button, rare instance + if (globalThis.HAXCMSContext === "php") { + // open link in new window + globalThis.open( + `gitlist/${site.metadata.site.name}`, + "_blank", + "noopener noreferrer", + ); + } + } else { + const bcontainer = globalThis.document.createElement("div"); + const b = globalThis.document.createElement("button"); + b.innerText = "Confirm"; + b.classList.add("hax-modal-btn"); + b.addEventListener("click", this.confirmOperation.bind(this)); + bcontainer.appendChild(b); + const b2 = globalThis.document.createElement("button"); + b2.innerText = "Cancel"; + b2.classList.add("hax-modal-btn"); + b2.classList.add("cancel"); + b2.addEventListener("click", this.cancelOperation.bind(this)); + bcontainer.appendChild(b2); + this.dispatchEvent( + new CustomEvent("simple-modal-show", { + bubbles: true, + cancelable: true, + composed: true, + detail: { + title: `${opName} ${site.metadata.site.name}?`, + elements: { content: div, buttons: bcontainer }, + invokedBy: target, + styles: { + "--simple-modal-titlebar-background": "orange", + "--simple-modal-titlebar-color": "black", + "--simple-modal-width": "30vw", + "--simple-modal-min-width": "300px", + "--simple-modal-z-index": "100000000", + "--simple-modal-height": "20vh", + "--simple-modal-min-height": "300px", + "--simple-modal-titlebar-height": "80px", + }, + }, + }), + ); + } + }, 0); + }); + } + + cancelOperation() { + store.activeSiteOp = ""; + store.activeSiteId = null; + globalThis.dispatchEvent(new CustomEvent("simple-modal-hide")); + store.appEl.playSound("error"); + } + + async confirmOperation() { + const op = toJS(store.activeSiteOp); + const site = toJS(store.activeSite); + // @todo bother to implement these / translate to the path via switch + await store.AppHaxAPI.makeCall( + op, + { + site: { + name: site.metadata.site.name, + id: site.id, + }, + }, + true, + () => { + const activeOp = toJS(store.activeSiteOp); + // download is weird relative to the others + if (activeOp === "downloadSite") { + // cheat to download a file path + globalThis.open( + store.AppHaxAPI.lastResponse.downloadSite.data.link, + "_blank", + ); + } else { + store.refreshSiteListing(); + } + }, + ); + globalThis.dispatchEvent(new CustomEvent("simple-modal-hide")); + store.appEl.playSound("success"); + store.toast( + `${site.metadata.site.name} ${op.replace("Site", "")} successful!`, + 3000, + { + hat: "random", + }, + ); + } + + // HTML - specific to Lit + render() { + return html` +
+
+
+
created
+ +
+
+
updated
+ +
+
+
pages
+
${this.details.pages}
+
+ +
+
+ ${this.detailOps.map( + (item) => html` +
+ +
${item.name.toLowerCase()}
+
+ ${item.op != "gitList" ? "" : "View"} ${item.name} + ${item.op != "gitList" ? "Site" : "source"} +
+ `, + )} +
+ + `; + } +} +customElements.define(AppHaxSiteDetails.tag, AppHaxSiteDetails); diff --git a/elements/app-hax/lib/v2/app-hax-site-login.js b/elements/app-hax/lib/v2/app-hax-site-login.js new file mode 100644 index 0000000000..89738955f4 --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-site-login.js @@ -0,0 +1,278 @@ +import { html, css } from "lit"; +import "@haxtheweb/simple-icon/lib/simple-icons.js"; +import "@haxtheweb/simple-icon/lib/simple-icon-lite.js"; +import { SimpleColors } from "@haxtheweb/simple-colors/simple-colors.js"; +import "@haxtheweb/rpg-character/rpg-character.js"; +import { store } from "./AppHaxStore.js"; +export class AppHaxSiteLogin extends SimpleColors { + // a convention I enjoy so you can change the tag name in 1 place + static get tag() { + return "app-hax-site-login"; + } + + // HTMLElement life-cycle, built in; use this for setting defaults + constructor() { + super(); + this.windowControllers = new AbortController(); + this.username = ""; + this.password = ""; + this.errorMSG = "Enter User name"; + this.hidePassword = true; + this.hasPass = false; + } + + // properties that you wish to use as data in HTML, CSS, and the updated life-cycle + static get properties() { + return { + ...super.properties, + username: { type: String }, + password: { type: String }, + errorMSG: { type: String }, + hidePassword: { type: Boolean }, + hasPass: { type: Boolean }, + }; + } + + firstUpdated() { + super.firstUpdated(); + setTimeout(() => { + this.shadowRoot.querySelector("input").focus(); + }, 0); + } + + // updated fires every time a property defined above changes + // this allows you to react to variables changing and use javascript to perform logic + // updated(changedProperties) { + // changedProperties.forEach((oldValue, propName) => { + // }); + // } + + // CSS - specific to Lit + static get styles() { + return [ + super.styles, + css` + :host { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + } + #inputcontainer { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + } + a { + color: red; + } + + // This does not work + #errorText > p { + visibility: hidden; + background-color: lightblue; + color: red; + font-weight: bold; + } + rpg-character { + display: block; + margin: 0px; + } + .external { + text-align: center; + } + input { + font-family: "Press Start 2P", sans-serif; + font-size: 28px; + padding: 8px; + border: 4px solid black; + border-radius: 8px; + width: 75%; + } + button { + font-family: "Press Start 2P", sans-serif; + font-size: 30px; + padding: 8px; + border: 4px solid black; + border-radius: 8px; + min-width: 50%; + margin: 16px; + } + button:focus, + button:hover { + background-color: var(--simple-colors-default-theme-green-8); + color: var(--simple-colors-default-theme-grey-1); + outline: 2px solid var(--simple-colors-default-theme-grey-1); + cursor: pointer; + } + .notyou { + padding: 8px; + } + .visibility-icon { + color: var(--simple-colors-default-theme-grey-12); + background-color: var(--simple-colors-default-theme-grey-3); + border: 2px solid var(--simple-colors-default-theme-grey-12); + position: relative; + margin-top: -44px; + margin-bottom: 20px; + margin-left: 70%; + z-index: 1; + padding: 2px; + --simple-icon-width: 26px; + --simple-icon-height: 26px; + } + `, + ]; + } + + // eslint-disable-next-line class-methods-use-this + checkUsername() { + // eslint-disable-next-line prefer-destructuring + const value = this.shadowRoot.querySelector("#username").value; + this.hidePassword = false; + this.errorMSG = ""; + this.username = value; + store.appEl.playSound("click2"); + setTimeout(() => { + this.shadowRoot.querySelector("input").focus(); + }, 0); + } + + // eslint-disable-next-line class-methods-use-this + async checkPassword() { + store.appEl.playSound("click2"); + // eslint-disable-next-line prefer-destructuring + const value = this.shadowRoot.querySelector("#password").value; + // attempt login and wait for response from the jwt-login tag via + // jwt-logged-in event @see _jwtLoggedIn + globalThis.dispatchEvent( + new CustomEvent("jwt-login-login", { + composed: true, + bubbles: true, + cancelable: false, + detail: { + username: this.username, + password: value, + }, + }), + ); + } + + // eslint-disable-next-line class-methods-use-this + reset() { + this.errorMSG = ""; + this.username = ""; + this.hasPass = false; + this.hidePassword = true; + } + + nameChange() { + this.username = this.shadowRoot.querySelector("#username").value; + } + + connectedCallback() { + super.connectedCallback(); + globalThis.addEventListener("jwt-logged-in", this._jwtLoggedIn.bind(this), { + signal: this.windowControllers.signal, + }); + globalThis.addEventListener( + "jwt-login-login-failed", + this._jwtLoginFailed.bind(this), + { signal: this.windowControllers.signal }, + ); + } + + disconnectedCallback() { + this.windowControllers.abort(); + super.disconnectedCallback(); + } + // implies that it failed to connect via the login credentials + _jwtLoginFailed(e) { + this.hidePassword = true; + this.errorMSG = "Invalid Username or Password"; + store.appEl.playSound("error"); + } + _jwtLoggedIn(e) { + if (e.detail) { + store.user = { + name: this.username, + }; + store.appEl.playSound("success"); + this.dispatchEvent( + new CustomEvent("simple-modal-hide", { + bubbles: true, + cancelable: true, + detail: {}, + }), + ); + store.toast(`Welcome ${this.username}! Let's go!`, 5000, { + hat: "construction", + }); + // just to be safe + store.appEl.reset(); + } + } + + passChange(e) { + const value = this.shadowRoot.querySelector("#password").value; + if (value) { + this.hasPass = true; + } else { + this.hasPass = false; + } + } + toggleViewPass(e) { + const password = this.shadowRoot.querySelector("#password"); + const type = + password.getAttribute("type") === "password" ? "text" : "password"; + password.setAttribute("type", type); + e.target.icon = type === "text" ? "lrn:visible" : "lrn:view-off"; + } + + render() { + return html` + +

${this.errorMSG}

+
+ ${this.hidePassword + ? html` + ` + : html`
+ Hey ${this.username}! not you? +
+ + + `} +
+ +
+
+ `; + } +} +customElements.define(AppHaxSiteLogin.tag, AppHaxSiteLogin); diff --git a/elements/app-hax/lib/v2/app-hax-steps.js b/elements/app-hax/lib/v2/app-hax-steps.js new file mode 100644 index 0000000000..f5780ce397 --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-steps.js @@ -0,0 +1,1274 @@ +/* eslint-disable lit/attribute-value-entities */ +/* eslint-disable lit/binding-positions */ +/* eslint-disable import/no-unresolved */ +/* eslint-disable import/no-extraneous-dependencies */ +/* eslint-disable class-methods-use-this */ +import { html, css, unsafeCSS } from "lit"; +import { SimpleColors } from "@haxtheweb/simple-colors/simple-colors.js"; +import { autorun, toJS } from "mobx"; +import { store } from "./AppHaxStore.js"; +import { localStorageSet } from "@haxtheweb/utils/utils.js"; +import "scrollable-component/index.js"; +import "@haxtheweb/simple-icon/lib/simple-icon-lite.js"; +import { MicroFrontendRegistry } from "@haxtheweb/micro-frontend-registry/micro-frontend-registry.js"; +import { enableServices } from "@haxtheweb/micro-frontend-registry/lib/microServices.js"; +import "./app-hax-site-button.js"; +import "./app-hax-hat-progress.js"; +import "./app-hax-button.js"; + +const homeIcon = new URL("../assets/images/Home.svg", import.meta.url).href; +const disabledCircle = new URL( + "../assets/images/DisabledCircle.svg", + import.meta.url, +).href; +const transparentCircle = new URL( + "../assets/images/TransparentCircle.svg", + import.meta.url, +).href; +const enabledCircle = new URL( + "../assets/images/EnabledCircle.svg", + import.meta.url, +).href; + +const themeContext = { + collection: ["collections-theme", "bootstrap-theme"], + blog: ["haxor-slevin"], + course: ["clean-one", "clean-two", "learn-two-theme"], + website: ["polaris-flex-theme"], + training: ["training-theme"], + import: ["clean-one", "clean-two", "learn-two-theme"], +}; +export class AppHaxSteps extends SimpleColors { + static get tag() { + return "app-hax-steps"; + } + + constructor() { + super(); + this.unlockComingSoon = false; + this.unlockTerrible = false; + this.windowControllers = new AbortController(); + this.nameTyped = ""; + this.stepRoutes = []; + this._progressReady = false; + this.step = null; + this.loaded = false; + this.themeNames = []; + this.appSettings = {}; + autorun(() => { + this.appSettings = toJS(store.appSettings); + const contextKey = toJS(store.site.structure); + this.themeNames = Object.keys(this.appSettings.themes).filter( + (value) => + contextKey && + themeContext[contextKey] && + themeContext[contextKey].includes(value), + ); + }); + autorun(() => { + this.dark = toJS(store.darkMode); + }); + autorun(() => { + localStorageSet("app-hax-step", toJS(store.step)); + }); + autorun(() => { + localStorageSet("app-hax-site", toJS(store.site)); + this.step = store.stepTest(this.step); + }); + autorun(() => { + if (toJS(store.createSiteSteps) && toJS(store.location)) { + this.step = store.stepTest(this.step); + } + }); + // routes, but only the ones that have a step property + autorun(() => { + const routes = toJS(store.routes); + this.stepRoutes = routes.filter((item) => item.step); + }); + } + + static get properties() { + return { + ...super.properties, + step: { type: Number, reflect: true }, + stepRoutes: { type: Array }, + themeNames: { type: Array }, + unlockComingSoon: { + type: Boolean, + reflect: true, + attribute: "unlock-coming-soon", + }, + unlockTerrible: { + type: Boolean, + reflect: true, + attribute: "unlock-terrible", + }, + loaded: { type: Boolean, reflect: true }, + appSettings: { type: Object }, + nameTyped: { type: String }, + }; + } + + // step 1 + chooseStructure(e) { + if (!e.target.comingSoon) { + const { value } = e.target; + store.site.structure = value; + // @note for now, auto select type and theme if making a course + // we might want to revisit this in the future + if (value === "course") { + store.site.type = "own"; + store.site.theme = "clean-one"; + } + if (value === "blog") { + store.site.type = "own"; + store.site.theme = "haxor-slevin"; + } + if (value === "collection") { + store.site.type = "own"; + store.site.theme = "collections-theme"; + } + if (value === "website") { + store.site.type = "own"; + store.site.theme = "polaris-flex-theme"; + } + if (value === "training") { + store.site.type = "own"; + store.site.theme = "training-theme"; + } + store.appEl.playSound("click2"); + } + } + + // step 2 + chooseType(e) { + if (!e.target.comingSoon) { + const { type } = e.target; + store.site.type = type; + store.appEl.playSound("click2"); + } + } + // step 2, doc import + async docxImport(e) { + if (!e.target.comingSoon) { + const { type } = e.target; + import( + "@haxtheweb/file-system-broker/lib/docx-file-system-broker.js" + ).then(async (e) => { + // enable core services + enableServices(["haxcms"]); + // get the broker for docx selection + const broker = globalThis.FileSystemBroker.requestAvailability(); + const file = await broker.loadFile("docx"); + // tee up as a form for upload + const formData = new FormData(); + formData.append("method", "site"); // this is a site based importer + formData.append("type", toJS(store.site.structure)); + formData.append("upload", file); + this.setProcessingVisual(); + const response = await MicroFrontendRegistry.call( + "@haxcms/docxToSite", + formData, + ); + store.toast(`Processed!`, 300); + // must be a valid response and have at least SOME html to bother attempting + if ( + response.status == 200 && + response.data && + response.data.contents != "" + ) { + store.items = response.data.items; + if (response.data.files) { + store.itemFiles = response.data.files; + } + // invoke a file broker for a docx file + // send to the endpoint and wait + // if it comes back with content, then we engineer details off of it + this.nameTyped = response.data.filename + .replace(".docx", "") + .replace("outline", "") + .replace(/\s/g, "") + .replace(/-/g, "") + .toLowerCase(); + setTimeout(() => { + this.shadowRoot.querySelector("#sitename").value = this.nameTyped; + this.shadowRoot.querySelector("#sitename").select(); + }, 800); + store.site.type = type; + store.site.theme = "clean-one"; + store.appEl.playSound("click2"); + } else { + store.appEl.playSound("error"); + store.toast(`File did not return valid HTML structure`); + } + }); + } + } + // evolution import + async evoImport(e) { + if (!e.target.comingSoon) { + const { type } = e.target; + import("@haxtheweb/file-system-broker/file-system-broker.js").then( + async (e) => { + // enable core services + enableServices(["haxcms"]); + // get the broker for docx selection + const broker = globalThis.FileSystemBroker.requestAvailability(); + const file = await broker.loadFile("zip"); + // tee up as a form for upload + const formData = new FormData(); + formData.append("method", "site"); // this is a site based importer + formData.append("type", toJS(store.site.structure)); + formData.append("upload", file); + // local end point + stupid JWT thing + this.setProcessingVisual(); + const response = await MicroFrontendRegistry.call( + "@haxcms/evolutionToSite", + formData, + null, + null, + "?jwt=" + toJS(store.AppHaxAPI.jwt), + ); + store.toast(`Processed!`, 300); + // must be a valid response and have at least SOME html to bother attempting + if ( + response.status == 200 && + response.data && + response.data.contents != "" + ) { + store.items = response.data.items; + // invoke a file broker for a docx file + // send to the endpoint and wait + // if it comes back with content, then we engineer details off of it + this.nameTyped = response.data.filename + .replace(".zip", "") + .replace("outline", "") + .replace(/\s/g, "") + .replace(/-/g, "") + .toLowerCase(); + setTimeout(() => { + this.shadowRoot.querySelector("#sitename").value = this.nameTyped; + this.shadowRoot.querySelector("#sitename").select(); + }, 800); + store.site.type = type; + store.site.theme = "clean-one"; + store.appEl.playSound("click2"); + } else { + store.appEl.playSound("error"); + store.toast(`File did not return valid HTML structure`); + } + }, + ); + } + } + // gitbook import endpoint + async gbImport(e) { + if (!e.target.comingSoon) { + const { type } = e.target; + let gbURL = globalThis.prompt("URL for the Gitbook repo"); + enableServices(["haxcms"]); + this.setProcessingVisual(); + const response = await MicroFrontendRegistry.call( + "@haxcms/gitbookToSite", + { md: gbURL }, + ); + store.toast(`Processed!`, 300); + // must be a valid response and have at least SOME html to bother attempting + if ( + response.status == 200 && + response.data && + response.data.contents != "" + ) { + store.items = response.data.items; + if (response.data.files) { + store.itemFiles = response.data.files; + } + // invoke a file broker for a docx file + // send to the endpoint and wait + // if it comes back with content, then we engineer details off of it + this.nameTyped = response.data.filename + .replace(/\s/g, "") + .replace(/-/g, "") + .toLowerCase(); + setTimeout(() => { + this.shadowRoot.querySelector("#sitename").value = this.nameTyped; + this.shadowRoot.querySelector("#sitename").select(); + }, 800); + store.site.type = type; + store.site.theme = "clean-one"; + store.appEl.playSound("click2"); + } else { + store.appEl.playSound("error"); + store.toast(`Repo did not return valid structure`); + } + } + } + async importFromURL(e) { + const { type, prompt, callback, param } = e.target; + if (!e.target.comingSoon) { + let promptUrl = globalThis.prompt(prompt); + enableServices(["haxcms"]); + this.setProcessingVisual(); + const params = {}; + params[param] = promptUrl; + const response = await MicroFrontendRegistry.call(callback, params); + store.toast(`Processed!`, 300); + // must be a valid response and have at least SOME html to bother attempting + if ( + response.status == 200 && + response.data && + response.data.contents != "" + ) { + store.items = response.data.items; + if (response.data.files) { + store.itemFiles = response.data.files; + } + // invoke a file broker for a docx file + // send to the endpoint and wait + // if it comes back with content, then we engineer details off of it + this.nameTyped = response.data.filename + .replace(/\s/g, "") + .replace(/-/g, "") + .toLowerCase(); + setTimeout(() => { + this.shadowRoot.querySelector("#sitename").value = this.nameTyped; + this.shadowRoot.querySelector("#sitename").select(); + }, 800); + store.site.type = type; + store.site.theme = "clean-one"; + store.appEl.playSound("click2"); + } else { + store.appEl.playSound("error"); + store.toast(`Repo did not return valid structure`); + } + } + } + // notion import endpoint + async notionImport(e) { + if (!e.target.comingSoon) { + const { type } = e.target; + let notionUrl = globalThis.prompt("URL for the Github Notion repo"); + enableServices(["haxcms"]); + this.setProcessingVisual(); + const response = await MicroFrontendRegistry.call( + "@haxcms/notionToSite", + { repoUrl: notionUrl }, + ); + store.toast(`Processed!`, 300); + // must be a valid response and have at least SOME html to bother attempting + if ( + response.status == 200 && + response.data && + response.data.contents != "" + ) { + store.items = response.data.items; + if (response.data.files) { + store.itemFiles = response.data.files; + } + // invoke a file broker for a docx file + // send to the endpoint and wait + // if it comes back with content, then we engineer details off of it + this.nameTyped = response.data.filename + .replace(/\s/g, "") + .replace(/-/g, "") + .toLowerCase(); + setTimeout(() => { + this.shadowRoot.querySelector("#sitename").value = this.nameTyped; + this.shadowRoot.querySelector("#sitename").select(); + }, 800); + store.site.type = type; + store.site.theme = "clean-one"; + store.appEl.playSound("click2"); + } else { + store.appEl.playSound("error"); + store.toast(`Repo did not return valid structure`); + } + } + } + // pressbooks import endpoint + async pressbooksImport(e) { + if (!e.target.comingSoon) { + const { type } = e.target; + import( + "@haxtheweb/file-system-broker/lib/docx-file-system-broker.js" + ).then(async (e) => { + // enable core services + enableServices(["haxcms"]); + // get the broker for docx selection + const broker = globalThis.FileSystemBroker.requestAvailability(); + const file = await broker.loadFile("html"); + // tee up as a form for upload + const formData = new FormData(); + formData.append("method", "site"); // this is a site based importer + formData.append("type", toJS(store.site.structure)); + formData.append("upload", file); + this.setProcessingVisual(); + const response = await MicroFrontendRegistry.call( + "@haxcms/pressbooksToSite", + formData, + ); + store.toast(`Processed!`, 300); + // must be a valid response and have at least SOME html to bother attempting + if ( + response.status == 200 && + response.data && + response.data.contents != "" + ) { + store.items = response.data.items; + if (response.data.files) { + store.itemFiles = response.data.files; + } + // invoke a file broker for a html file + // send to the endpoint and wait + // if it comes back with content, then we engineer details off of it + this.nameTyped = response.data.filename + .replace(".html", "") + .replace("outline", "") + .replace(/\s/g, "") + .replace(/-/g, "") + .toLowerCase(); + setTimeout(() => { + this.shadowRoot.querySelector("#sitename").value = this.nameTyped; + this.shadowRoot.querySelector("#sitename").select(); + }, 800); + store.site.type = type; + store.site.theme = "clean-one"; + store.appEl.playSound("click2"); + } else { + store.appEl.playSound("error"); + store.toast(`File did not return valid HTML structure`); + } + }); + } + } + // makes guy have hat on, shows it's doing something + setProcessingVisual() { + let loadingIcon = globalThis.document.createElement("simple-icon-lite"); + loadingIcon.icon = "hax:loading"; + loadingIcon.style.setProperty("--simple-icon-height", "40px"); + loadingIcon.style.setProperty("--simple-icon-width", "40px"); + loadingIcon.style.height = "150px"; + loadingIcon.style.marginLeft = "8px"; + store.toast(`Processing`, 60000, { + hat: "construction", + slot: loadingIcon, + }); + } + // step 3 + chooseTheme(e) { + if (!e.target.comingSoon) { + const { value } = e.target; + store.site.theme = value; + store.appEl.playSound("click2"); + } + } + + // step 4 + chooseName() { + if (this.nameTyped !== "") { + const value = this.shadowRoot.querySelector("#sitename").value; + store.site.name = value; + store.appEl.playSound("click2"); + } + } + + progressReady(e) { + if (e.detail) { + this._progressReady = true; + if (this.step === 5) { + setTimeout(() => { + this.shadowRoot.querySelector("app-hax-hat-progress").process(); + }, 300); + } + } + } + + updated(changedProperties) { + if (super.updated) { + super.updated(changedProperties); + } + changedProperties.forEach((oldValue, propName) => { + // set input field to whats in store if we have it + if (this.step === 4 && propName === "step" && this.shadowRoot) { + this.shadowRoot.querySelector("#sitename").value = toJS( + store.site.name, + ); + } + // progress + if ( + this.step === 5 && + propName === "step" && + this.shadowRoot && + this._progressReady + ) { + setTimeout(() => { + this.shadowRoot.querySelector("app-hax-hat-progress").process(); + }, 600); + } + // update the store for step when it changes internal to our step flow + if (propName === "step") { + store.step = this.step; + } + if (propName === "unlockTerrible" && this[propName]) { + Object.keys(themeContext).forEach((key) => { + themeContext[key] = [ + ...themeContext[key], + "terrible-themes", + "terrible-productionz-themes", + "terrible-outlet-themes", + "terrible-best-themes", + "terrible-resume-themes", + ]; + }); + const contextKey = toJS(store.site.structure); + this.themeNames = Object.keys(this.appSettings.themes).filter( + (value) => + contextKey && + themeContext[contextKey] && + themeContext[contextKey].includes(value), + ); + } + }); + } + + connectedCallback() { + super.connectedCallback(); + globalThis.addEventListener("resize", this.maintainScroll.bind(this), { + signal: this.windowControllers.signal, + }); + globalThis.addEventListener("popstate", this.popstateListener.bind(this), { + signal: this.windowControllers.signal, + }); + } + + disconnectedCallback() { + this.windowControllers.abort(); + super.disconnectedCallback(); + } + + // see if user navigates forward or backward while in app + popstateListener(e) { + // filter out vaadin link clicks which have a state signature + if (e.type === "popstate" && e.state === null) { + // a lot going on here, just to be safe + try { + // the delay allows clicking for step to change, process, and then testing it + setTimeout(() => { + const link = e.target.document.location.pathname.split("/").pop(); + // other links we don't care about validating state + if (link.includes("createSite")) { + const step = parseInt(link.replace("createSite-step-", "")); + if (step < store.stepTest(step)) { + this.shadowRoot.querySelector("#link-step-" + step).click(); + } else if (step > store.stepTest(step)) { + store.toast(`Please select an option`); + this.step = store.stepTest(step); + // forces state by maintaining where we are + this.shadowRoot.querySelector("#link-step-" + this.step).click(); + } + } + }, 0); + } catch (e) {} + } + } + + // account for resizing + maintainScroll() { + if (this.shadowRoot && this.step) { + this.scrollToThing(`#step-${this.step}`, { + behavior: "instant", + block: "start", + inline: "nearest", + }); + // account for an animated window drag... stupid. + setTimeout(() => { + this.scrollToThing(`#step-${this.step}`, { + behavior: "instant", + block: "start", + inline: "nearest", + }); + }, 100); + } + } + + firstUpdated(changedProperties) { + if (super.firstUpdated) { + super.firstUpdated(changedProperties); + } + setTimeout(() => { + // ensure paint issues not a factor for null step + if (this.step === null) { + this.step = 1; + } + this.scrollToThing(`#step-${this.step}`, { + behavior: "instant", + block: "start", + inline: "nearest", + }); + }, 100); + + autorun(() => { + // verify we are in the site creation process + if (toJS(store.createSiteSteps) && toJS(store.appReady)) { + const location = toJS(store.location); + if (location.route && location.route.step && location.route.name) { + // account for an animated window drag... stupid. + setTimeout(() => { + this.scrollToThing("#".concat(location.route.name), { + behavior: "smooth", + block: "start", + inline: "nearest", + }); + /// just for step 4 since it has an input + if (location.route.step === 4 && store.stepTest(4) === 4) { + setTimeout(() => { + this.shadowRoot.querySelector("#sitename").focus(); + this.scrollToThing(`#step-4`, { + behavior: "instant", + block: "start", + inline: "nearest", + }); + }, 800); + } + }, 300); // this delay helps w/ initial paint timing but also user perception + // there's a desire to have a delay especialy when tapping things of + // about 300ms + } + } + }); + autorun(() => { + if ( + this.shadowRoot && + toJS(store.createSiteSteps) && + toJS(store.appReady) + ) { + const activeItem = toJS(store.activeItem); + if ( + activeItem && + activeItem.name && + activeItem.step && + !this.__overrideProgression + ) { + this.shadowRoot + .querySelector("#link-".concat(activeItem.name)) + .click(); + } + } + }); + } + + /** + * Yet another reason Apple doesn't let us have nice things. + * This detects the NONSTANDARD BS VERSION OF SCROLLINTOVIEW + * and then ensures that it incorrectly calls to scroll into view + * WITHOUT the wonderful params that ALL OTHER BROWSERS ACCEPT + * AND MAKE OUR LIVES SO WONDERFUL TO SCROLL TO THINGS SMOOTHLY + */ + scrollToThing(sel, props) { + const isSafari = globalThis.safari !== undefined; + if ( + this.shadowRoot.querySelector(".carousel-with-snapping-item.active-step") + ) { + this.shadowRoot + .querySelector(".carousel-with-snapping-item.active-step") + .classList.remove("active-step"); + } + if (isSafari) { + this.shadowRoot.querySelector(sel).scrollIntoView(); + } else { + this.shadowRoot.querySelector(sel).scrollIntoView(props); + } + this.shadowRoot.querySelector(sel).classList.add("active-step"); + } + + static get styles() { + return [ + super.styles, + css` + :host { + display: block; + } + scrollable-component { + --scrollbar-width: 0px; + --scrollbar-height: 0px; + --scrollbar-padding: 0; + --viewport-overflow-x: hidden; + overflow: hidden; + } + #grid-container { + display: grid; + grid-template-columns: 200px 200px 200px; + background: transparent; + } + .carousel-with-snapping-track { + display: grid; + grid-auto-flow: column; + grid-gap: 30px; + } + .carousel-with-snapping-item { + display: flex; + flex-direction: column; + align-items: center; + justify-content: normal; + scroll-snap-align: center; + scroll-snap-stop: always; + scrollbar-gutter: stable; + width: var(--viewport-width); + font-size: 1.5rem; + text-align: center; + overflow-x: hidden; + max-height: 60vh; + padding-top: 1vh; + } + #step-links { + padding: 0; + margin: 0; + } + ul, + li { + list-style: none; + } + li { + vertical-align: middle; + display: inline-flex; + margin: 5px; + } + li.step { + border-radius: 50%; + background-color: transparent; + } + li a { + font-size: 12px; + color: var(--simple-colors-default-theme-grey-12, white); + text-decoration: none; + padding: 5px; + width: 20px; + height: 20px; + line-height: 20px; + margin: 0; + display: block; + border: 0; + border-radius: 50%; + background-repeat: no-repeat; + background-size: 30px 30px; + background-color: var(--simple-colors-default-theme-grey-1, white); + background-image: url("${unsafeCSS(enabledCircle)}"); + transition: + 0.3s ease-in-out background, + 0.3s ease-in-out color; + transition-delay: 0.6s, 0.3s; + } + li a[disabled] { + background-image: url("${unsafeCSS(disabledCircle)}"); + pointer-events: none; + color: var(--simple-colors-default-theme-grey-7, grey); + user-select: none; + } + li[disabled] { + background-color: grey; + } + li.active-step a { + background-color: orange; + background-image: url("${unsafeCSS(transparentCircle)}"); + } + app-hax-button { + padding: 10px 0px 10px 0px; + background: transparent; + } + #theme-container { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + } + img { + pointer-events: none; + } + #themeContainer { + width: 70vw; + height: 55vh; + } + .theme-button { + background-color: transparent; + color: var(--simple-colors-default-theme-grey-12, white); + border: none; + margin: 8px; + padding: 8px; + width: 245px; + } + + .theme-button div { + font-family: "Press Start 2P", sans-serif; + font-size: 14px; + margin-top: 12px; + } + .theme-button:focus, + .theme-button:hover { + outline: 4px solid var(--app-hax-accent-color, var(--accent-color)); + outline-offset: 4px; + background-color: transparent; + border: none; + cursor: pointer; + } + #sitename { + font-family: "Press Start 2P", sans-serif; + font-size: 32px; + padding: 8px; + width: 40vw; + } + #homebtn { + --simple-icon-height: 30px; + --simple-icon-width: 30px; + border-radius: 50%; + cursor: pointer; + background-color: var(--simple-colors-default-theme-grey-1, white); + } + .homelnk { + background-image: none; + display: flex; + padding: 0; + margin: 0; + height: 30px; + width: 30px; + } + app-hax-site-button { + justify-content: center; + --app-hax-site-button-width: 35vw; + --app-hax-site-button-min-width: 240px; + } + app-hax-hat-progress { + height: 400px; + width: 400px; + display: block; + } + + @media (max-width: 800px) { + .theme-button { + width: unset; + padding: 0; + } + .theme-button div { + font-size: 12px; + margin-top: 8px; + } + .theme-button img { + height: 70px; + } + app-hax-site-button { + width: 320px; + max-width: 60vw; + --app-hax-site-button-font-size: 2.5vw; + } + #sitename { + width: 70vw; + font-size: 20px; + } + #grid-container { + grid-template-columns: 150px 150px 150px; + } + } + @media (max-height: 600px) { + .carousel-with-snapping-item { + padding-top: 4px; + max-height: 57vh; + } + #sitename { + width: 40vw; + font-size: 14px; + } + app-hax-hat-progress { + transform: scale(0.5); + margin-top: -18vh; + } + } + @media (max-width: 500px) { + app-hax-hat-progress { + transform: scale(0.5); + margin-top: -15vh; + } + } + @media (max-height: 400px) { + .carousel-with-snapping-item { + padding-top: 4px; + max-height: 40vh; + } + app-hax-hat-progress { + transform: scale(0.3); + } + .carousel-with-snapping-item.active-step app-hax-hat-progress { + position: fixed; + top: 20%; + left: 20%; + } + } + `, + ]; + } + + progressFinished(e) { + if (e.detail) { + this.loaded = true; + store.appEl.playSound("success"); + // focus the button for going to the site + e.target.shadowRoot.querySelector(".game").focus(); + this.scrollToThing(`#step-${this.step}`, { + behavior: "instant", + block: "start", + inline: "nearest", + }); + } + } + + typeKey() { + this.nameTyped = this.shadowRoot.querySelector("#sitename").value; + } + keydown(e) { + // some trapping for common characters that make us sad + if ( + [ + " ", + "/", + "\\", + "&", + "#", + "?", + "+", + "=", + "{", + "}", + "|", + "^", + "~", + "[", + "]", + "`", + '"', + "'", + ].includes(e.key) + ) { + store.appEl.playSound("error"); + store.toast(`"${e.key}" is not allowed. Use - or _`); + e.preventDefault(); + } else if (e.key === "Enter") { + this.chooseName(); + } else if ( + ["ArrowUp", "ArrowRight", "ArrowDown", "ArrowLeft"].includes(e.key) + ) { + // do nothing, directional keys for modifying word + } else { + store.appEl.playSound("click"); + } + } + + stepLinkClick(e) { + const clickedStep = parseInt(e.target.getAttribute("data-step"), 10); + if (this.step < clickedStep) { + e.preventDefault(); + } else if (e.target.getAttribute("data-step") === null) { + store.createSiteSteps = false; + store.appMode = "home"; + this.nameTyped = ""; + store.siteReady = false; + store.site.structure = null; + store.site.type = null; + store.site.theme = null; + store.site.name = null; + } + // means user went backwards + else if (this.step > clickedStep) { + this.nameTyped = ""; + store.siteReady = false; + if (clickedStep === 1) { + store.site.structure = null; + store.site.type = null; + store.site.theme = null; + store.site.name = null; + } else if (clickedStep === 2) { + store.site.type = null; + store.site.theme = null; + store.site.name = null; + } else if (clickedStep === 3) { + store.site.theme = null; + store.site.name = null; + } else if (clickedStep === 4) { + store.site.name = null; + } + this.step = clickedStep; + } + } + + renderTypes(step) { + const structure = toJS(store.site.structure); + var template = html``; + switch (structure) { + case "collection": + template = html` + + + `; + break; + default: + case "course": + template = html` + `; + break; + case "website": + template = html` `; + break; + case "training": + template = html` `; + break; + case "blog": + template = html` `; + break; + case "import": + template = html` + + + + + + + `; + break; + } + return template; + } + + render() { + return html` +
+ + + + +
+ `; + } +} +customElements.define(AppHaxSteps.tag, AppHaxSteps); diff --git a/elements/app-hax/lib/v2/app-hax-toast.js b/elements/app-hax/lib/v2/app-hax-toast.js new file mode 100644 index 0000000000..814abcdb3a --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-toast.js @@ -0,0 +1,60 @@ +import { autorun, toJS } from "mobx"; +import { store } from "./AppHaxStore.js"; +import { RPGCharacterToast } from "../rpg-character-toast/rpg-character-toast.js"; + +export class AppHaxToast extends RPGCharacterToast { + static get tag() { + return "app-hax-toast"; + } + + constructor() { + super(); + this.windowControllers = new AbortController(); + autorun(() => { + this.userName = toJS(store.user.name); + }); + autorun(() => { + this.darkMode = toJS(store.darkMode); + }); + } + + connectedCallback() { + super.connectedCallback(); + globalThis.addEventListener( + "haxcms-toast-hide", + this.hideSimpleToast.bind(this), + { signal: this.windowControllers.signal }, + ); + + globalThis.addEventListener( + "haxcms-toast-show", + this.showSimpleToast.bind(this), + { signal: this.windowControllers.signal }, + ); + } + + hideSimpleToast(e) { + this.hide(); + } + + /** + * life cycle, element is removed from the DOM + */ + disconnectedCallback() { + this.windowControllers.abort(); + super.disconnectedCallback(); + } +} +customElements.define(AppHaxToast.tag, AppHaxToast); +globalThis.AppHaxToast = globalThis.AppHaxToast || {}; + +globalThis.AppHaxToast.requestAvailability = () => { + if (!globalThis.AppHaxToast.instance) { + globalThis.AppHaxToast.instance = globalThis.document.createElement( + AppHaxToast.tag, + ); + globalThis.document.body.appendChild(globalThis.AppHaxToast.instance); + } + return globalThis.AppHaxToast.instance; +}; +export const AppHaxToastInstance = globalThis.AppHaxToast.requestAvailability(); diff --git a/elements/app-hax/lib/v2/app-hax-top-bar.js b/elements/app-hax/lib/v2/app-hax-top-bar.js new file mode 100644 index 0000000000..300145aa56 --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-top-bar.js @@ -0,0 +1,130 @@ +// dependencies / things imported +import { LitElement, html, css } from "lit"; +import "./app-hax-wired-toggle.js"; +import { SimpleTourFinder } from "@haxtheweb/simple-popover/lib/SimpleTourFinder.js"; + +// top bar of the UI +export class AppHaxTopBar extends LitElement { + // a convention I enjoy so you can change the tag name in 1 place + static get tag() { + return "app-hax-top-bar"; + } + + constructor() { + super(); + this.editMode = false; + } + + static get properties() { + return { + editMode: { + type: Boolean, + reflect: true, + attribute: "edit-mode", + }, + }; + } + + static get styles() { + return css` + :host { + --bg-color: var(--app-hax-background-color); + --accent-color: var(--app-hax-accent-color); + --top-bar-height: 48px; + display: block; + height: var(--top-bar-height); + } + + /* @media (prefers-color-scheme: dark) { + :root { + --accent-color: white; + color: var(--accent-color); + + } + + :host { + background-color: black; + } + } */ + + .topBar { + overflow: hidden; + background-color: var(--bg-color); + color: var(--accent-color); + height: var(--top-bar-height); + text-align: center; + vertical-align: middle; + border-bottom: 3px solid var(--app-hax-accent-color); + display: grid; + grid-template-columns: 32.5% 35% 32.5%; + transition: border-bottom 0.6s ease-in-out; + } + + :host([edit-mode]) .topBar { + border-bottom: 6px solid black; + } + + /* .topBar > div { + background-color: rgba(255, 255, 255, 0.8); + border: 1px solid black; + } */ + + .topBar .left { + text-align: left; + height: var(--top-bar-height); + vertical-align: text-top; + } + + .topBar .center { + text-align: center; + height: var(--top-bar-height); + vertical-align: text-top; + } + + .topBar .right { + text-align: right; + height: var(--top-bar-height); + vertical-align: text-top; + } + @media (max-width: 640px) { + .topBar .left { + opacity: 0; + pointer-events: none; + } + .topBar .center { + text-align: left; + } + .topBar .right { + text-align: left; + } + #home { + display: none; + } + app-hax-search-bar { + display: none; + } + .topBar { + grid-template-columns: 0% 35% 65%; + display: inline-grid; + } + } + `; + } + + render() { + return html` +
+
+ +
+
+ +
+
+ +
+
+ `; + } +} +customElements.define(AppHaxTopBar.tag, AppHaxTopBar); diff --git a/elements/app-hax/lib/v2/app-hax-user-menu-button.js b/elements/app-hax/lib/v2/app-hax-user-menu-button.js new file mode 100644 index 0000000000..a3870224ac --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-user-menu-button.js @@ -0,0 +1,70 @@ +// TODO: Text-overflow-ellipses + +// dependencies / things imported +import { LitElement, html, css } from "lit"; + +export class AppHaxUserMenuButton extends LitElement { + // a convention I enjoy so you can change the tag name in 1 place + static get tag() { + return "app-hax-user-menu-button"; + } + + constructor() { + super(); + this.icon = "account-circle"; + this.label = "Default"; + } + + static get properties() { + return { + icon: { type: String }, + label: { type: String }, + }; + } + + static get styles() { + return css` + :host { + font-family: "Press Start 2P", sans-serif; + text-align: center; + width: 100%; + --background-color: var(--app-hax-background-color); + --accent-color: var(--app-hax-accent-color); + } + + .menu-button { + display: block; + width: 100%; + border: 2px solid var(--accent-color); + margin: 0; + padding: 8px; + font-size: 16px; + text-align: left; + color: var(--accent-color); + background-color: var(--background-color); + cursor: pointer; + } + + .menu-button:hover, + .menu-button:active, + .menu-button:focus { + background-color: var(--accent-color); + color: var(--background-color); + } + + .icon { + padding-right: 16px; + } + `; + } + + render() { + return html` + + `; + } +} +customElements.define(AppHaxUserMenuButton.tag, AppHaxUserMenuButton); diff --git a/elements/app-hax/lib/v2/app-hax-user-menu.js b/elements/app-hax/lib/v2/app-hax-user-menu.js new file mode 100644 index 0000000000..8b03e726e3 --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-user-menu.js @@ -0,0 +1,110 @@ +// TODO: Create app-hax-user-menu-button to be tossed into this +// TODO: Create prefix and suffix sections for sound/light toggles and other shtuff + +// dependencies / things imported +import { LitElement, html, css } from "lit"; + +export class AppHaxUserMenu extends LitElement { + // a convention I enjoy so you can change the tag name in 1 place + static get tag() { + return "app-hax-user-menu"; + } + + constructor() { + super(); + this.isOpen = false; + this.icon = "account-circle"; + } + + static get properties() { + return { + isOpen: { type: Boolean, reflect: true, attribute: "is-open" }, + icon: { type: String, reflect: true }, + }; + } + + static get styles() { + return css` + :host { + font-family: "Press Start 2P", sans-serif; + text-align: center; + display: inline-block; + margin: 0px; + padding: 0px; + } + + .entireComponent { + max-height: 48px; + } + + .menuToggle { + cursor: pointer; + max-height: 48px; + } + + .user-menu { + display: none; + } + + .user-menu.open { + display: block; + top: 50px; + right: 0px; + position: absolute; + border: 1px solid var(--app-hax-accent-color); + background-color: var(--app-hax-background-color); + } + + .user-menu.open ::slotted(*) { + display: block; + width: 100%; + margin: 0; + font-size: 16px; + text-align: left; + font-family: "Press Start 2P", sans-serif; + color: var(--app-hax-accent-color); + background-color: var(--app-hax-background-color); + } + + .user-menu.open .main-menu ::slotted(*:hover), + .user-menu.open .main-menu ::slotted(*:active), + .user-menu.open .main-menu ::slotted(*:focus) { + background-color: var(--app-hax-background-color-active); + color: var(--app-hax-background-color); + } + + .user-menu ::slotted(button) { + cursor: pointer; + } + + .user-menu ::slotted(*) simple-icon-lite { + padding-right: 16px; + } + `; + } + + render() { + return html` +
+ + +
+
+ +
+ +
+ +
+
+
+ `; + } +} +customElements.define(AppHaxUserMenu.tag, AppHaxUserMenu); diff --git a/elements/app-hax/lib/v2/app-hax-wired-toggle.js b/elements/app-hax/lib/v2/app-hax-wired-toggle.js new file mode 100644 index 0000000000..5d3b2d486e --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-wired-toggle.js @@ -0,0 +1,47 @@ +import { autorun, toJS } from "mobx"; +import { html } from "lit"; +import { store } from "./AppHaxStore.js"; +import { WiredDarkmodeToggle } from "../wired-darkmode-toggle/wired-darkmode-toggle.js"; +import { SimpleTourFinder } from "@haxtheweb/simple-popover/lib/SimpleTourFinder.js"; + +export class AppHAXWiredToggle extends SimpleTourFinder(WiredDarkmodeToggle) { + constructor() { + super(); + this.tourName = "hax"; + autorun(() => { + this.checked = toJS(store.darkMode); + }); + } + + static get tag() { + return "app-hax-wired-toggle"; + } + + updated(changedProperties) { + if (super.updated) { + super.updated(changedProperties); + } + changedProperties.forEach((oldValue, propName) => { + if (propName === "checked" && oldValue !== undefined) { + store.darkMode = this[propName]; + store.appEl.playSound("click"); + } + }); + } + render() { + return html` +
+ ${super.render()} +
+ You can toggle your user interface between "light" and "dark" for you + viewing enjoyment. +
+
+ `; + } +} +customElements.define(AppHAXWiredToggle.tag, AppHAXWiredToggle); From 57e9ea93ee85e7f217330f9c8f2f523d36697d5c Mon Sep 17 00:00:00 2001 From: izzabizz5 Date: Mon, 10 Feb 2025 14:13:57 -0500 Subject: [PATCH 003/166] initial commit --- elements/app-hax/lib/v2/app-hax-button.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elements/app-hax/lib/v2/app-hax-button.js b/elements/app-hax/lib/v2/app-hax-button.js index f20af41f16..a5c12f48e0 100644 --- a/elements/app-hax/lib/v2/app-hax-button.js +++ b/elements/app-hax/lib/v2/app-hax-button.js @@ -11,7 +11,7 @@ export class AppHaxButton extends LitElement { static get tag() { return "app-hax-button"; } - +// heeyyyyyyyy heeeyyyyyy constructor() { super(); this.icon = "save"; From 47dd16f8685012e0ecb51bb0d65117273cfa8670 Mon Sep 17 00:00:00 2001 From: izzabizz5 Date: Tue, 11 Feb 2025 12:26:45 -0500 Subject: [PATCH 004/166] implementing json for templates and loading with some data --- elements/app-hax/lib/v2/app-hax-receipes.json | 225 ++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100644 elements/app-hax/lib/v2/app-hax-receipes.json diff --git a/elements/app-hax/lib/v2/app-hax-receipes.json b/elements/app-hax/lib/v2/app-hax-receipes.json new file mode 100644 index 0000000000..18b7f24beb --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-receipes.json @@ -0,0 +1,225 @@ +{ + "status": 200, + "item": [ + { + "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350 (rn they have the same uuid so change that)", + "theme-tag": "collections-theme", + "path-to-theme": "", + "template-tag": "collection", + "title": "something to describe the theme", + "author": "author of theme? idk if we need this or not", + "image": "I want a screenshot of the thing for the image", + "description": "describe what a collection is or describe theme", + "alt": "if image doesnt display or something", + "license": "idk", + "icon": "if we wanted to display the cards like they have on the oer course website", + "demo-url": "should this be in the json or hardcoded in the js file", + "site-url": "this same question as demo", + "attributes": [ + { "icon": "value", "tooltip": "value"}, + { "icon": "value", "tooltip": "value"}, + { "icon": "value", "tooltip": "value"} + ] + }, + { + "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350", + "theme-tag": "bootstrap-theme", + "path-to-theme": "", + "template-tag": "collection", + "title": "value", + "author": "value", + "image": "value", + "description": "value", + "alt": "value", + "license": "value", + "icon": "value", + "demo-url": "value", + "site-url": "value", + "attributes": [ + { "icon": "value", "tooltip": "value"}, + { "icon": "value", "tooltip": "value"}, + { "icon": "value", "tooltip": "value"} + ] + }, + { + "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350", + "theme-tag": "haxor-slevin", + "path-to-theme": "", + "template-tag": "blog", + "title": "Haxor Slevin", + "author": "btopro", + "image": "value", + "description": "Haxor Slevin offers a clean layout optimized for showcasing code snippets, technical articles, and developer-focused content.", + "alt": "Screenshot of the Haxor Slevin theme showing blog layout", + "license": "Apache-2.0", + "icon": "value", + "demo-url": "value", + "site-url": "value", + "attributes": [ + { "icon": "value", "tooltip": "value"}, + { "icon": "value", "tooltip": "value"}, + { "icon": "value", "tooltip": "value"} + ] + }, + { + "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350", + "theme-tag": "clean-one", + "path-to-theme": "", + "template-tag": "course", + "title": "Clean One for Courses", + "author": "value", + "image": "value", + "description": "Clean One Course features a clean layout optimized for easy navigation and content consumption, making it ideal for course creators and educational institutions.", + "alt": "Screenshot of Clean One Course theme showing course layout", + "license": "value", + "icon": "value", + "demo-url": "value", + "site-url": "value", + "attributes": [ + { "icon": "value", "tooltip": "value"}, + { "icon": "value", "tooltip": "value"}, + { "icon": "value", "tooltip": "value"} + ] + }, + { + "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350", + "theme-tag": "clean-two", + "path-to-theme": "", + "template-tag": "course", + "title": "value", + "author": "value", + "image": "value", + "description": "Clean Two Course features a clean layout optimized for easy navigation and content consumption, making it ideal for course creators and educational institutions.", + "alt": "Screenshot of Clean Two Course theme showing course layout", + "license": "value", + "icon": "value", + "demo-url": "value", + "site-url": "value", + "attributes": [ + { "icon": "value", "tooltip": "value"}, + { "icon": "value", "tooltip": "value"}, + { "icon": "value", "tooltip": "value"} + ] + }, + { + "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350", + "theme-tag": "learn-two-theme", + "path-to-theme": "", + "template-tag": "course", + "title": "Learn Two for Courses", + "author": "value", + "image": "value", + "description": "Learn Two Course features a clean layout optimized for easy navigation and content consumption, making it ideal for course creators and educational institutions.", + "alt": "Screenshot of Learn Two Course theme showing course layout", + "license": "value", + "icon": "value", + "demo-url": "value", + "site-url": "value", + "attributes": [ + { "icon": "value", "tooltip": "value"}, + { "icon": "value", "tooltip": "value"}, + { "icon": "value", "tooltip": "value"} + ] + }, + { + "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350", + "theme-tag": "polaris-flex-theme", + "path-to-theme": "", + "template-tag": "website", + "title": "Polaris Flex for Websites", + "author": "value", + "image": "value", + "description": "Highly customizable theme designed for creating modern, responsive websites.", + "alt": "Screenshot of Polaris Flex theme showing website layout", + "license": "value", + "icon": "value", + "demo-url": "value", + "site-url": "value", + "attributes": [ + { "icon": "value", "tooltip": "value"}, + { "icon": "value", "tooltip": "value"}, + { "icon": "value", "tooltip": "value"} + ] + }, + { + "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350", + "theme-tag": "polaris-flex-theme", + "path-to-theme": "", + "template-tag": "training", + "title": "Polaris Flex for Trainings", + "author": "value", + "image": "value", + "description": "Highly customizable theme designed for creating modern, responsive trainings.", + "alt": "Screenshot of Polaris Flex theme showing training layout", + "license": "value", + "icon": "value", + "demo-url": "value", + "site-url": "value", + "attributes": [ + { "icon": "value", "tooltip": "value"}, + { "icon": "value", "tooltip": "value"}, + { "icon": "value", "tooltip": "value"} + ] + }, + { + "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350", + "theme-tag": "clean-one", + "path-to-theme": "", + "template-tag": "import", + "title": "Clean One for Import", + "author": "value", + "image": "value", + "description": "Clean One Import features a clean layout optimized for easy navigation and content consumption.", + "alt": "Screenshot of Clean One Import theme showing default layout", + "license": "value", + "icon": "value", + "demo-url": "value", + "site-url": "value", + "attributes": [ + { "icon": "value", "tooltip": "value"}, + { "icon": "value", "tooltip": "value"}, + { "icon": "value", "tooltip": "value"} + ] + }, + { + "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350", + "theme-tag": "clean-two", + "path-to-theme": "", + "template-tag": "import", + "title": "Clean Two for Import", + "author": "value", + "image": "value", + "description": "Clean Two Import features a clean layout optimized for easy navigation and content consumption.", + "alt": "Screenshot of Clean Two Import theme showing default layout", + "license": "value", + "icon": "value", + "demo-url": "value", + "site-url": "value", + "attributes": [ + { "icon": "value", "tooltip": "value"}, + { "icon": "value", "tooltip": "value"}, + { "icon": "value", "tooltip": "value"} + ] + }, + { + "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350", + "theme-tag": "learn-two-theme", + "path-to-theme": "", + "template-tag": "import", + "title": "Learn Two for Imports", + "author": "value", + "image": "value", + "description": "Learn Two Import features a clean layout optimized for easy navigation and content consumption.", + "alt": "Screenshot of Learn Two Import theme showing default layout", + "license": "value", + "icon": "value", + "demo-url": "value", + "site-url": "value", + "attributes": [ + { "icon": "value", "tooltip": "value"}, + { "icon": "value", "tooltip": "value"}, + { "icon": "value", "tooltip": "value"} + ] + } + ] +} \ No newline at end of file From c44c2c6f7204b095ed313b4253152c0acb888659 Mon Sep 17 00:00:00 2001 From: Bryan Ollendyke Date: Tue, 18 Feb 2025 11:42:51 -0500 Subject: [PATCH 005/166] Update app-hax-receipes.json Some better data on initial item from my take --- elements/app-hax/lib/v2/app-hax-receipes.json | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/elements/app-hax/lib/v2/app-hax-receipes.json b/elements/app-hax/lib/v2/app-hax-receipes.json index 18b7f24beb..c7d4c72c34 100644 --- a/elements/app-hax/lib/v2/app-hax-receipes.json +++ b/elements/app-hax/lib/v2/app-hax-receipes.json @@ -2,19 +2,18 @@ "status": 200, "item": [ { - "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350 (rn they have the same uuid so change that)", - "theme-tag": "collections-theme", - "path-to-theme": "", - "template-tag": "collection", - "title": "something to describe the theme", - "author": "author of theme? idk if we need this or not", - "image": "I want a screenshot of the thing for the image", - "description": "describe what a collection is or describe theme", - "alt": "if image doesnt display or something", - "license": "idk", - "icon": "if we wanted to display the cards like they have on the oer course website", - "demo-url": "should this be in the json or hardcoded in the js file", - "site-url": "this same question as demo", + "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350", + "title": "Portfolio", + "recipe": "recipes/portfolio/portfolio.recipe", + "theme": { + "element": "clean-portfolio", + "path": "@haxtheweb/clean-portfolio/clean-portfolio.js", + }, + "author": "haxtheweb", + "image": "@haxtheweb/clean-portfolio/assets/screenshot.jpg", + "description": "Art gallery, blog posts, any collection of work and self presentation", + "icon": "hax:theme", + "demo-url": "https://playground.hax.cloud/site.html?recipe=", "attributes": [ { "icon": "value", "tooltip": "value"}, { "icon": "value", "tooltip": "value"}, @@ -222,4 +221,4 @@ ] } ] -} \ No newline at end of file +} From 464ee906848f583d7bfd64ed31423f615c28ed8d Mon Sep 17 00:00:00 2001 From: izzabizz5 Date: Tue, 18 Feb 2025 12:07:17 -0500 Subject: [PATCH 006/166] adding icons and reducing cluttered stuff --- elements/app-hax/lib/v2/app-hax-receipes.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/elements/app-hax/lib/v2/app-hax-receipes.json b/elements/app-hax/lib/v2/app-hax-receipes.json index c7d4c72c34..2a667edf6a 100644 --- a/elements/app-hax/lib/v2/app-hax-receipes.json +++ b/elements/app-hax/lib/v2/app-hax-receipes.json @@ -1,7 +1,7 @@ { "status": 200, "item": [ - { + { "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350", "title": "Portfolio", "recipe": "recipes/portfolio/portfolio.recipe", @@ -221,4 +221,4 @@ ] } ] -} +} \ No newline at end of file From 1d7d26a2165da3b8e35e9377bdb9ab649212d69f Mon Sep 17 00:00:00 2001 From: izzabizz5 Date: Tue, 18 Feb 2025 12:07:26 -0500 Subject: [PATCH 007/166] reducing fluff --- elements/app-hax/lib/v2/app-hax-receipes.json | 2 +- elements/app-hax/lib/v2/app-hax-use-case.js | 26 +++++++++++-------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/elements/app-hax/lib/v2/app-hax-receipes.json b/elements/app-hax/lib/v2/app-hax-receipes.json index 2a667edf6a..4199c0aad9 100644 --- a/elements/app-hax/lib/v2/app-hax-receipes.json +++ b/elements/app-hax/lib/v2/app-hax-receipes.json @@ -7,7 +7,7 @@ "recipe": "recipes/portfolio/portfolio.recipe", "theme": { "element": "clean-portfolio", - "path": "@haxtheweb/clean-portfolio/clean-portfolio.js", + "path": "@haxtheweb/clean-portfolio/clean-portfolio.js" }, "author": "haxtheweb", "image": "@haxtheweb/clean-portfolio/assets/screenshot.jpg", diff --git a/elements/app-hax/lib/v2/app-hax-use-case.js b/elements/app-hax/lib/v2/app-hax-use-case.js index 37cfd669d2..3764da4a71 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case.js +++ b/elements/app-hax/lib/v2/app-hax-use-case.js @@ -80,6 +80,15 @@ export class AppHaxUseCase extends LitElement { justify-content: center; color: white; } + #haxIcons { + position: absolute; + bottom: var(--ddd-spacing-2); + left: var(--ddd-spacing-2); + padding: var(--ddd-spacing-1) var(--ddd-spacing-1); + opacity: 0.8; + gap: var(--ddd-spacing-3); + color: var(--ddd-primary-8); + } `, ]; } @@ -93,22 +102,17 @@ export class AppHaxUseCase extends LitElement {

${this.title}

${this.description}

-

Demo>

- +
+ +
`; From fc705651a7128c5292e70058c0273f13abd00304 Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Tue, 18 Feb 2025 12:18:44 -0500 Subject: [PATCH 008/166] messy filtering added --- elements/app-hax/app-hax.js | 67 ++++--- .../app-hax/lib/v2/app-hax-filter-results.js | 177 +++++++++++++++++ elements/app-hax/lib/v2/app-hax-filter.js | 180 ++++++++++++++++++ elements/app-hax/lib/v2/app-hax-search-bar.js | 2 +- elements/app-hax/lib/v2/app-hax-use-case.js | 4 +- elements/app-hax/src/app-hax.js | 67 ++++--- 6 files changed, 444 insertions(+), 53 deletions(-) create mode 100644 elements/app-hax/lib/v2/app-hax-filter-results.js create mode 100644 elements/app-hax/lib/v2/app-hax-filter.js diff --git a/elements/app-hax/app-hax.js b/elements/app-hax/app-hax.js index 1e557e2586..91e8c851ff 100644 --- a/elements/app-hax/app-hax.js +++ b/elements/app-hax/app-hax.js @@ -15,6 +15,8 @@ import "./lib/v2/app-hax-label.js"; import "./lib/v2/app-hax-top-bar.js"; import { SimpleTourFinder } from "@haxtheweb/simple-popover/lib/SimpleTourFinder.js"; import "./lib/v2/app-hax-use-case.js"; +import "./lib/v2/app-hax-filter.js"; +import "./lib/v2/app-hax-filter-results.js"; const logoutBtn = new URL("./lib/assets/images/Logout.svg", import.meta.url) .href; @@ -166,6 +168,14 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} this.unlockTerrible = false; this.t = this.t || {}; + + this.items = []; + this.filteredItems = []; + this.errorMessage = ""; + this.loading = false; + this.demoLink = ""; + + this.t = { ...this.t, selectPage: "Select page", @@ -647,6 +657,13 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} siteReady: { type: Boolean }, basePath: { type: String, attribute: "base-path" }, token: { type: String }, + + + items: { type: Array }, + filteredItems: { type: Array }, + errorMessage: { type: String }, + loading: { type: Boolean }, + demoLink: { type: String} }; } @@ -984,23 +1001,6 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} border: var(--simple-colors-default-theme-grey-12) 2px solid; } } - .filter { - display:flex; - background-color: white; - flex-direction: column; - margin: var(--ddd-spacing-2); - padding: var(--ddd-spacing-4); - background-color: var(--ddd-theme-default-white); - border-radius: var(--ddd-radius-xs); - width: 300px; - } - .filterButtons { - text-align: start; - display: flex; - flex-direction: column; - gap: var(--ddd-spacing-2); - max-width: 150px; - } @media (prefers-reduced-motion: reduce) { app-hax-label { animation: none; @@ -1346,15 +1346,9 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} templateHome() { return html`
- -
- - - - - -
+
+
+ + +
+ ${this.filteredItems.length > 0 + ? this.filteredItems.map( + (item, index) => html` +
+ + + +
+
+ ` + ) + : html`

No templates match the filters specified.

`} +
+ ` } diff --git a/elements/app-hax/lib/v2/app-hax-filter-results.js b/elements/app-hax/lib/v2/app-hax-filter-results.js new file mode 100644 index 0000000000..7a5b231745 --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-filter-results.js @@ -0,0 +1,177 @@ +/* eslint-disable no-return-assign */ +import { SimpleColors } from "@haxtheweb/simple-colors/simple-colors.js"; +import { html, css } from "lit"; +import { autorun, toJS } from "mobx"; +import { varGet } from "@haxtheweb/utils/utils.js"; +import { store } from "./AppHaxStore.js"; +import "./app-hax-filter.js"; + +export class AppHaxFilterResults extends SimpleColors { + // a convention I enjoy so you can change the tag name in 1 place + static get tag() { + return "app-hax-filter-results"; + } + + constructor() { + super(); + this.searchItems = []; + this.displayItems = []; + this.searchTerm = ""; + this.dark = false; + } + + // Site.json is coming from + + static get properties() { + return { + ...super.properties, + searchTerm: { type: String, reflect: true }, + searchItems: { type: Array }, + displayItems: { type: Array }, + }; + } + + updated(changedProperties) { + if ( + changedProperties.has("searchQuery") || + changedProperties.has("activeFilters") || + changedProperties.has("item") + ) { + this.applyFilters(); + } + } + + //Izzy's code from hax-use-case-app + updateResults() { + this.loading = true; + this.errorMessage = ""; // Reset error before fetching + + fetch(new URL('./lib/v2/app-hax-receipes.json', import.meta.url).href) + .then(response => { + if (!response.ok) { + throw new Error('Network response was not ok'); + } + return response.json(); // Parse JSON data + }) + .then(data => { + // Map JSON data to component's items + + if (Array.isArray(data.item)) { + this.items = data.item.map(item => ({ + useCaseTitle: item.title, + useCaseImage: item.image, + useCaseDescription: item.description, + useCaseIcon: item.useCaseAttributes.map(attribute => ({ + icon: attribute.icon, + tooltip: attribute.tooltip + })), + useCaseTag: item.template-tag + })); + this.filteredItems = this.items; + this.filters = []; + + data.item.forEach(item => { + if (Array.isArray(item.tag)) { + item.tag.forEach(tag => { + if (!this.filters.includes(tag)) { + this.filters = [...this.filters, tag]; + } + }); + } + }); + } else { + this.errorMessage = 'No Templates Found'; + } + }) + .catch(error => { + this.errorMessage = `Failed to load data: ${error.message}`; + this.items = []; + this.filteredItems = []; + }) + .finally(() => { + this.loading = false; + }); + } + + static get styles() { + return [ + super.styles, + css` + :host { + overflow: hidden; + } + `, + ]; + } + render() { + return html` +
    + ${this.displayItems.length > 0 + ? this.displayItems.map( + (item) => + html`
  • + + ${item.title} + ${item.author} + +
    + ${item.description} +
    +
    +
    +
  • `, + ) + : html`
    + No results for + ${this.searchTerm !== "" + ? html`"${this.searchTerm}"` + : "your account, try starting a new journey!"}. +
    `} +
+ `; + } + + getItemDetails(item) { + const details = { + created: varGet(item, "metadata.site.created", new Date() / 1000), + updated: varGet(item, "metadata.site.updated", new Date() / 1000), + pages: varGet(item, "metadata.pageCount", 0), + url: item.slug, + }; + return details; + } + + openedChanged(e) { + store.appEl.playSound("click"); + if (!e.detail.value) { + this.shadowRoot + .querySelector("app-hax-site-details") + .setAttribute("tabindex", "-1"); + } else { + this.shadowRoot + .querySelector("app-hax-site-details") + .removeAttribute("tabindex"); + } + } +} +customElements.define(AppHaxFilterResults.tag, AppHaxFilterResults); diff --git a/elements/app-hax/lib/v2/app-hax-filter.js b/elements/app-hax/lib/v2/app-hax-filter.js new file mode 100644 index 0000000000..98673a499e --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-filter.js @@ -0,0 +1,180 @@ +/* eslint-disable no-return-assign */ +import { LitElement, html, css } from "lit"; +import "@haxtheweb/simple-tooltip/simple-tooltip.js"; +import { store } from "./AppHaxStore.js"; + +export class AppHaxFilter extends LitElement { + // a convention I enjoy so you can change the tag name in 1 place + static get tag() { + return "app-hax-filter"; + } + + constructor() { + super(); + this.searchTerm = ""; + this.disabled = false; + this.showSearch = false; + this.searchQuery = ""; + this.activeFilters = []; + this.filters = []; + } + + // Site.json is coming from + + static get properties() { + return { + searchTerm: { type: String }, + showSearch: { type: Boolean, reflect: true, attribute: "show-search" }, + disabled: { type: Boolean, reflect: true }, + searchQuery: { type: String }, + activeFilters: { type: Array }, + filters: { type: Array }, + }; + } + + static get styles() { + return [ + css` + :host { + overflow: hidden; + } + input { + visibility: none; + opacity: 0; + width: 0; + transition: all ease-in-out 0.3s; + padding: 4px; + font-family: "Press Start 2P", sans-serif; + font-size: 20px; + margin: 2px 0 0 16px; + } + :host([show-search]) input { + visibility: visible; + opacity: 1; + width: 250px; + max-width: 25vw; + } + .filter { + display:flex; + background-color: white; + flex-direction: column; + margin: var(--ddd-spacing-2); + padding: var(--ddd-spacing-4); + background-color: var(--ddd-theme-default-white); + border-radius: var(--ddd-radius-xs); + width: 300px; + } + .filterButtons { + text-align: start; + display: flex; + flex-direction: column; + gap: var(--ddd-spacing-2); + max-width: 150px; + } + `, + ]; + } + testKeydown(e) { + if (e.key === "Escape" || e.key === "Enter") { + this.toggleSearch(); + } + } + // eslint-disable-next-line class-methods-use-this + search() { + store.appEl.playSound("click"); + this.searchTerm = this.shadowRoot.querySelector("#searchField").value; + } + + render() { + return html` +
+ + Toggle Search + + +
+ + + + + +
+
+ `; + } + + toggleSearch() { + if (!this.disabled) { + this.shadowRoot.querySelector("#searchField").value = ""; + store.appEl.playSound("click"); + this.showSearch = !this.showSearch; + setTimeout(() => { + this.shadowRoot.querySelector("#searchField").focus(); + }, 300); + } + } + + applyFilters() { + const lowerCaseQuery = this.searchQuery.toLowerCase(); + + this.filteredItems = this.items.filter((item) => { + const matchesSearch = item.useCaseTitle.toLowerCase().includes(lowerCaseQuery); + + const matchesFilters = + this.activeFilters.length === 0 || // No filters means match all + this.activeFilters.some((filter) => item.useCaseTag.includes(filter)); + + return matchesSearch && matchesFilters; + }); + } + + handleSearch(event) { + this.searchQuery = event.target.value.toLowerCase(); + } + + toggleFilter(filter) { + if (this.activeFilters.includes(filter)) { + this.activeFilters = this.activeFilters.filter((f) => f !== filter); + } else { + this.activeFilters = [...this.activeFilters, filter]; + } + } + + resetFilters() { + this.searchQuery = ""; + this.activeFilters = []; // Clear active filters + this.filteredItems = this.items; // Reset to show all items + this.requestUpdate(); // Trigger an update + + // Uncheck checkboxes + const checkboxes = this.shadowRoot.querySelectorAll( + '.filterButtons input[type="checkbox"]' + ); + checkboxes.forEach((checkbox) => (checkbox.checked = false)); + + // Clear search bar + const searchInput = this.shadowRoot.querySelector('#searchField input[type="text"]'); + if (searchInput) { + searchInput.value = ""; + } + } +} +customElements.define(AppHaxFilter.tag, AppHaxFilter); diff --git a/elements/app-hax/lib/v2/app-hax-search-bar.js b/elements/app-hax/lib/v2/app-hax-search-bar.js index c3036f8c76..7806cf9878 100644 --- a/elements/app-hax/lib/v2/app-hax-search-bar.js +++ b/elements/app-hax/lib/v2/app-hax-search-bar.js @@ -136,7 +136,7 @@ export class AppHaxSearchBar extends LitElement { @input="${this.search}" @keydown="${this.testKeydown}" type="text" - placeholder="Site name.." + placeholder="Search Sites.." /> `; } diff --git a/elements/app-hax/lib/v2/app-hax-use-case.js b/elements/app-hax/lib/v2/app-hax-use-case.js index 37cfd669d2..6cd883ae3a 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case.js +++ b/elements/app-hax/lib/v2/app-hax-use-case.js @@ -93,7 +93,7 @@ export class AppHaxUseCase extends LitElement {

${this.title}

${this.description}

- +
diff --git a/elements/app-hax/src/app-hax.js b/elements/app-hax/src/app-hax.js index 1e557e2586..91e8c851ff 100644 --- a/elements/app-hax/src/app-hax.js +++ b/elements/app-hax/src/app-hax.js @@ -15,6 +15,8 @@ import "./lib/v2/app-hax-label.js"; import "./lib/v2/app-hax-top-bar.js"; import { SimpleTourFinder } from "@haxtheweb/simple-popover/lib/SimpleTourFinder.js"; import "./lib/v2/app-hax-use-case.js"; +import "./lib/v2/app-hax-filter.js"; +import "./lib/v2/app-hax-filter-results.js"; const logoutBtn = new URL("./lib/assets/images/Logout.svg", import.meta.url) .href; @@ -166,6 +168,14 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} this.unlockTerrible = false; this.t = this.t || {}; + + this.items = []; + this.filteredItems = []; + this.errorMessage = ""; + this.loading = false; + this.demoLink = ""; + + this.t = { ...this.t, selectPage: "Select page", @@ -647,6 +657,13 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} siteReady: { type: Boolean }, basePath: { type: String, attribute: "base-path" }, token: { type: String }, + + + items: { type: Array }, + filteredItems: { type: Array }, + errorMessage: { type: String }, + loading: { type: Boolean }, + demoLink: { type: String} }; } @@ -984,23 +1001,6 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} border: var(--simple-colors-default-theme-grey-12) 2px solid; } } - .filter { - display:flex; - background-color: white; - flex-direction: column; - margin: var(--ddd-spacing-2); - padding: var(--ddd-spacing-4); - background-color: var(--ddd-theme-default-white); - border-radius: var(--ddd-radius-xs); - width: 300px; - } - .filterButtons { - text-align: start; - display: flex; - flex-direction: column; - gap: var(--ddd-spacing-2); - max-width: 150px; - } @media (prefers-reduced-motion: reduce) { app-hax-label { animation: none; @@ -1346,15 +1346,9 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} templateHome() { return html`
- -
- - - - - -
+
+
+ + +
+ ${this.filteredItems.length > 0 + ? this.filteredItems.map( + (item, index) => html` +
+ + + +
+
+ ` + ) + : html`

No templates match the filters specified.

`} +
+
` } From e30831b2c0ee1ca944123f0797bf0676fafa07ee Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Thu, 20 Feb 2025 10:48:46 -0500 Subject: [PATCH 009/166] combined filter components --- elements/app-hax/app-hax.js | 71 ++----- .../app-hax/lib/v2/app-hax-filter-results.js | 177 ------------------ ...x-filter.js => app-hax-use-case-filter.js} | 106 ++++++++++- elements/app-hax/src/app-hax.js | 71 ++----- 4 files changed, 127 insertions(+), 298 deletions(-) delete mode 100644 elements/app-hax/lib/v2/app-hax-filter-results.js rename elements/app-hax/lib/v2/{app-hax-filter.js => app-hax-use-case-filter.js} (62%) diff --git a/elements/app-hax/app-hax.js b/elements/app-hax/app-hax.js index 91e8c851ff..a6852be7ec 100644 --- a/elements/app-hax/app-hax.js +++ b/elements/app-hax/app-hax.js @@ -15,8 +15,7 @@ import "./lib/v2/app-hax-label.js"; import "./lib/v2/app-hax-top-bar.js"; import { SimpleTourFinder } from "@haxtheweb/simple-popover/lib/SimpleTourFinder.js"; import "./lib/v2/app-hax-use-case.js"; -import "./lib/v2/app-hax-filter.js"; -import "./lib/v2/app-hax-filter-results.js"; +import "./lib/v2/app-hax-use-case.js"; const logoutBtn = new URL("./lib/assets/images/Logout.svg", import.meta.url) .href; @@ -168,14 +167,6 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} this.unlockTerrible = false; this.t = this.t || {}; - - this.items = []; - this.filteredItems = []; - this.errorMessage = ""; - this.loading = false; - this.demoLink = ""; - - this.t = { ...this.t, selectPage: "Select page", @@ -657,13 +648,6 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} siteReady: { type: Boolean }, basePath: { type: String, attribute: "base-path" }, token: { type: String }, - - - items: { type: Array }, - filteredItems: { type: Array }, - errorMessage: { type: String }, - loading: { type: Boolean }, - demoLink: { type: String} }; } @@ -777,6 +761,7 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} css` :host { display: block; + --app-hax-background-color-active: var(--app-hax-accent-color); } #home { display: inline-flex; @@ -1018,9 +1003,6 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} padding-top: 0; } - //added code - - app-hax-site-button { --app-hax-site-button-font-size: 12px; } @@ -1341,48 +1323,19 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} } return template; } - - //EDIT STARTING FROM HERE TO TEST CODE + + //EDIT HERE templateHome() { return html`
-
- -
- -
- - -
- - -
- ${this.filteredItems.length > 0 - ? this.filteredItems.map( - (item, index) => html` -
- - - -
-
- ` - ) - : html`

No templates match the filters specified.

`} -
+ + - - ` + `; } // eslint-disable-next-line class-methods-use-this diff --git a/elements/app-hax/lib/v2/app-hax-filter-results.js b/elements/app-hax/lib/v2/app-hax-filter-results.js deleted file mode 100644 index 7a5b231745..0000000000 --- a/elements/app-hax/lib/v2/app-hax-filter-results.js +++ /dev/null @@ -1,177 +0,0 @@ -/* eslint-disable no-return-assign */ -import { SimpleColors } from "@haxtheweb/simple-colors/simple-colors.js"; -import { html, css } from "lit"; -import { autorun, toJS } from "mobx"; -import { varGet } from "@haxtheweb/utils/utils.js"; -import { store } from "./AppHaxStore.js"; -import "./app-hax-filter.js"; - -export class AppHaxFilterResults extends SimpleColors { - // a convention I enjoy so you can change the tag name in 1 place - static get tag() { - return "app-hax-filter-results"; - } - - constructor() { - super(); - this.searchItems = []; - this.displayItems = []; - this.searchTerm = ""; - this.dark = false; - } - - // Site.json is coming from - - static get properties() { - return { - ...super.properties, - searchTerm: { type: String, reflect: true }, - searchItems: { type: Array }, - displayItems: { type: Array }, - }; - } - - updated(changedProperties) { - if ( - changedProperties.has("searchQuery") || - changedProperties.has("activeFilters") || - changedProperties.has("item") - ) { - this.applyFilters(); - } - } - - //Izzy's code from hax-use-case-app - updateResults() { - this.loading = true; - this.errorMessage = ""; // Reset error before fetching - - fetch(new URL('./lib/v2/app-hax-receipes.json', import.meta.url).href) - .then(response => { - if (!response.ok) { - throw new Error('Network response was not ok'); - } - return response.json(); // Parse JSON data - }) - .then(data => { - // Map JSON data to component's items - - if (Array.isArray(data.item)) { - this.items = data.item.map(item => ({ - useCaseTitle: item.title, - useCaseImage: item.image, - useCaseDescription: item.description, - useCaseIcon: item.useCaseAttributes.map(attribute => ({ - icon: attribute.icon, - tooltip: attribute.tooltip - })), - useCaseTag: item.template-tag - })); - this.filteredItems = this.items; - this.filters = []; - - data.item.forEach(item => { - if (Array.isArray(item.tag)) { - item.tag.forEach(tag => { - if (!this.filters.includes(tag)) { - this.filters = [...this.filters, tag]; - } - }); - } - }); - } else { - this.errorMessage = 'No Templates Found'; - } - }) - .catch(error => { - this.errorMessage = `Failed to load data: ${error.message}`; - this.items = []; - this.filteredItems = []; - }) - .finally(() => { - this.loading = false; - }); - } - - static get styles() { - return [ - super.styles, - css` - :host { - overflow: hidden; - } - `, - ]; - } - render() { - return html` -
    - ${this.displayItems.length > 0 - ? this.displayItems.map( - (item) => - html`
  • - - ${item.title} - ${item.author} - -
    - ${item.description} -
    -
    -
    -
  • `, - ) - : html`
    - No results for - ${this.searchTerm !== "" - ? html`"${this.searchTerm}"` - : "your account, try starting a new journey!"}. -
    `} -
- `; - } - - getItemDetails(item) { - const details = { - created: varGet(item, "metadata.site.created", new Date() / 1000), - updated: varGet(item, "metadata.site.updated", new Date() / 1000), - pages: varGet(item, "metadata.pageCount", 0), - url: item.slug, - }; - return details; - } - - openedChanged(e) { - store.appEl.playSound("click"); - if (!e.detail.value) { - this.shadowRoot - .querySelector("app-hax-site-details") - .setAttribute("tabindex", "-1"); - } else { - this.shadowRoot - .querySelector("app-hax-site-details") - .removeAttribute("tabindex"); - } - } -} -customElements.define(AppHaxFilterResults.tag, AppHaxFilterResults); diff --git a/elements/app-hax/lib/v2/app-hax-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js similarity index 62% rename from elements/app-hax/lib/v2/app-hax-filter.js rename to elements/app-hax/lib/v2/app-hax-use-case-filter.js index 98673a499e..38b7d001ce 100644 --- a/elements/app-hax/lib/v2/app-hax-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -2,11 +2,12 @@ import { LitElement, html, css } from "lit"; import "@haxtheweb/simple-tooltip/simple-tooltip.js"; import { store } from "./AppHaxStore.js"; +import "/lib/v2/app-hax-use-case.js"; -export class AppHaxFilter extends LitElement { +export class AppHaxUseCaseFilter extends LitElement { // a convention I enjoy so you can change the tag name in 1 place static get tag() { - return "app-hax-filter"; + return "app-hax-use-case-filter"; } constructor() { @@ -15,8 +16,21 @@ export class AppHaxFilter extends LitElement { this.disabled = false; this.showSearch = false; this.searchQuery = ""; + this.activeFilters = []; this.filters = []; + + this.items = []; + this.useCaseTitle = ""; + this.useCaseImage = ""; + this.useCaseDescription = ""; + this.useCaseIcon = []; + this.useCaseTag = ""; + + this.filteredItems = []; + this.errorMessage = ""; + this.loading = false; + this.demoLink = ""; } // Site.json is coming from @@ -29,6 +43,12 @@ export class AppHaxFilter extends LitElement { searchQuery: { type: String }, activeFilters: { type: Array }, filters: { type: Array }, + + items: { type: Array }, + filteredItems: { type: Array }, + errorMessage: { type: String }, + loading: { type: Boolean }, + demoLink: { type: String} }; } @@ -85,6 +105,16 @@ export class AppHaxFilter extends LitElement { this.searchTerm = this.shadowRoot.querySelector("#searchField").value; } + updated(changedProperties) { + if ( + changedProperties.has("searchQuery") || + changedProperties.has("activeFilters") || + changedProperties.has("item") + ) { + this.applyFilters(); + } + }S + render() { return html`
@@ -118,6 +148,25 @@ export class AppHaxFilter extends LitElement {
+
+ ${this.filteredItems.length > 0 + ? this.filteredItems.map( + (item, index) => html` +
+ + + +
+ ` + ) + : html`

No templates match the filters specified.

`} +
`; } @@ -176,5 +225,56 @@ export class AppHaxFilter extends LitElement { searchInput.value = ""; } } + + updateResults() { + this.loading = true; + this.errorMessage = ""; // Reset error before fetching + + fetch(new URL('./lib/v2/app-hax-receipes.json', import.meta.url).href) + .then(response => { + if (!response.ok) { + throw new Error('Network response was not ok'); + } + return response.json(); // Parse JSON data + }) + .then(data => { + // Map JSON data to component's items + + if (Array.isArray(data.item)) { + this.items = data.item.map(item => ({ + useCaseTitle: item.title, + useCaseImage: item.image, + useCaseDescription: item.description, + useCaseIcon: item.useCaseAttributes.map(attribute => ({ + icon: attribute.icon, + tooltip: attribute.tooltip + })), + useCaseTag: item.template-tag + })); + this.filteredItems = this.items; + this.filters = []; + + data.item.forEach(item => { + if (Array.isArray(item.tag)) { + item.tag.forEach(tag => { + if (!this.filters.includes(tag)) { + this.filters = [...this.filters, tag]; + } + }); + } + }); + } else { + this.errorMessage = 'No Templates Found'; + } + }) + .catch(error => { + this.errorMessage = `Failed to load data: ${error.message}`; + this.items = []; + this.filteredItems = []; + }) + .finally(() => { + this.loading = false; + }); + } } -customElements.define(AppHaxFilter.tag, AppHaxFilter); +customElements.define(AppHaxUseCaseFilter.tag, AppHaxUseCaseFilter); diff --git a/elements/app-hax/src/app-hax.js b/elements/app-hax/src/app-hax.js index 91e8c851ff..a6852be7ec 100644 --- a/elements/app-hax/src/app-hax.js +++ b/elements/app-hax/src/app-hax.js @@ -15,8 +15,7 @@ import "./lib/v2/app-hax-label.js"; import "./lib/v2/app-hax-top-bar.js"; import { SimpleTourFinder } from "@haxtheweb/simple-popover/lib/SimpleTourFinder.js"; import "./lib/v2/app-hax-use-case.js"; -import "./lib/v2/app-hax-filter.js"; -import "./lib/v2/app-hax-filter-results.js"; +import "./lib/v2/app-hax-use-case.js"; const logoutBtn = new URL("./lib/assets/images/Logout.svg", import.meta.url) .href; @@ -168,14 +167,6 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} this.unlockTerrible = false; this.t = this.t || {}; - - this.items = []; - this.filteredItems = []; - this.errorMessage = ""; - this.loading = false; - this.demoLink = ""; - - this.t = { ...this.t, selectPage: "Select page", @@ -657,13 +648,6 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} siteReady: { type: Boolean }, basePath: { type: String, attribute: "base-path" }, token: { type: String }, - - - items: { type: Array }, - filteredItems: { type: Array }, - errorMessage: { type: String }, - loading: { type: Boolean }, - demoLink: { type: String} }; } @@ -777,6 +761,7 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} css` :host { display: block; + --app-hax-background-color-active: var(--app-hax-accent-color); } #home { display: inline-flex; @@ -1018,9 +1003,6 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} padding-top: 0; } - //added code - - app-hax-site-button { --app-hax-site-button-font-size: 12px; } @@ -1341,48 +1323,19 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} } return template; } - - //EDIT STARTING FROM HERE TO TEST CODE + + //EDIT HERE templateHome() { return html`
-
- -
- -
- - -
- - -
- ${this.filteredItems.length > 0 - ? this.filteredItems.map( - (item, index) => html` -
- - - -
-
- ` - ) - : html`

No templates match the filters specified.

`} -
+ + - - ` + `; } // eslint-disable-next-line class-methods-use-this From f17167356c7af5f38dad8be6ef3170348154b94f Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Thu, 20 Feb 2025 11:25:11 -0500 Subject: [PATCH 010/166] fixed filter to show up --- elements/app-hax/app-hax.js | 7 +- .../app-hax/lib/v2/app-hax-use-case-filter.js | 197 +++++++++--------- elements/app-hax/src/app-hax.js | 7 +- 3 files changed, 106 insertions(+), 105 deletions(-) diff --git a/elements/app-hax/app-hax.js b/elements/app-hax/app-hax.js index a6852be7ec..fb0cfcd285 100644 --- a/elements/app-hax/app-hax.js +++ b/elements/app-hax/app-hax.js @@ -15,7 +15,7 @@ import "./lib/v2/app-hax-label.js"; import "./lib/v2/app-hax-top-bar.js"; import { SimpleTourFinder } from "@haxtheweb/simple-popover/lib/SimpleTourFinder.js"; import "./lib/v2/app-hax-use-case.js"; -import "./lib/v2/app-hax-use-case.js"; +import "./lib/v2/app-hax-use-case-filter.js"; const logoutBtn = new URL("./lib/assets/images/Logout.svg", import.meta.url) .href; @@ -718,7 +718,7 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} // eslint-disable-next-line class-methods-use-this login() { - import("./lib/2/app-hax-site-login.js").then(() => { + import("./lib/v2/app-hax-site-login.js").then(() => { const p = globalThis.document.createElement("app-hax-site-login"); if (this.querySelector('[slot="externalproviders"]')) { const cloneSlot = this.querySelector( @@ -1334,8 +1334,9 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} source="https://i.kym-cdn.com/photos/images/original/002/717/773/6d7.jpeg" > + - `; + `; } // eslint-disable-next-line class-methods-use-this diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index 38b7d001ce..5da3d95acb 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -2,7 +2,7 @@ import { LitElement, html, css } from "lit"; import "@haxtheweb/simple-tooltip/simple-tooltip.js"; import { store } from "./AppHaxStore.js"; -import "/lib/v2/app-hax-use-case.js"; +import "./app-hax-use-case.js"; export class AppHaxUseCaseFilter extends LitElement { // a convention I enjoy so you can change the tag name in 1 place @@ -15,22 +15,15 @@ export class AppHaxUseCaseFilter extends LitElement { this.searchTerm = ""; this.disabled = false; this.showSearch = false; - this.searchQuery = ""; - - this.activeFilters = []; - this.filters = []; - + this.items = []; - this.useCaseTitle = ""; - this.useCaseImage = ""; - this.useCaseDescription = ""; - this.useCaseIcon = []; - this.useCaseTag = ""; - this.filteredItems = []; + this.activeFilters = []; + this.filters = []; + this.searchQuery = ""; + this.demoLink = ""; this.errorMessage = ""; this.loading = false; - this.demoLink = ""; } // Site.json is coming from @@ -40,15 +33,15 @@ export class AppHaxUseCaseFilter extends LitElement { searchTerm: { type: String }, showSearch: { type: Boolean, reflect: true, attribute: "show-search" }, disabled: { type: Boolean, reflect: true }, - searchQuery: { type: String }, - activeFilters: { type: Array }, - filters: { type: Array }, items: { type: Array }, filteredItems: { type: Array }, + activeFilters: { type: Array }, + filters: { type: Array }, + searchQuery: { type: String }, + demoLink: { type: String}, errorMessage: { type: String }, - loading: { type: Boolean }, - demoLink: { type: String} + loading: { type: Boolean } }; } @@ -57,6 +50,7 @@ export class AppHaxUseCaseFilter extends LitElement { css` :host { overflow: hidden; + display: block !important; } input { visibility: none; @@ -75,6 +69,7 @@ export class AppHaxUseCaseFilter extends LitElement { max-width: 25vw; } .filter { + visibility: visible; display:flex; background-color: white; flex-direction: column; @@ -113,12 +108,12 @@ export class AppHaxUseCaseFilter extends LitElement { ) { this.applyFilters(); } - }S + } render() { return html`
- Toggle Search + Course
+
${this.filteredItems.length > 0 ? this.filteredItems.map( @@ -181,100 +178,102 @@ export class AppHaxUseCaseFilter extends LitElement { } } - applyFilters() { - const lowerCaseQuery = this.searchQuery.toLowerCase(); + handleSearch(event) { + this.searchQuery = event.target.value.toLowerCase(); + } + + toggleFilter(filter) { + if (this.activeFilters.includes(filter)) { + this.activeFilters = this.activeFilters.filter((f) => f !== filter); + } else { + this.activeFilters = [...this.activeFilters, filter]; + } + } + + applyFilters() { + const lowerCaseQuery = this.searchQuery.toLowerCase(); - this.filteredItems = this.items.filter((item) => { - const matchesSearch = item.useCaseTitle.toLowerCase().includes(lowerCaseQuery); + this.filteredItems = this.items.filter((item) => { + const matchesSearch = item.useCaseTitle.toLowerCase().includes(lowerCaseQuery); - const matchesFilters = - this.activeFilters.length === 0 || // No filters means match all - this.activeFilters.some((filter) => item.useCaseTag.includes(filter)); + const matchesFilters = + this.activeFilters.length === 0 || // No filters means match all + this.activeFilters.some((filter) => item.useCaseTag.includes(filter)); - return matchesSearch && matchesFilters; - }); - } + return matchesSearch && matchesFilters; + }); + } - handleSearch(event) { - this.searchQuery = event.target.value.toLowerCase(); - } - toggleFilter(filter) { - if (this.activeFilters.includes(filter)) { - this.activeFilters = this.activeFilters.filter((f) => f !== filter); - } else { - this.activeFilters = [...this.activeFilters, filter]; - } - } - resetFilters() { - this.searchQuery = ""; - this.activeFilters = []; // Clear active filters - this.filteredItems = this.items; // Reset to show all items - this.requestUpdate(); // Trigger an update + resetFilters() { + this.searchQuery = ""; + this.activeFilters = []; // Clear active filters + this.filteredItems = this.items; // Reset to show all items + this.requestUpdate(); // Trigger an update - // Uncheck checkboxes - const checkboxes = this.shadowRoot.querySelectorAll( - '.filterButtons input[type="checkbox"]' - ); - checkboxes.forEach((checkbox) => (checkbox.checked = false)); + // Uncheck checkboxes + const checkboxes = this.shadowRoot.querySelectorAll( + '.filterButtons input[type="checkbox"]' + ); + checkboxes.forEach((checkbox) => (checkbox.checked = false)); - // Clear search bar - const searchInput = this.shadowRoot.querySelector('#searchField input[type="text"]'); - if (searchInput) { - searchInput.value = ""; - } + // Clear search bar + const searchInput = this.shadowRoot.querySelector('#searchField input[type="text"]'); + if (searchInput) { + searchInput.value = ""; } + } - updateResults() { - this.loading = true; - this.errorMessage = ""; // Reset error before fetching + updateResults() { + this.loading = true; + this.errorMessage = ""; // Reset error before fetching - fetch(new URL('./lib/v2/app-hax-receipes.json', import.meta.url).href) - .then(response => { - if (!response.ok) { - throw new Error('Network response was not ok'); - } - return response.json(); // Parse JSON data - }) - .then(data => { - // Map JSON data to component's items + fetch(new URL('./lib/v2/app-hax-receipes.json', import.meta.url).href) + .then(response => { + if (!response.ok) { + throw new Error('Network response was not ok'); + } + return response.json(); // Parse JSON data + }) + .then(data => { + // Map JSON data to component's items - if (Array.isArray(data.item)) { - this.items = data.item.map(item => ({ - useCaseTitle: item.title, - useCaseImage: item.image, - useCaseDescription: item.description, - useCaseIcon: item.useCaseAttributes.map(attribute => ({ - icon: attribute.icon, - tooltip: attribute.tooltip - })), - useCaseTag: item.template-tag - })); - this.filteredItems = this.items; - this.filters = []; + if (Array.isArray(data.item)) { + this.items = data.item.map(item => ({ + useCaseTitle: item.title, + useCaseImage: item.image, + useCaseDescription: item.description, + useCaseIcon: item.attributes.map(attributes => ({ + icon: attributes.icon, + tooltip: attributes.tooltip + })), + useCaseTag: item[template-tag] + })); + this.filteredItems = this.items; + this.filters = []; - data.item.forEach(item => { - if (Array.isArray(item.tag)) { - item.tag.forEach(tag => { - if (!this.filters.includes(tag)) { - this.filters = [...this.filters, tag]; - } - }); + data.item.forEach(item => { + if (Array.isArray(item[template-tag])) { + item.template-tag.forEach(tag => { + if (!this.filters.includes([template-tag])) { + this.filters = [...this.filters, [template-tag]]; } }); - } else { - this.errorMessage = 'No Templates Found'; } - }) - .catch(error => { - this.errorMessage = `Failed to load data: ${error.message}`; - this.items = []; - this.filteredItems = []; - }) - .finally(() => { - this.loading = false; }); + } else { + this.errorMessage = 'No Templates Found'; } + }) + .catch(error => { + this.errorMessage = `Failed to load data: ${error.message}`; + this.items = []; + this.filteredItems = []; + }) + .finally(() => { + this.loading = false; + }); + } } -customElements.define(AppHaxUseCaseFilter.tag, AppHaxUseCaseFilter); +customElements.define("app-hax-use-case-filter", AppHaxUseCaseFilter); diff --git a/elements/app-hax/src/app-hax.js b/elements/app-hax/src/app-hax.js index a6852be7ec..fb0cfcd285 100644 --- a/elements/app-hax/src/app-hax.js +++ b/elements/app-hax/src/app-hax.js @@ -15,7 +15,7 @@ import "./lib/v2/app-hax-label.js"; import "./lib/v2/app-hax-top-bar.js"; import { SimpleTourFinder } from "@haxtheweb/simple-popover/lib/SimpleTourFinder.js"; import "./lib/v2/app-hax-use-case.js"; -import "./lib/v2/app-hax-use-case.js"; +import "./lib/v2/app-hax-use-case-filter.js"; const logoutBtn = new URL("./lib/assets/images/Logout.svg", import.meta.url) .href; @@ -718,7 +718,7 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} // eslint-disable-next-line class-methods-use-this login() { - import("./lib/2/app-hax-site-login.js").then(() => { + import("./lib/v2/app-hax-site-login.js").then(() => { const p = globalThis.document.createElement("app-hax-site-login"); if (this.querySelector('[slot="externalproviders"]')) { const cloneSlot = this.querySelector( @@ -1334,8 +1334,9 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} source="https://i.kym-cdn.com/photos/images/original/002/717/773/6d7.jpeg" > +
- `; + `; } // eslint-disable-next-line class-methods-use-this From 1a08d1a91b1f02b95ef8109b881a063568a2f72c Mon Sep 17 00:00:00 2001 From: izzabizz5 Date: Thu, 20 Feb 2025 12:04:22 -0500 Subject: [PATCH 011/166] add json data --- elements/app-hax/app-hax.js | 8 +- elements/app-hax/lib/v2/app-hax-receipes.json | 222 +++--------------- .../app-hax/lib/v2/app-hax-use-case-filter.js | 4 +- elements/app-hax/lib/v2/app-hax-use-case.js | 30 +-- elements/app-hax/src/app-hax.js | 8 +- 5 files changed, 50 insertions(+), 222 deletions(-) diff --git a/elements/app-hax/app-hax.js b/elements/app-hax/app-hax.js index fb0cfcd285..1e2a46a82a 100644 --- a/elements/app-hax/app-hax.js +++ b/elements/app-hax/app-hax.js @@ -1328,10 +1328,10 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} templateHome() { return html`
diff --git a/elements/app-hax/lib/v2/app-hax-receipes.json b/elements/app-hax/lib/v2/app-hax-receipes.json index 4199c0aad9..8820556ced 100644 --- a/elements/app-hax/lib/v2/app-hax-receipes.json +++ b/elements/app-hax/lib/v2/app-hax-receipes.json @@ -4,221 +4,61 @@ { "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350", "title": "Portfolio", + "category": "portfolio", "recipe": "recipes/portfolio/portfolio.recipe", "theme": { "element": "clean-portfolio", "path": "@haxtheweb/clean-portfolio/clean-portfolio.js" }, "author": "haxtheweb", - "image": "@haxtheweb/clean-portfolio/assets/screenshot.jpg", + "image": "webcomponents/elements/app-hax/lib/clean-one.jpg", "description": "Art gallery, blog posts, any collection of work and self presentation", - "icon": "hax:theme", + "icon": "hax:hax2022", "demo-url": "https://playground.hax.cloud/site.html?recipe=", "attributes": [ - { "icon": "value", "tooltip": "value"}, - { "icon": "value", "tooltip": "value"}, - { "icon": "value", "tooltip": "value"} - ] - }, - { - "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350", - "theme-tag": "bootstrap-theme", - "path-to-theme": "", - "template-tag": "collection", - "title": "value", - "author": "value", - "image": "value", - "description": "value", - "alt": "value", - "license": "value", - "icon": "value", - "demo-url": "value", - "site-url": "value", - "attributes": [ - { "icon": "value", "tooltip": "value"}, - { "icon": "value", "tooltip": "value"}, - { "icon": "value", "tooltip": "value"} - ] - }, - { - "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350", - "theme-tag": "haxor-slevin", - "path-to-theme": "", - "template-tag": "blog", - "title": "Haxor Slevin", - "author": "btopro", - "image": "value", - "description": "Haxor Slevin offers a clean layout optimized for showcasing code snippets, technical articles, and developer-focused content.", - "alt": "Screenshot of the Haxor Slevin theme showing blog layout", - "license": "Apache-2.0", - "icon": "value", - "demo-url": "value", - "site-url": "value", - "attributes": [ - { "icon": "value", "tooltip": "value"}, + { "icon": "icons:favorite", "tooltip": "Mark as Favorite" }, { "icon": "value", "tooltip": "value"}, { "icon": "value", "tooltip": "value"} ] }, { "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350", - "theme-tag": "clean-one", - "path-to-theme": "", - "template-tag": "course", - "title": "Clean One for Courses", - "author": "value", - "image": "value", - "description": "Clean One Course features a clean layout optimized for easy navigation and content consumption, making it ideal for course creators and educational institutions.", - "alt": "Screenshot of Clean One Course theme showing course layout", - "license": "value", - "icon": "value", - "demo-url": "value", - "site-url": "value", - "attributes": [ - { "icon": "value", "tooltip": "value"}, - { "icon": "value", "tooltip": "value"}, - { "icon": "value", "tooltip": "value"} - ] - }, - { - "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350", - "theme-tag": "clean-two", - "path-to-theme": "", - "template-tag": "course", - "title": "value", - "author": "value", - "image": "value", - "description": "Clean Two Course features a clean layout optimized for easy navigation and content consumption, making it ideal for course creators and educational institutions.", - "alt": "Screenshot of Clean Two Course theme showing course layout", - "license": "value", - "icon": "value", - "demo-url": "value", - "site-url": "value", - "attributes": [ - { "icon": "value", "tooltip": "value"}, - { "icon": "value", "tooltip": "value"}, - { "icon": "value", "tooltip": "value"} - ] - }, - { - "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350", - "theme-tag": "learn-two-theme", - "path-to-theme": "", - "template-tag": "course", - "title": "Learn Two for Courses", - "author": "value", - "image": "value", - "description": "Learn Two Course features a clean layout optimized for easy navigation and content consumption, making it ideal for course creators and educational institutions.", - "alt": "Screenshot of Learn Two Course theme showing course layout", - "license": "value", - "icon": "value", - "demo-url": "value", - "site-url": "value", - "attributes": [ - { "icon": "value", "tooltip": "value"}, - { "icon": "value", "tooltip": "value"}, - { "icon": "value", "tooltip": "value"} - ] - }, - { - "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350", - "theme-tag": "polaris-flex-theme", - "path-to-theme": "", - "template-tag": "website", - "title": "Polaris Flex for Websites", - "author": "value", - "image": "value", - "description": "Highly customizable theme designed for creating modern, responsive websites.", - "alt": "Screenshot of Polaris Flex theme showing website layout", - "license": "value", - "icon": "value", - "demo-url": "value", - "site-url": "value", - "attributes": [ - { "icon": "value", "tooltip": "value"}, - { "icon": "value", "tooltip": "value"}, - { "icon": "value", "tooltip": "value"} - ] - }, - { - "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350", - "theme-tag": "polaris-flex-theme", - "path-to-theme": "", - "template-tag": "training", - "title": "Polaris Flex for Trainings", - "author": "value", - "image": "value", - "description": "Highly customizable theme designed for creating modern, responsive trainings.", - "alt": "Screenshot of Polaris Flex theme showing training layout", - "license": "value", - "icon": "value", - "demo-url": "value", - "site-url": "value", - "attributes": [ - { "icon": "value", "tooltip": "value"}, - { "icon": "value", "tooltip": "value"}, - { "icon": "value", "tooltip": "value"} - ] - }, - { - "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350", - "theme-tag": "clean-one", - "path-to-theme": "", - "template-tag": "import", - "title": "Clean One for Import", - "author": "value", - "image": "value", - "description": "Clean One Import features a clean layout optimized for easy navigation and content consumption.", - "alt": "Screenshot of Clean One Import theme showing default layout", - "license": "value", - "icon": "value", - "demo-url": "value", - "site-url": "value", - "attributes": [ - { "icon": "value", "tooltip": "value"}, - { "icon": "value", "tooltip": "value"}, - { "icon": "value", "tooltip": "value"} - ] - }, - { - "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350", - "theme-tag": "clean-two", - "path-to-theme": "", - "template-tag": "import", - "title": "Clean Two for Import", - "author": "value", - "image": "value", - "description": "Clean Two Import features a clean layout optimized for easy navigation and content consumption.", - "alt": "Screenshot of Clean Two Import theme showing default layout", - "license": "value", - "icon": "value", - "demo-url": "value", - "site-url": "value", + "title": "Course", + "category": "course", + "recipe": "recipes/course/course.recipe", + "theme": { + "element": "clean-course", + "path": "@haxtheweb/clean-course/clean-course.js" + }, + "author": "haxtheweb", + "image": "webcomponents/elements/app-hax/lib/clean-one.jpg", + "description": "Art gallery, blog posts, any collection of work and self presentation", + "icon": "hax:hax2022", + "demo-url": "https://playground.hax.cloud/site.html?recipe=", "attributes": [ - { "icon": "value", "tooltip": "value"}, + { "icon": "icons:favorite", "tooltip": "Mark as Favorite" }, { "icon": "value", "tooltip": "value"}, { "icon": "value", "tooltip": "value"} ] }, { "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350", - "theme-tag": "learn-two-theme", - "path-to-theme": "", - "template-tag": "import", - "title": "Learn Two for Imports", - "author": "value", - "image": "value", - "description": "Learn Two Import features a clean layout optimized for easy navigation and content consumption.", - "alt": "Screenshot of Learn Two Import theme showing default layout", - "license": "value", - "icon": "value", - "demo-url": "value", - "site-url": "value", + "title": "Blog", + "category": "blog", + "recipe": "recipes/blog/blog.recipe", + "theme": { + "element": "clean-blog", + "path": "@haxtheweb/clean-blog/clean-blog.js" + }, + "author": "haxtheweb", + "image": "webcomponents/elements/app-hax/lib/clean-one.jpg", + "description": "Art gallery, blog posts, any collection of work and self presentation", + "icon": "hax:hax2022", + "demo-url": "https://playground.hax.cloud/site.html?recipe=", "attributes": [ - { "icon": "value", "tooltip": "value"}, + { "icon": "icons:favorite", "tooltip": "Mark as Favorite" }, { "icon": "value", "tooltip": "value"}, { "icon": "value", "tooltip": "value"} ] - } - ] + }] } \ No newline at end of file diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index 5da3d95acb..6a194c3748 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -14,8 +14,7 @@ export class AppHaxUseCaseFilter extends LitElement { super(); this.searchTerm = ""; this.disabled = false; - this.showSearch = false; - + this.showSearch = false; this.items = []; this.filteredItems = []; this.activeFilters = []; @@ -33,7 +32,6 @@ export class AppHaxUseCaseFilter extends LitElement { searchTerm: { type: String }, showSearch: { type: Boolean, reflect: true, attribute: "show-search" }, disabled: { type: Boolean, reflect: true }, - items: { type: Array }, filteredItems: { type: Array }, activeFilters: { type: Array }, diff --git a/elements/app-hax/lib/v2/app-hax-use-case.js b/elements/app-hax/lib/v2/app-hax-use-case.js index 08bc120c90..9d856b6bc7 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case.js +++ b/elements/app-hax/lib/v2/app-hax-use-case.js @@ -20,8 +20,6 @@ export class AppHaxUseCase extends LitElement { static get properties() { return { - id: { type: String }, - tag: { type: String }, title: { type: String }, description: { type: String }, source: { type: String }, @@ -97,31 +95,23 @@ export class AppHaxUseCase extends LitElement { return html`
- + ${this.title}

${this.title}

${this.description}

-
- ${this.iconImage.map( - (icon) => html` - - ` - )} -
+ ${this.iconImage.map( + (icon) => html` + + ` + )}
-

Demo>

-
-
diff --git a/elements/app-hax/src/app-hax.js b/elements/app-hax/src/app-hax.js index fb0cfcd285..1e2a46a82a 100644 --- a/elements/app-hax/src/app-hax.js +++ b/elements/app-hax/src/app-hax.js @@ -1328,10 +1328,10 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} templateHome() { return html`
From fcf8366692d3213b08f160283ea91f5c3a2baefd Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Thu, 20 Feb 2025 12:05:48 -0500 Subject: [PATCH 012/166] changes --- elements/app-hax/lib/v2/app-hax-use-case-filter.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index 5da3d95acb..0b45ee8866 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -248,16 +248,16 @@ export class AppHaxUseCaseFilter extends LitElement { icon: attributes.icon, tooltip: attributes.tooltip })), - useCaseTag: item[template-tag] + useCaseTag: item.category })); this.filteredItems = this.items; this.filters = []; data.item.forEach(item => { - if (Array.isArray(item[template-tag])) { - item.template-tag.forEach(tag => { - if (!this.filters.includes([template-tag])) { - this.filters = [...this.filters, [template-tag]]; + if (Array.isArray(item.category)) { + item.category.forEach(tag => { + if (!this.filters.includes(category)) { + this.filters = [...this.filters, category]; } }); } From b814a407d1047fc87daf1efb2af33076053a974e Mon Sep 17 00:00:00 2001 From: izzabizz5 Date: Thu, 20 Feb 2025 12:28:36 -0500 Subject: [PATCH 013/166] update json category names --- elements/app-hax/lib/v2/app-hax-receipes.json | 6 +++--- elements/app-hax/lib/v2/app-hax-use-case-filter.js | 13 +++++++------ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/elements/app-hax/lib/v2/app-hax-receipes.json b/elements/app-hax/lib/v2/app-hax-receipes.json index 8820556ced..b1b0619c48 100644 --- a/elements/app-hax/lib/v2/app-hax-receipes.json +++ b/elements/app-hax/lib/v2/app-hax-receipes.json @@ -4,7 +4,7 @@ { "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350", "title": "Portfolio", - "category": "portfolio", + "category": "Portfolio", "recipe": "recipes/portfolio/portfolio.recipe", "theme": { "element": "clean-portfolio", @@ -24,7 +24,7 @@ { "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350", "title": "Course", - "category": "course", + "category": "Course", "recipe": "recipes/course/course.recipe", "theme": { "element": "clean-course", @@ -44,7 +44,7 @@ { "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350", "title": "Blog", - "category": "blog", + "category": "Blog", "recipe": "recipes/blog/blog.recipe", "theme": { "element": "clean-blog", diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index 6a194c3748..24146aeae7 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -148,7 +148,8 @@ export class AppHaxUseCaseFilter extends LitElement { ? this.filteredItems.map( (item, index) => html`
- + > { - if (Array.isArray(item[template-tag])) { - item.template-tag.forEach(tag => { - if (!this.filters.includes([template-tag])) { - this.filters = [...this.filters, [template-tag]]; + if (Array.isArray(item[category])) { + item.category.forEach(tag => { + if (!this.filters.includes([category])) { + this.filters = [...this.filters, [category] } }); } From e3d2b8a15a6fd766495323471a679071e9cac58e Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Thu, 20 Feb 2025 12:59:20 -0500 Subject: [PATCH 014/166] updated filter section --- .../app-hax/lib/v2/app-hax-use-case-filter.js | 39 ++++++++++++------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index 2aef65a5c9..1394e4a2d6 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -14,11 +14,12 @@ export class AppHaxUseCaseFilter extends LitElement { super(); this.searchTerm = ""; this.disabled = false; - this.showSearch = false; + this.showSearch = false; + this.items = []; this.filteredItems = []; this.activeFilters = []; - this.filters = []; + this.filters = ['portfolio', 'blog', 'course', 'resume', 'research site']; this.searchQuery = ""; this.demoLink = ""; this.errorMessage = ""; @@ -32,6 +33,7 @@ export class AppHaxUseCaseFilter extends LitElement { searchTerm: { type: String }, showSearch: { type: Boolean, reflect: true, attribute: "show-search" }, disabled: { type: Boolean, reflect: true }, + items: { type: Array }, filteredItems: { type: Array }, activeFilters: { type: Array }, @@ -48,7 +50,7 @@ export class AppHaxUseCaseFilter extends LitElement { css` :host { overflow: hidden; - display: block !important; + } input { visibility: none; @@ -135,11 +137,14 @@ export class AppHaxUseCaseFilter extends LitElement { />
- - - - - + ${this.filters.map( + (filter) => html` + + ` + )}
@@ -153,7 +158,7 @@ export class AppHaxUseCaseFilter extends LitElement { .source=${item.useCaseImage || ""} .title=${item.useCaseTitle || ""} .description=${item.useCaseDescription || ""} - .demoLink=${item.demoLink || ""} + .demoLink=${item[demo-url] || ""} .iconImage=${item.useCaseIcon || []} > @@ -180,11 +185,13 @@ export class AppHaxUseCaseFilter extends LitElement { this.searchQuery = event.target.value.toLowerCase(); } - toggleFilter(filter) { - if (this.activeFilters.includes(filter)) { - this.activeFilters = this.activeFilters.filter((f) => f !== filter); + toggleFilter(event) { + const filterId = event.target.dataset.id; + + if (this.activeFilters.includes(filterId)) { + this.activeFilters = this.activeFilters.filter((f) => f !== filterId); } else { - this.activeFilters = [...this.activeFilters, filter]; + this.activeFilters = [...this.activeFilters, filterId]; } } @@ -197,7 +204,7 @@ export class AppHaxUseCaseFilter extends LitElement { const matchesFilters = this.activeFilters.length === 0 || // No filters means match all this.activeFilters.some((filter) => item.useCaseTag.includes(filter)); - + return matchesSearch && matchesFilters; }); } @@ -226,6 +233,7 @@ export class AppHaxUseCaseFilter extends LitElement { updateResults() { this.loading = true; this.errorMessage = ""; // Reset error before fetching + this.checkActiveFilters; fetch(new URL('./lib/v2/app-hax-receipes.json', import.meta.url).href) .then(response => { @@ -253,7 +261,7 @@ export class AppHaxUseCaseFilter extends LitElement { data.item.forEach(item => { if (Array.isArray(item.category)) { - item.category.forEach(tag => { + item.category.forEach(category => { if (!this.filters.includes(category)) { this.filters = [...this.filters, category]; } @@ -263,6 +271,7 @@ export class AppHaxUseCaseFilter extends LitElement { } else { this.errorMessage = 'No Templates Found'; } + console.log(data); }) .catch(error => { this.errorMessage = `Failed to load data: ${error.message}`; From 70a697acc808e7581d4bdc0f5d5a50576cade8fc Mon Sep 17 00:00:00 2001 From: izzabizz5 Date: Tue, 25 Feb 2025 10:51:44 -0500 Subject: [PATCH 015/166] fetching works --- ...hax-receipes.json => app-hax-recipes.json} | 10 +-- .../app-hax/lib/v2/app-hax-use-case-filter.js | 70 +++++++++++-------- 2 files changed, 47 insertions(+), 33 deletions(-) rename elements/app-hax/lib/v2/{app-hax-receipes.json => app-hax-recipes.json} (91%) diff --git a/elements/app-hax/lib/v2/app-hax-receipes.json b/elements/app-hax/lib/v2/app-hax-recipes.json similarity index 91% rename from elements/app-hax/lib/v2/app-hax-receipes.json rename to elements/app-hax/lib/v2/app-hax-recipes.json index b1b0619c48..e743ddc83d 100644 --- a/elements/app-hax/lib/v2/app-hax-receipes.json +++ b/elements/app-hax/lib/v2/app-hax-recipes.json @@ -4,7 +4,7 @@ { "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350", "title": "Portfolio", - "category": "Portfolio", + "category": ["Portfolio"], "recipe": "recipes/portfolio/portfolio.recipe", "theme": { "element": "clean-portfolio", @@ -22,9 +22,9 @@ ] }, { - "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350", + "uuid": "b12c82ef-1545-4697-9c76-90f1aa6f352c", "title": "Course", - "category": "Course", + "category": ["Course"], "recipe": "recipes/course/course.recipe", "theme": { "element": "clean-course", @@ -42,8 +42,8 @@ ] }, { - "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350", - "title": "Blog", + "uuid": "1b4132dd-c557-4576-89c7-f89446feda4a", + "title": ["Blog"], "category": "Blog", "recipe": "recipes/blog/blog.recipe", "theme": { diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index 24146aeae7..6ab1916925 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -26,7 +26,7 @@ export class AppHaxUseCaseFilter extends LitElement { } // Site.json is coming from - + static get properties() { return { searchTerm: { type: String }, @@ -98,16 +98,6 @@ export class AppHaxUseCaseFilter extends LitElement { this.searchTerm = this.shadowRoot.querySelector("#searchField").value; } - updated(changedProperties) { - if ( - changedProperties.has("searchQuery") || - changedProperties.has("activeFilters") || - changedProperties.has("item") - ) { - this.applyFilters(); - } - } - render() { return html`
@@ -133,13 +123,21 @@ export class AppHaxUseCaseFilter extends LitElement { type="text" placeholder="Search Template.." /> +
- - - - - + ${this.filters.map( + (filter) => html` + + ` + )}
@@ -149,7 +147,7 @@ export class AppHaxUseCaseFilter extends LitElement { (item, index) => html`
> + class="${index === this.activeUseCase ? "active-card" : ""}"> { const matchesSearch = item.useCaseTitle.toLowerCase().includes(lowerCaseQuery); - const matchesFilters = - this.activeFilters.length === 0 || // No filters means match all - this.activeFilters.some((filter) => item.useCaseTag.includes(filter)); + const matchesFilters = this.activeFilters.length === 0 || + this.activeFilters.some(filter => + item.useCaseTag.includes(filter)); return matchesSearch && matchesFilters; }); } - resetFilters() { this.searchQuery = ""; this.activeFilters = []; // Clear active filters @@ -218,7 +231,7 @@ export class AppHaxUseCaseFilter extends LitElement { checkboxes.forEach((checkbox) => (checkbox.checked = false)); // Clear search bar - const searchInput = this.shadowRoot.querySelector('#searchField input[type="text"]'); + const searchInput = this.shadowRoot.querySelector('#searchField'); if (searchInput) { searchInput.value = ""; } @@ -228,7 +241,7 @@ export class AppHaxUseCaseFilter extends LitElement { this.loading = true; this.errorMessage = ""; // Reset error before fetching - fetch(new URL('./lib/v2/app-hax-receipes.json', import.meta.url).href) + fetch(new URL('./app-hax-recipes.json', import.meta.url).href) .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); @@ -247,16 +260,17 @@ export class AppHaxUseCaseFilter extends LitElement { icon: attributes.icon, tooltip: attributes.tooltip })), - useCaseTag: item[category] + useCaseTag: Array.isArray(item.category) ? item.category : [item.category], + demoLink: item["demo-url"], })); this.filteredItems = this.items; this.filters = []; data.item.forEach(item => { - if (Array.isArray(item[category])) { - item.category.forEach(tag => { - if (!this.filters.includes([category])) { - this.filters = [...this.filters, [category] + if (Array.isArray(item.category)) { + item.category.forEach(category => { + if (!this.filters.includes(category)) { + this.filters = [...this.filters, category]; } }); } From 2637cfd8db0cab24935e53a35d0f63f4953aa1cf Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Tue, 25 Feb 2025 10:51:59 -0500 Subject: [PATCH 016/166] tues --- elements/app-hax/lib/v2/app-hax-use-case-filter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index 1394e4a2d6..036813f24e 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -246,7 +246,7 @@ export class AppHaxUseCaseFilter extends LitElement { // Map JSON data to component's items if (Array.isArray(data.item)) { - this.items = data.item.map(item => ({ + this.items = data.map(item => ({ useCaseTitle: item.title, useCaseImage: item.image, useCaseDescription: item.description, From 06bd644a7a1ca1e195266a272f027e4a71b7850f Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Tue, 25 Feb 2025 10:58:50 -0500 Subject: [PATCH 017/166] please just work --- elements/app-hax/lib/v2/app-hax-receipes.json | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 elements/app-hax/lib/v2/app-hax-receipes.json diff --git a/elements/app-hax/lib/v2/app-hax-receipes.json b/elements/app-hax/lib/v2/app-hax-receipes.json new file mode 100644 index 0000000000..8820556ced --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-receipes.json @@ -0,0 +1,64 @@ +{ + "status": 200, + "item": [ + { + "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350", + "title": "Portfolio", + "category": "portfolio", + "recipe": "recipes/portfolio/portfolio.recipe", + "theme": { + "element": "clean-portfolio", + "path": "@haxtheweb/clean-portfolio/clean-portfolio.js" + }, + "author": "haxtheweb", + "image": "webcomponents/elements/app-hax/lib/clean-one.jpg", + "description": "Art gallery, blog posts, any collection of work and self presentation", + "icon": "hax:hax2022", + "demo-url": "https://playground.hax.cloud/site.html?recipe=", + "attributes": [ + { "icon": "icons:favorite", "tooltip": "Mark as Favorite" }, + { "icon": "value", "tooltip": "value"}, + { "icon": "value", "tooltip": "value"} + ] + }, + { + "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350", + "title": "Course", + "category": "course", + "recipe": "recipes/course/course.recipe", + "theme": { + "element": "clean-course", + "path": "@haxtheweb/clean-course/clean-course.js" + }, + "author": "haxtheweb", + "image": "webcomponents/elements/app-hax/lib/clean-one.jpg", + "description": "Art gallery, blog posts, any collection of work and self presentation", + "icon": "hax:hax2022", + "demo-url": "https://playground.hax.cloud/site.html?recipe=", + "attributes": [ + { "icon": "icons:favorite", "tooltip": "Mark as Favorite" }, + { "icon": "value", "tooltip": "value"}, + { "icon": "value", "tooltip": "value"} + ] + }, + { + "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350", + "title": "Blog", + "category": "blog", + "recipe": "recipes/blog/blog.recipe", + "theme": { + "element": "clean-blog", + "path": "@haxtheweb/clean-blog/clean-blog.js" + }, + "author": "haxtheweb", + "image": "webcomponents/elements/app-hax/lib/clean-one.jpg", + "description": "Art gallery, blog posts, any collection of work and self presentation", + "icon": "hax:hax2022", + "demo-url": "https://playground.hax.cloud/site.html?recipe=", + "attributes": [ + { "icon": "icons:favorite", "tooltip": "Mark as Favorite" }, + { "icon": "value", "tooltip": "value"}, + { "icon": "value", "tooltip": "value"} + ] + }] +} \ No newline at end of file From 6e2c10a29c68839d58502688780d434af9b0a289 Mon Sep 17 00:00:00 2001 From: izzabizz5 Date: Tue, 25 Feb 2025 11:30:16 -0500 Subject: [PATCH 018/166] reset and filter functionality --- elements/app-hax/lib/v2/app-hax-recipes.json | 4 ++-- .../app-hax/lib/v2/app-hax-use-case-filter.js | 17 ++++++++--------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/elements/app-hax/lib/v2/app-hax-recipes.json b/elements/app-hax/lib/v2/app-hax-recipes.json index e743ddc83d..f824852e9a 100644 --- a/elements/app-hax/lib/v2/app-hax-recipes.json +++ b/elements/app-hax/lib/v2/app-hax-recipes.json @@ -43,8 +43,8 @@ }, { "uuid": "1b4132dd-c557-4576-89c7-f89446feda4a", - "title": ["Blog"], - "category": "Blog", + "title": "Blog", + "category": ["Blog"], "recipe": "recipes/blog/blog.recipe", "theme": { "element": "clean-blog", diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index 6ab1916925..9093395ce4 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -77,7 +77,7 @@ export class AppHaxUseCaseFilter extends LitElement { border-radius: var(--ddd-radius-xs); width: 300px; } - .filterButtons { + .filterButtons input[type="checkbox"] { text-align: start; display: flex; flex-direction: column; @@ -266,14 +266,12 @@ export class AppHaxUseCaseFilter extends LitElement { this.filteredItems = this.items; this.filters = []; - data.item.forEach(item => { - if (Array.isArray(item.category)) { - item.category.forEach(category => { - if (!this.filters.includes(category)) { - this.filters = [...this.filters, category]; - } - }); - } + this.items.forEach(item => { + item.useCaseTag.forEach(category => { + if (!this.filters.includes(category)) { + this.filters = [...this.filters, category]; + } + }); }); } else { this.errorMessage = 'No Templates Found'; @@ -286,6 +284,7 @@ export class AppHaxUseCaseFilter extends LitElement { }) .finally(() => { this.loading = false; + this.requestUpdate(); }); } } From 34cf7de155770e257a9530a2bede159d2f1f5482 Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Tue, 25 Feb 2025 11:47:38 -0500 Subject: [PATCH 019/166] updated style --- elements/app-hax/app-hax.js | 7 --- elements/app-hax/lib/v2/app-hax-recipes.json | 2 +- .../app-hax/lib/v2/app-hax-use-case-filter.js | 57 +++++++++---------- elements/app-hax/src/app-hax.js | 7 --- 4 files changed, 27 insertions(+), 46 deletions(-) diff --git a/elements/app-hax/app-hax.js b/elements/app-hax/app-hax.js index 1e2a46a82a..addde44474 100644 --- a/elements/app-hax/app-hax.js +++ b/elements/app-hax/app-hax.js @@ -1327,13 +1327,6 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} //EDIT HERE templateHome() { return html`
- -
`; diff --git a/elements/app-hax/lib/v2/app-hax-recipes.json b/elements/app-hax/lib/v2/app-hax-recipes.json index e743ddc83d..709e892d77 100644 --- a/elements/app-hax/lib/v2/app-hax-recipes.json +++ b/elements/app-hax/lib/v2/app-hax-recipes.json @@ -11,7 +11,7 @@ "path": "@haxtheweb/clean-portfolio/clean-portfolio.js" }, "author": "haxtheweb", - "image": "webcomponents/elements/app-hax/lib/clean-one.jpg", + "image": "./webcomponents/elements/app-hax/lib/assets/screenshots/clean-one.jpg", "description": "Art gallery, blog posts, any collection of work and self presentation", "icon": "hax:hax2022", "demo-url": "https://playground.hax.cloud/site.html?recipe=", diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index b7476781ac..cd9a264c70 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -15,7 +15,6 @@ export class AppHaxUseCaseFilter extends LitElement { this.searchTerm = ""; this.disabled = false; this.showSearch = false; - this.items = []; this.filteredItems = []; this.activeFilters = []; @@ -33,7 +32,6 @@ export class AppHaxUseCaseFilter extends LitElement { searchTerm: { type: String }, showSearch: { type: Boolean, reflect: true, attribute: "show-search" }, disabled: { type: Boolean, reflect: true }, - items: { type: Array }, filteredItems: { type: Array }, activeFilters: { type: Array }, @@ -50,23 +48,29 @@ export class AppHaxUseCaseFilter extends LitElement { css` :host { overflow: hidden; - + display: inline-flex; + } + .results { + display: flex; + } + .reset-button { + width: 50px; + height: 24px; + margin: 8px; } input { - visibility: none; - opacity: 0; - width: 0; + opacity: 1; + width: 200px; + max-width: 25vw; transition: all ease-in-out 0.3s; padding: 4px; font-family: "Press Start 2P", sans-serif; - font-size: 20px; + font-size: 12px; margin: 2px 0 0 16px; + height: 24px; } - :host([show-search]) input { - visibility: visible; - opacity: 1; - width: 250px; - max-width: 25vw; + .upper-filter { + display: flex; } .filter { visibility: visible; @@ -103,30 +107,22 @@ export class AppHaxUseCaseFilter extends LitElement { render() { return html`
- - Toggle Search +
- + +
+
${this.filters.map( (filter) => html` @@ -154,7 +150,7 @@ export class AppHaxUseCaseFilter extends LitElement { .source=${item.useCaseImage || ""} .title=${item.useCaseTitle || ""} .description=${item.useCaseDescription || ""} - .demoLink=${item[demo-url] || ""} + .demoLink=${item.demoLink || ""} .iconImage=${item.useCaseIcon || []} > @@ -244,7 +240,6 @@ export class AppHaxUseCaseFilter extends LitElement { updateResults() { this.loading = true; this.errorMessage = ""; // Reset error before fetching - this.checkActiveFilters; fetch(new URL('./app-hax-recipes.json', import.meta.url).href) .then(response => { @@ -257,7 +252,7 @@ export class AppHaxUseCaseFilter extends LitElement { // Map JSON data to component's items if (Array.isArray(data.item)) { - this.items = data.map(item => ({ + this.items = data.item.map(item => ({ useCaseTitle: item.title, useCaseImage: item.image, useCaseDescription: item.description, diff --git a/elements/app-hax/src/app-hax.js b/elements/app-hax/src/app-hax.js index 1e2a46a82a..addde44474 100644 --- a/elements/app-hax/src/app-hax.js +++ b/elements/app-hax/src/app-hax.js @@ -1327,13 +1327,6 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} //EDIT HERE templateHome() { return html`
- -
`; From e4a8d47275283243907ca2570ccebde34332e570 Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Tue, 25 Feb 2025 13:06:13 -0500 Subject: [PATCH 020/166] new style --- elements/app-hax/lib/v2/app-hax-recipes.json | 22 +++++------ .../app-hax/lib/v2/app-hax-use-case-filter.js | 38 ++++++++++++++----- elements/app-hax/lib/v2/app-hax-use-case.js | 2 +- 3 files changed, 41 insertions(+), 21 deletions(-) diff --git a/elements/app-hax/lib/v2/app-hax-recipes.json b/elements/app-hax/lib/v2/app-hax-recipes.json index 709e892d77..4395a05d12 100644 --- a/elements/app-hax/lib/v2/app-hax-recipes.json +++ b/elements/app-hax/lib/v2/app-hax-recipes.json @@ -11,14 +11,14 @@ "path": "@haxtheweb/clean-portfolio/clean-portfolio.js" }, "author": "haxtheweb", - "image": "./webcomponents/elements/app-hax/lib/assets/screenshots/clean-one.jpg", + "image": "/elements/app-hax/lib/assets/screenshots/clean-one.jpg", "description": "Art gallery, blog posts, any collection of work and self presentation", "icon": "hax:hax2022", "demo-url": "https://playground.hax.cloud/site.html?recipe=", "attributes": [ { "icon": "icons:favorite", "tooltip": "Mark as Favorite" }, - { "icon": "value", "tooltip": "value"}, - { "icon": "value", "tooltip": "value"} + { "icon": "icons:language", "tooltip": "Translatable"}, + { "icon": "icons:thumb-up", "tooltip": "Popular"} ] }, { @@ -31,34 +31,34 @@ "path": "@haxtheweb/clean-course/clean-course.js" }, "author": "haxtheweb", - "image": "webcomponents/elements/app-hax/lib/clean-one.jpg", + "image": "/elements/app-hax/lib/assets/screenshots/clean-one.jpg", "description": "Art gallery, blog posts, any collection of work and self presentation", "icon": "hax:hax2022", "demo-url": "https://playground.hax.cloud/site.html?recipe=", "attributes": [ { "icon": "icons:favorite", "tooltip": "Mark as Favorite" }, - { "icon": "value", "tooltip": "value"}, - { "icon": "value", "tooltip": "value"} + { "icon": "icons:language", "tooltip": "Translatable"}, + { "icon": "icons:thumb-up", "tooltip": "Popular"} ] }, { "uuid": "1b4132dd-c557-4576-89c7-f89446feda4a", - "title": ["Blog"], - "category": "Blog", + "title": "Blog", + "category": ["Blog"], "recipe": "recipes/blog/blog.recipe", "theme": { "element": "clean-blog", "path": "@haxtheweb/clean-blog/clean-blog.js" }, "author": "haxtheweb", - "image": "webcomponents/elements/app-hax/lib/clean-one.jpg", + "image": "/elements/app-hax/lib/assets/screenshots/clean-one.jpg", "description": "Art gallery, blog posts, any collection of work and self presentation", "icon": "hax:hax2022", "demo-url": "https://playground.hax.cloud/site.html?recipe=", "attributes": [ { "icon": "icons:favorite", "tooltip": "Mark as Favorite" }, - { "icon": "value", "tooltip": "value"}, - { "icon": "value", "tooltip": "value"} + { "icon": "icons:language", "tooltip": "Translatable"}, + { "icon": "icons:thumb-up", "tooltip": "Popular"} ] }] } \ No newline at end of file diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index cd9a264c70..6e46409f52 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -51,14 +51,16 @@ export class AppHaxUseCaseFilter extends LitElement { display: inline-flex; } .results { + flex-grow: 1; display: flex; + margin-left: 320px; } .reset-button { width: 50px; height: 24px; margin: 8px; } - input { + input [type="text"]{ opacity: 1; width: 200px; max-width: 25vw; @@ -73,22 +75,34 @@ export class AppHaxUseCaseFilter extends LitElement { display: flex; } .filter { - visibility: visible; + position: fixed; + top: 225px; + left: 20px; + height: 300px; + justify-self: flex-start; display:flex; background-color: white; flex-direction: column; margin: var(--ddd-spacing-2); padding: var(--ddd-spacing-4); background-color: var(--ddd-theme-default-white); + border: solid var(--ddd-theme-default-limestoneGray) 1px; border-radius: var(--ddd-radius-xs); width: 300px; } .filterButtons { - text-align: start; + text-align: left; + align-items: flex-start; + justify-self: flex-start; display: flex; flex-direction: column; gap: var(--ddd-spacing-2); - max-width: 150px; + width: 150px; + } + .filterButtons label { + display: flex; + align-items: center; + justify-content: flex-start; } `, ]; @@ -129,8 +143,9 @@ export class AppHaxUseCaseFilter extends LitElement { @@ -191,21 +206,25 @@ export class AppHaxUseCaseFilter extends LitElement { handleSearch(event) { this.searchQuery = event.target.value.toLowerCase(); + this.applyFilters(); } toggleFilter(event) { - const filterId = event.target.dataset.id; + const filterValue = event.target.value; - if (this.activeFilters.includes(filterId)) { - this.activeFilters = this.activeFilters.filter((f) => f !== filterId); + if (this.activeFilters.includes(filterValue)) { + this.activeFilters = this.activeFilters.filter((f) => f !== filterValue); } else { - this.activeFilters = [...this.activeFilters, filterId]; + this.activeFilters = [...this.activeFilters, filterValue]; } + this.applyFilters(); } applyFilters() { const lowerCaseQuery = this.searchQuery.toLowerCase(); + console.log("Active Filters:", this.activeFilters); + this.filteredItems = this.items.filter((item) => { const matchesSearch = item.useCaseTitle.toLowerCase().includes(lowerCaseQuery); @@ -215,6 +234,7 @@ export class AppHaxUseCaseFilter extends LitElement { return matchesSearch && matchesFilters; }); + this.requestUpdate(); } diff --git a/elements/app-hax/lib/v2/app-hax-use-case.js b/elements/app-hax/lib/v2/app-hax-use-case.js index 9d856b6bc7..c2a97a399c 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case.js +++ b/elements/app-hax/lib/v2/app-hax-use-case.js @@ -76,7 +76,7 @@ export class AppHaxUseCase extends LitElement { border-radius: var(--ddd-radius-xs); align-items: center; justify-content: center; - color: white; + } #haxIcons { position: absolute; From 69fb7fd8623835a96eb00a491b5436d88cccaccc Mon Sep 17 00:00:00 2001 From: izzabizz5 Date: Tue, 25 Feb 2025 13:07:26 -0500 Subject: [PATCH 021/166] background removed --- elements/app-hax/demo/home.html | 4 ++-- elements/app-hax/demo/index.html | 12 ++++++------ .../app-hax/lib/v2/app-hax-use-case-filter.js | 16 +++++++++------- elements/app-hax/test-use-cases/app-hax-copy.js | 15 --------------- 4 files changed, 17 insertions(+), 30 deletions(-) diff --git a/elements/app-hax/demo/home.html b/elements/app-hax/demo/home.html index 02cfff7f47..3989bada5a 100644 --- a/elements/app-hax/demo/home.html +++ b/elements/app-hax/demo/home.html @@ -28,10 +28,10 @@ margin: 0; padding: 0; overflow-x: hidden; - background-image: url('../assets/LMGridBox.svg'); + background-image: url('../assets/LMGridBox.svg'); background-repeat: repeat; background-position: center center; - background-size: auto, 20% auto, 20% auto; + background-size: auto, 20% auto, 20% auto; --app-hax-accent-color: black; --app-hax-background-color: white; --simple-tooltip-background: #000000; diff --git a/elements/app-hax/demo/index.html b/elements/app-hax/demo/index.html index aec0e88b34..8e3963509c 100644 --- a/elements/app-hax/demo/index.html +++ b/elements/app-hax/demo/index.html @@ -31,10 +31,10 @@ padding: 0; font-family: 'Press Start 2P', sans-serif; overflow-x: hidden; - background-image: url('../lib/assets/images/LMGridBox.svg'); + /*background-image: url('../lib/assets/images/LMGridBox.svg');*/ background-repeat: repeat; background-position: center center; - background-size: auto, 20% auto, 20% auto; + background-size: auto, 20% auto, 20% auto; --app-hax-accent-color: black; --app-hax-background-color: white; --simple-tooltip-background: #000000; @@ -51,17 +51,17 @@ } body.dark-mode { background-color: black; - background-image: url('../lib/assets/images/DMGridBox.svg'); + /*background-image: url('../lib/assets/images/DMGridBox.svg');*/ --app-hax-accent-color: white; --app-hax-background-color: black; } body.app-loaded:not(.bad-device) { - background-image: url('../lib/assets/images/LMGridBox.svg'), url('../lib/assets/images/DesignLightModeLeft.svg'), url('../lib/assets/images/DesignLightModeRight.svg'); + /*background-image: url('../lib/assets/images/LMGridBox.svg'), url('../lib/assets/images/DesignLightModeLeft.svg'), url('../lib/assets/images/DesignLightModeRight.svg');*/ background-repeat: repeat, repeat-y, repeat-y; background-position: center center, top left, top right; background-size: auto, 20% auto, 20% auto; background-attachment: fixed, fixed, fixed; - } + } div[slot="externalproviders"] { display: none; } @@ -69,7 +69,7 @@ display: unset; } body.app-loaded.dark-mode { - background-image: url('../lib/assets/images/DMGridBox.svg'), url('../lib/assets/images/DesignDarkModeLeft.svg'), url('../lib/assets/images/DesignDarkModeRight.svg'); + /*background-image: url('../lib/assets/images/DMGridBox.svg'), url('../lib/assets/images/DesignDarkModeLeft.svg'), url('../lib/assets/images/DesignDarkModeRight.svg');*/ } #loading { diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index 6f9dc9b0f5..32660b7fa7 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -83,7 +83,7 @@ export class AppHaxUseCaseFilter extends LitElement { border-radius: var(--ddd-radius-xs); width: 300px; } - .filterButtons input[type="checkbox"] { + .filterButtons { text-align: start; display: flex; flex-direction: column; @@ -266,12 +266,14 @@ export class AppHaxUseCaseFilter extends LitElement { this.filteredItems = this.items; this.filters = []; - this.items.forEach(item => { - item.useCaseTag.forEach(category => { - if (!this.filters.includes(category)) { - this.filters = [...this.filters, category]; - } - }); + data.item.forEach(item => { + if (Array.isArray(item.category)) { + item.category.forEach(category => { + if (!this.filters.includes(category)) { + this.filters = [...this.filters, category]; + } + }); + } }); } else { this.errorMessage = 'No Templates Found'; diff --git a/elements/app-hax/test-use-cases/app-hax-copy.js b/elements/app-hax/test-use-cases/app-hax-copy.js index 69b87eb192..5b45815f73 100644 --- a/elements/app-hax/test-use-cases/app-hax-copy.js +++ b/elements/app-hax/test-use-cases/app-hax-copy.js @@ -1263,7 +1263,6 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight}
-
${this.activeItem && !this.siteReady @@ -1295,7 +1294,6 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} @click="${this.getNewWord}" >
${this.appBody(this.appMode)}
-
`; } @@ -1347,19 +1345,6 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} >`; } - siteReadyToGo(e) { - import("@haxtheweb/multiple-choice/lib/confetti-container.js").then( - (module) => { - setTimeout(() => { - this.shadowRoot.querySelector("#confetti").setAttribute("popped", ""); - }, 0); - }, - ); - if (e.detail) { - store.siteReady = true; - } - } - template404() { return html`
Date: Thu, 27 Feb 2025 10:22:51 -0500 Subject: [PATCH 022/166] design stuff --- elements/app-hax/lib/v2/app-hax-use-case-filter.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index 6e46409f52..fc9cfb43cf 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -69,7 +69,7 @@ export class AppHaxUseCaseFilter extends LitElement { font-family: "Press Start 2P", sans-serif; font-size: 12px; margin: 2px 0 0 16px; - height: 24px; + } .upper-filter { display: flex; @@ -103,6 +103,10 @@ export class AppHaxUseCaseFilter extends LitElement { display: flex; align-items: center; justify-content: flex-start; + padding: 8px; + } + input[type="checkbox"] { + width: 30px; } `, ]; From 35b5753df48bd866fe98abbf2bdbfe1d3a62c1d5 Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Thu, 27 Feb 2025 10:36:27 -0500 Subject: [PATCH 023/166] fixed alignment --- elements/app-hax/lib/v2/app-hax-use-case-filter.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index fc9cfb43cf..375a814a34 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -48,12 +48,14 @@ export class AppHaxUseCaseFilter extends LitElement { css` :host { overflow: hidden; - display: inline-flex; + display: block; + width: 100%; } .results { - flex-grow: 1; display: flex; - margin-left: 320px; + margin-left: 360px; + justify-content: flex-start; + align-items: flex-start; } .reset-button { width: 50px; @@ -69,7 +71,6 @@ export class AppHaxUseCaseFilter extends LitElement { font-family: "Press Start 2P", sans-serif; font-size: 12px; margin: 2px 0 0 16px; - } .upper-filter { display: flex; From 4627f0ba37073efd31d2702139b97c63de3c4393 Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Thu, 27 Feb 2025 11:08:02 -0500 Subject: [PATCH 024/166] bleh --- .../app-hax/lib/v2/app-hax-use-case-filter.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index 375a814a34..3617399496 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -64,7 +64,7 @@ export class AppHaxUseCaseFilter extends LitElement { } input [type="text"]{ opacity: 1; - width: 200px; + width: 216px; max-width: 25vw; transition: all ease-in-out 0.3s; padding: 4px; @@ -211,6 +211,16 @@ export class AppHaxUseCaseFilter extends LitElement { handleSearch(event) { this.searchQuery = event.target.value.toLowerCase(); + + const matchingFilter = this.filters.find(filter => + filter.toLowerCase() === this.searchQuery + ); + + const checkbox = this.shadowRoot.querySelector(`input[value="${matchingFilter}"]`); + if (checkbox) { + checkbox.checked = true; + } + this.applyFilters(); } @@ -231,7 +241,9 @@ export class AppHaxUseCaseFilter extends LitElement { console.log("Active Filters:", this.activeFilters); this.filteredItems = this.items.filter((item) => { - const matchesSearch = item.useCaseTitle.toLowerCase().includes(lowerCaseQuery); + const matchesSearch = lowerCaseQuery === "" || + item.useCaseTitle.toLowerCase().includes(lowerCaseQuery) || + item.useCaseTag.some(tag => tag.toLowerCase() === lowerCaseQuery); const matchesFilters = this.activeFilters.length === 0 || this.activeFilters.some(filter => From 7fbd20d5d49c75498bcb4757a63c402cf2a67575 Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Thu, 27 Feb 2025 11:10:14 -0500 Subject: [PATCH 025/166] Add files via upload --- .../lib/assets/images/LMBackgroundImage.svg | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 elements/app-hax/lib/assets/images/LMBackgroundImage.svg diff --git a/elements/app-hax/lib/assets/images/LMBackgroundImage.svg b/elements/app-hax/lib/assets/images/LMBackgroundImage.svg new file mode 100644 index 0000000000..666303f396 --- /dev/null +++ b/elements/app-hax/lib/assets/images/LMBackgroundImage.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + From 4ce67d94e867177c4ad50e020e531afcacbffd69 Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Thu, 27 Feb 2025 11:25:49 -0500 Subject: [PATCH 026/166] blehhhh --- .../lib/assets/images/LMBackgroundImage.svg | 20 ------------------- 1 file changed, 20 deletions(-) delete mode 100644 elements/app-hax/lib/assets/images/LMBackgroundImage.svg diff --git a/elements/app-hax/lib/assets/images/LMBackgroundImage.svg b/elements/app-hax/lib/assets/images/LMBackgroundImage.svg deleted file mode 100644 index 666303f396..0000000000 --- a/elements/app-hax/lib/assets/images/LMBackgroundImage.svg +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - From 7b8a30b70627f353f85461558eec5f8384a76f23 Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Thu, 27 Feb 2025 11:47:05 -0500 Subject: [PATCH 027/166] Add files via upload --- .../lib/assets/images/LMBackgroundImage.svg | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 elements/app-hax/lib/assets/images/LMBackgroundImage.svg diff --git a/elements/app-hax/lib/assets/images/LMBackgroundImage.svg b/elements/app-hax/lib/assets/images/LMBackgroundImage.svg new file mode 100644 index 0000000000..c7b3235a30 --- /dev/null +++ b/elements/app-hax/lib/assets/images/LMBackgroundImage.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 3331daed13741e2282c26f0af44f52c95c0e4f9e Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Thu, 27 Feb 2025 11:47:27 -0500 Subject: [PATCH 028/166] mmmemememe --- elements/app-hax/app-hax.js | 6 +++++- elements/app-hax/src/app-hax.js | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/elements/app-hax/app-hax.js b/elements/app-hax/app-hax.js index addde44474..f8e497a0eb 100644 --- a/elements/app-hax/app-hax.js +++ b/elements/app-hax/app-hax.js @@ -16,6 +16,7 @@ import "./lib/v2/app-hax-top-bar.js"; import { SimpleTourFinder } from "@haxtheweb/simple-popover/lib/SimpleTourFinder.js"; import "./lib/v2/app-hax-use-case.js"; import "./lib/v2/app-hax-use-case-filter.js"; +import "./lib/v2/app-hax-search-results.js"; const logoutBtn = new URL("./lib/assets/images/Logout.svg", import.meta.url) .href; @@ -1326,7 +1327,10 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} //EDIT HERE templateHome() { - return html`
+ return html` + +
+
`; diff --git a/elements/app-hax/src/app-hax.js b/elements/app-hax/src/app-hax.js index addde44474..f8e497a0eb 100644 --- a/elements/app-hax/src/app-hax.js +++ b/elements/app-hax/src/app-hax.js @@ -16,6 +16,7 @@ import "./lib/v2/app-hax-top-bar.js"; import { SimpleTourFinder } from "@haxtheweb/simple-popover/lib/SimpleTourFinder.js"; import "./lib/v2/app-hax-use-case.js"; import "./lib/v2/app-hax-use-case-filter.js"; +import "./lib/v2/app-hax-search-results.js"; const logoutBtn = new URL("./lib/assets/images/Logout.svg", import.meta.url) .href; @@ -1326,7 +1327,10 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} //EDIT HERE templateHome() { - return html`
+ return html` + +
+
`; From 505d3085b3823a946deadc1da4c6058584da5cc5 Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Thu, 27 Feb 2025 12:03:49 -0500 Subject: [PATCH 029/166] changed LM background --- elements/app-hax/demo/index.html | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/elements/app-hax/demo/index.html b/elements/app-hax/demo/index.html index aec0e88b34..02751d9966 100644 --- a/elements/app-hax/demo/index.html +++ b/elements/app-hax/demo/index.html @@ -31,7 +31,7 @@ padding: 0; font-family: 'Press Start 2P', sans-serif; overflow-x: hidden; - background-image: url('../lib/assets/images/LMGridBox.svg'); + background-image: url('../lib/assets/images/LMBackgroundImage.svg'); background-repeat: repeat; background-position: center center; background-size: auto, 20% auto, 20% auto; @@ -56,11 +56,10 @@ --app-hax-background-color: black; } body.app-loaded:not(.bad-device) { - background-image: url('../lib/assets/images/LMGridBox.svg'), url('../lib/assets/images/DesignLightModeLeft.svg'), url('../lib/assets/images/DesignLightModeRight.svg'); - background-repeat: repeat, repeat-y, repeat-y; - background-position: center center, top left, top right; + background-image: url('../lib/assets/images/LMBackgroundImage.svg'), url('../lib/assets/images/DesignLightModeLeft.svg'), url('../lib/assets/images/DesignLightModeRight.svg'); + background-position: top; background-size: auto, 20% auto, 20% auto; - background-attachment: fixed, fixed, fixed; + } div[slot="externalproviders"] { display: none; From 5d4fbf7fff99bde2c612d1afe1ec4cff0b88d6f3 Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Thu, 27 Feb 2025 12:04:41 -0500 Subject: [PATCH 030/166] Add files via upload --- .../lib/assets/images/DMBackgroundImage.svg | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 elements/app-hax/lib/assets/images/DMBackgroundImage.svg diff --git a/elements/app-hax/lib/assets/images/DMBackgroundImage.svg b/elements/app-hax/lib/assets/images/DMBackgroundImage.svg new file mode 100644 index 0000000000..d71bfb600e --- /dev/null +++ b/elements/app-hax/lib/assets/images/DMBackgroundImage.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 3a95e5236b60b88e96eaff5cc4ae9af0f13b2488 Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Thu, 27 Feb 2025 13:13:35 -0500 Subject: [PATCH 031/166] major styling changes --- elements/app-hax/app-hax.js | 2 - elements/app-hax/demo/index.html | 4 +- .../app-hax/lib/v2/app-hax-search-results.js | 4 +- elements/app-hax/lib/v2/app-hax-site-bar.js | 57 ++++++++++++------- .../app-hax/lib/v2/app-hax-use-case-filter.js | 23 +++++++- elements/app-hax/src/app-hax.js | 2 - 6 files changed, 65 insertions(+), 27 deletions(-) diff --git a/elements/app-hax/app-hax.js b/elements/app-hax/app-hax.js index f8e497a0eb..039d110211 100644 --- a/elements/app-hax/app-hax.js +++ b/elements/app-hax/app-hax.js @@ -1328,9 +1328,7 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} //EDIT HERE templateHome() { return html` -
-
`; diff --git a/elements/app-hax/demo/index.html b/elements/app-hax/demo/index.html index 02751d9966..edf2f2ac5b 100644 --- a/elements/app-hax/demo/index.html +++ b/elements/app-hax/demo/index.html @@ -51,7 +51,7 @@ } body.dark-mode { background-color: black; - background-image: url('../lib/assets/images/DMGridBox.svg'); + background-image: url('../lib/assets/images/DMBackgroundImage.svg'); --app-hax-accent-color: white; --app-hax-background-color: black; } @@ -68,7 +68,7 @@ display: unset; } body.app-loaded.dark-mode { - background-image: url('../lib/assets/images/DMGridBox.svg'), url('../lib/assets/images/DesignDarkModeLeft.svg'), url('../lib/assets/images/DesignDarkModeRight.svg'); + background-image: url('../lib/assets/images/DMBackgroundImage.svg'), url('../lib/assets/images/DesignDarkModeLeft.svg'), url('../lib/assets/images/DesignDarkModeRight.svg'); } #loading { diff --git a/elements/app-hax/lib/v2/app-hax-search-results.js b/elements/app-hax/lib/v2/app-hax-search-results.js index 329a663296..a398d182c9 100644 --- a/elements/app-hax/lib/v2/app-hax-search-results.js +++ b/elements/app-hax/lib/v2/app-hax-search-results.js @@ -77,9 +77,11 @@ export class AppHaxSearchResults extends SimpleColors { } ul, li { - margin: 0; + margin: 4px; padding: 0; list-style: none; + display: flex; + flex-wrap: wrap; } app-hax-site-bar { margin: 8px 0; diff --git a/elements/app-hax/lib/v2/app-hax-site-bar.js b/elements/app-hax/lib/v2/app-hax-site-bar.js index 587932b03b..b3ce7dddfe 100644 --- a/elements/app-hax/lib/v2/app-hax-site-bar.js +++ b/elements/app-hax/lib/v2/app-hax-site-bar.js @@ -68,17 +68,27 @@ export class AppHaxSiteBars extends SimpleColors { super.styles, css` :host { - --main-banner-width: 513px; - --main-banner-height: 60px; - --band-banner-height: 208px; - display: inline-block; + --main-banner-width: 240px; + --main-banner-height: 240px; + --band-banner-height: 240px; + display: block; background-color: var(--simple-colors-default-theme-accent-3); color: var(--simple-colors-default-theme-grey-12); border-color: var(--simple-colors-default-theme-accent-4); border-style: solid; border-width: 5px 10px 5px 10px; + box-shadow: 4px 4px 4px rgba(0, 0, 0, 0.6); } + .imageLink img{ + display: block; + width: 240px; + height: 150px; + overflow: clip; + justify-self: center; + border-radius: 4px; + } + #labels { display: block; text-overflow: ellipsis; @@ -87,7 +97,7 @@ export class AppHaxSiteBars extends SimpleColors { } #labels ::slotted(*) { font-family: "Press Start 2P", sans-serif; - font-size: 25px; + font-size: 16px; } #labels ::slotted(a) { color: var(--simple-colors-default-theme-accent-11); @@ -104,7 +114,7 @@ export class AppHaxSiteBars extends SimpleColors { background-color: var(--simple-colors-default-theme-accent-3); } #mainCard { - display: flex; + display: block; flex-direction: row; justify-content: space-between; align-items: center; @@ -128,6 +138,9 @@ export class AppHaxSiteBars extends SimpleColors { flex: 1; } #labels { + display: flex; + text-align: center; + justify-content: center; flex: 6; overflow: hidden; text-overflow: ellipsis; @@ -144,12 +157,12 @@ export class AppHaxSiteBars extends SimpleColors { background-color: var(--simple-colors-default-theme-accent-11); } #dots { - --simple-icon-width: 49px; - --simple-icon-height: 49px; - color: var(--simple-colors-default-theme-grey-12); - background-image: url(${unsafeCSS(DropDownBorder)}); - background-repeat: no-repeat; - background-position: center; + --simple-icon-width: 24px; + --simple-icon-height: 24px; + color: var(--simple-colors-default-theme-accent-11); + border: solid var(--simple-colors-default-theme-accent-11); + border-radius: 4px; + margin-left: 8px; } @media (max-width: 640px) { :host { @@ -164,6 +177,7 @@ export class AppHaxSiteBars extends SimpleColors { #mainCard { padding: 0; } + } `, ]; @@ -177,19 +191,24 @@ export class AppHaxSiteBars extends SimpleColors { render() { return html`
- - - + +
-
- +
+
diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index 3617399496..f3bf941818 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -3,6 +3,7 @@ import { LitElement, html, css } from "lit"; import "@haxtheweb/simple-tooltip/simple-tooltip.js"; import { store } from "./AppHaxStore.js"; import "./app-hax-use-case.js"; +import "./app-hax-search-results.js"; export class AppHaxUseCaseFilter extends LitElement { // a convention I enjoy so you can change the tag name in 1 place @@ -57,11 +58,23 @@ export class AppHaxUseCaseFilter extends LitElement { justify-content: flex-start; align-items: flex-start; } + app-hax-search-results { + display: flex; + justify-content: flex-start; + align-items: flex-start; + margin-left: 365px; + } .reset-button { width: 50px; height: 24px; margin: 8px; } + h3 { + font-family: "Press Start 2P"; + justify-content: flex-start; + align-items: flex-start; + color: var(--app-hax-accent-color, var(--accent-color)); + } input [type="text"]{ opacity: 1; width: 216px; @@ -89,7 +102,7 @@ export class AppHaxUseCaseFilter extends LitElement { background-color: var(--ddd-theme-default-white); border: solid var(--ddd-theme-default-limestoneGray) 1px; border-radius: var(--ddd-radius-xs); - width: 300px; + width: px; } .filterButtons { text-align: left; @@ -159,6 +172,14 @@ export class AppHaxUseCaseFilter extends LitElement {
+
+ +
+ +
+

Start New Journey

+
+
${this.filteredItems.length > 0 ? this.filteredItems.map( diff --git a/elements/app-hax/src/app-hax.js b/elements/app-hax/src/app-hax.js index f8e497a0eb..039d110211 100644 --- a/elements/app-hax/src/app-hax.js +++ b/elements/app-hax/src/app-hax.js @@ -1328,9 +1328,7 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} //EDIT HERE templateHome() { return html` -
-
`; From 3367acf2f07ef0fc1e452bfea5954e9ec6e6a949 Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Tue, 4 Mar 2025 10:57:49 -0500 Subject: [PATCH 032/166] bckgrnd stuff --- .../lib/assets/images/LMBackgroundImage.svg | 56 ------------------- .../app-hax/lib/v2/app-hax-use-case-filter.js | 1 + 2 files changed, 1 insertion(+), 56 deletions(-) delete mode 100644 elements/app-hax/lib/assets/images/LMBackgroundImage.svg diff --git a/elements/app-hax/lib/assets/images/LMBackgroundImage.svg b/elements/app-hax/lib/assets/images/LMBackgroundImage.svg deleted file mode 100644 index c7b3235a30..0000000000 --- a/elements/app-hax/lib/assets/images/LMBackgroundImage.svg +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index f3bf941818..6a571b2344 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -70,6 +70,7 @@ export class AppHaxUseCaseFilter extends LitElement { margin: 8px; } h3 { + background-color: white, black; font-family: "Press Start 2P"; justify-content: flex-start; align-items: flex-start; From 8f2b3a3351ec84505539fe698ff63b34275330ac Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Tue, 4 Mar 2025 10:58:42 -0500 Subject: [PATCH 033/166] Add files via upload --- .../assets/images/LMBackgroundImage (1).svg | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 elements/app-hax/lib/assets/images/LMBackgroundImage (1).svg diff --git a/elements/app-hax/lib/assets/images/LMBackgroundImage (1).svg b/elements/app-hax/lib/assets/images/LMBackgroundImage (1).svg new file mode 100644 index 0000000000..861c0a9195 --- /dev/null +++ b/elements/app-hax/lib/assets/images/LMBackgroundImage (1).svg @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From f0552e39feb0d00a86d5f8804a63cee8c606bf2a Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Tue, 4 Mar 2025 12:56:17 -0500 Subject: [PATCH 034/166] Add files via upload --- .../lib/assets/images/LMBackgroundImage.svg | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 elements/app-hax/lib/assets/images/LMBackgroundImage.svg diff --git a/elements/app-hax/lib/assets/images/LMBackgroundImage.svg b/elements/app-hax/lib/assets/images/LMBackgroundImage.svg new file mode 100644 index 0000000000..576f5df74d --- /dev/null +++ b/elements/app-hax/lib/assets/images/LMBackgroundImage.svg @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 65a86d5af711af2cc7f8d3c1680f0da21f9afa19 Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Tue, 4 Mar 2025 12:57:49 -0500 Subject: [PATCH 035/166] some design changes --- elements/app-hax/app-hax.js | 4 +- elements/app-hax/lib/v2/app-hax-label.js | 6 +- .../app-hax/lib/v2/app-hax-use-case-filter.js | 7 ++- elements/app-hax/lib/v2/app-hax-use-case.js | 16 ++--- elements/app-hax/src/app-hax.js | 4 +- .../simple-colors-shared-styles-polymer.js | 59 +++++++++++++++++++ 6 files changed, 78 insertions(+), 18 deletions(-) diff --git a/elements/app-hax/app-hax.js b/elements/app-hax/app-hax.js index 039d110211..cee8532fa6 100644 --- a/elements/app-hax/app-hax.js +++ b/elements/app-hax/app-hax.js @@ -948,8 +948,8 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} padding: 12px; font-size: 12px; border: 4px solid var(--simple-colors-default-theme-grey-12); - background-color: var(--simple-colors-default-theme-yellow-5); - color: var(--simple-colors-default-theme-grey-12); + background-color: var(--ddd-theme-default-nittanyNavy); + color: var(--ddd-theme-default-slateMaxLight); width: 100px; word-wrap: break-word; text-align: center; diff --git a/elements/app-hax/lib/v2/app-hax-label.js b/elements/app-hax/lib/v2/app-hax-label.js index 320fdfb4e6..fcee5f6041 100644 --- a/elements/app-hax/lib/v2/app-hax-label.js +++ b/elements/app-hax/lib/v2/app-hax-label.js @@ -44,7 +44,7 @@ export class AppHaxLabel extends LitElement { .subtitle { color: var(--app-hax-accent-color, var(--accent-color)); font-weight: normal; - margin-top: 2px; + margin-top: 12px; font-size: 20px; } @media (max-width: 700px) { @@ -81,8 +81,8 @@ export class AppHaxLabel extends LitElement { return html`
- <${this.title}> + ${this.title}
${this.subtitle} diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index 6a571b2344..0085cb01dc 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -82,7 +82,7 @@ export class AppHaxUseCaseFilter extends LitElement { max-width: 25vw; transition: all ease-in-out 0.3s; padding: 4px; - font-family: "Press Start 2P", sans-serif; + font-family: "Press Start 2P"; font-size: 12px; margin: 2px 0 0 16px; } @@ -91,7 +91,7 @@ export class AppHaxUseCaseFilter extends LitElement { } .filter { position: fixed; - top: 225px; + top: 215px; left: 20px; height: 300px; justify-self: flex-start; @@ -102,7 +102,6 @@ export class AppHaxUseCaseFilter extends LitElement { padding: var(--ddd-spacing-4); background-color: var(--ddd-theme-default-white); border: solid var(--ddd-theme-default-limestoneGray) 1px; - border-radius: var(--ddd-radius-xs); width: px; } .filterButtons { @@ -115,6 +114,8 @@ export class AppHaxUseCaseFilter extends LitElement { width: 150px; } .filterButtons label { + font-family: "Press Start 2P"; + font-size: 16px; display: flex; align-items: center; justify-content: flex-start; diff --git a/elements/app-hax/lib/v2/app-hax-use-case.js b/elements/app-hax/lib/v2/app-hax-use-case.js index c2a97a399c..c824046cb4 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case.js +++ b/elements/app-hax/lib/v2/app-hax-use-case.js @@ -41,11 +41,10 @@ export class AppHaxUseCase extends LitElement { max-width: 240px; margin:20px; font-family: var(--ddd-font-primary); - background-color: var(--ddd-theme-default-white); + background-color: #EDF8F7; padding: 4px; min-height: 270px; border: solid var(--ddd-theme-default-limestoneGray) 1px; - border-radius: var(--ddd-radius-sm); box-shadow: var(--ddd-boxShadow-md); text-align: center; } @@ -55,7 +54,6 @@ export class AppHaxUseCase extends LitElement { height: 200px; overflow: clip; justify-self: center; - border-radius: 4px; } h3, p { margin: 8px; @@ -66,14 +64,16 @@ export class AppHaxUseCase extends LitElement { a:link { color: var(--ddd-theme-defaut-slateMaxLight); text-decoration: none; + font-size: 16px; } button { display: flex; - font-size: 10px; + background-color: #D9D9D9; + font-family: 'Press Start 2P'; + font-size: 8px; padding: 8px; margin: 0px 2px 0px 2px; height: 16px; - border-radius: var(--ddd-radius-xs); align-items: center; justify-content: center; @@ -98,7 +98,7 @@ export class AppHaxUseCase extends LitElement { ${this.title}
-

${this.title}

+

${this.title}

${this.description}

${this.iconImage.map( (icon) => html` @@ -110,8 +110,8 @@ export class AppHaxUseCase extends LitElement { )}
- - Demo -> + + Demo->
diff --git a/elements/app-hax/src/app-hax.js b/elements/app-hax/src/app-hax.js index 039d110211..cee8532fa6 100644 --- a/elements/app-hax/src/app-hax.js +++ b/elements/app-hax/src/app-hax.js @@ -948,8 +948,8 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} padding: 12px; font-size: 12px; border: 4px solid var(--simple-colors-default-theme-grey-12); - background-color: var(--simple-colors-default-theme-yellow-5); - color: var(--simple-colors-default-theme-grey-12); + background-color: var(--ddd-theme-default-nittanyNavy); + color: var(--ddd-theme-default-slateMaxLight); width: 100px; word-wrap: break-word; text-align: center; diff --git a/elements/simple-colors/lib/simple-colors-shared-styles-polymer.js b/elements/simple-colors/lib/simple-colors-shared-styles-polymer.js index 342422faf5..0e0c2ac28b 100644 --- a/elements/simple-colors/lib/simple-colors-shared-styles-polymer.js +++ b/elements/simple-colors/lib/simple-colors-shared-styles-polymer.js @@ -162,6 +162,19 @@ const css = html` --simple-colors-default-theme-teal-11: #98ffd7; --simple-colors-default-theme-teal-12: #d9fff0; + /*--simple-colors-default-theme-seafoam-1: #031514; + --simple-colors-default-theme-seafoam-2: #052322; + --simple-colors-default-theme-seafoam-3: #0A3432; + --simple-colors-default-theme-seafoam-4: #0E4543; + --simple-colors-default-theme-seafoam-5: #125553; + --simple-colors-default-theme-seafoam-6: #0C8780; + --simple-colors-default-theme-seafoam-7: #00938B; + --simple-colors-default-theme-seafoam-8: #0FAEA6; + --simple-colors-default-theme-seafoam-9: #30D2C9; + --simple-colors-default-theme-seafoam-10: #e1ffeb; + --simple-colors-default-theme-seafoam-11: #40BBB5; + --simple-colors-default-theme-seafoam-12: #e1ffeb;*/ + --simple-colors-default-theme-green-1: #001d0c; --simple-colors-default-theme-green-2: #002a11; --simple-colors-default-theme-green-3: #003d18; @@ -740,6 +753,52 @@ const css = html` --simple-colors-default-theme-accent-12: #d9fff0; } + /*:host([accent-color="seafoam"]), + :host[accent-color="seafoam"] { + --simple-colors-default-theme-accent-1: #001d0c; + --simple-colors-default-theme-accent-2: #40BBB5; + --simple-colors-default-theme-accent-3: #0E4543; + --simple-colors-default-theme-accent-4: #30D2C9; + --simple-colors-default-theme-accent-5: #0FAEA6; + --simple-colors-default-theme-accent-6: #00938B; + --simple-colors-default-theme-accent-7: #0C8780; + --simple-colors-default-theme-accent-8: #125553; + --simple-colors-default-theme-accent-9: #0E4543; + --simple-colors-default-theme-accent-10: #0A3432; + --simple-colors-default-theme-accent-11: #052322; + --simple-colors-default-theme-accent-12: #031514; + --simple-colors-fixed-theme-accent-1: #001d0c; + --simple-colors-fixed-theme-accent-2: #40BBB5; + --simple-colors-fixed-theme-accent-3: #0E4543; + --simple-colors-fixed-theme-accent-4: #30D2C9; + --simple-colors-fixed-theme-accent-5: #0FAEA6; + --simple-colors-fixed-theme-accent-6: #00938B; + --simple-colors-fixed-theme-accent-7: #0C8780; + --simple-colors-fixed-theme-accent-8: #125553; + --simple-colors-fixed-theme-accent-9: #0E4543; + --simple-colors-fixed-theme-accent-10: #0A3432; + --simple-colors-fixed-theme-accent-11: #052322; + --simple-colors-fixed-theme-accent-12: #031514; + } + + :host([dark][accent-color="seafoam"]), + :host([dark]) [accent-color="seafoam"], + :host([accent-color="seafoam"]) [dark], + :host [dark][accent-color="seafoam"] { + --simple-colors-default-theme-accent-1: #031514; + --simple-colors-default-theme-accent-2: #052322; + --simple-colors-default-theme-accent-3: #0A3432; + --simple-colors-default-theme-accent-4: #0E4543; + --simple-colors-default-theme-accent-5: #125553; + --simple-colors-default-theme-accent-6: #0C8780; + --simple-colors-default-theme-accent-7: #00938B; + --simple-colors-default-theme-accent-8: #0FAEA6; + --simple-colors-default-theme-accent-9: #30D2C9; + --simple-colors-default-theme-accent-10: #79ffa7; + --simple-colors-default-theme-accent-11: #40BBB5; + --simple-colors-default-theme-accent-12: #e1ffeb; + }*/ + :host([accent-color="green"]), :host [accent-color="green"] { --simple-colors-default-theme-accent-1: #e1ffeb; From c15c2d533c44a673cd15e9bc9e239b33954b1aff Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Tue, 4 Mar 2025 16:44:38 -0500 Subject: [PATCH 036/166] messing w/ colors --- .../app-hax/lib/v2/app-hax-use-case-filter.js | 29 +++++++++++++------ elements/app-hax/lib/v2/app-hax-use-case.js | 7 +++-- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index 0085cb01dc..40f8440d58 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -70,13 +70,22 @@ export class AppHaxUseCaseFilter extends LitElement { margin: 8px; } h3 { - background-color: white, black; + background-color: var(--simple-colors-default-theme-accent-1, var(--app-hax-accent-color)); + width: 500px; + height: 50px; + text-align: center; font-family: "Press Start 2P"; - justify-content: flex-start; - align-items: flex-start; + display: flex; + justify-content: center; + align-items: center; color: var(--app-hax-accent-color, var(--accent-color)); } - input [type="text"]{ + .startNew { + display: flex; + justify-content: center; + align-items: center; + } + input[type="text"]{ opacity: 1; width: 216px; max-width: 25vw; @@ -85,6 +94,7 @@ export class AppHaxUseCaseFilter extends LitElement { font-family: "Press Start 2P"; font-size: 12px; margin: 2px 0 0 16px; + height: 20px; } .upper-filter { display: flex; @@ -92,19 +102,20 @@ export class AppHaxUseCaseFilter extends LitElement { .filter { position: fixed; top: 215px; - left: 20px; + left: 16px; height: 300px; justify-self: flex-start; display:flex; - background-color: white; + background-color: var(--simple-colors-default-theme-accent-2, var(--accent-color)); + color: var(--simple-colors-default-theme-accent-12, var(--accent-color)); flex-direction: column; margin: var(--ddd-spacing-2); padding: var(--ddd-spacing-4); - background-color: var(--ddd-theme-default-white); border: solid var(--ddd-theme-default-limestoneGray) 1px; - width: px; + width: 300px; } .filterButtons { + margin-top: 8px; text-align: left; align-items: flex-start; justify-self: flex-start; @@ -178,7 +189,7 @@ export class AppHaxUseCaseFilter extends LitElement {
-
+

Start New Journey

diff --git a/elements/app-hax/lib/v2/app-hax-use-case.js b/elements/app-hax/lib/v2/app-hax-use-case.js index c824046cb4..7c42f7e5e9 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case.js +++ b/elements/app-hax/lib/v2/app-hax-use-case.js @@ -39,12 +39,13 @@ export class AppHaxUseCase extends LitElement { display: flex; flex-direction: column; max-width: 240px; - margin:20px; + margin:16px; font-family: var(--ddd-font-primary); - background-color: #EDF8F7; + color: var(--simple-colors-default-theme-light-blue-12, var(--accent-color)); + background-color: var(--simple-colors-default-theme-light-blue-1, var(--accent-color)); padding: 4px; min-height: 270px; - border: solid var(--ddd-theme-default-limestoneGray) 1px; + border: solid var(--simple-colors-default-theme-light-blue-12, var(--accent-9)) 8px; box-shadow: var(--ddd-boxShadow-md); text-align: center; } From 889a6d1aa330f0a093344f879b57c36829e8c154 Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Thu, 6 Mar 2025 11:33:02 -0500 Subject: [PATCH 037/166] background --- .../assets/images/LMBackgroundImage (1).svg | 58 ------------------- .../lib/assets/images/LMBackgroundImage.svg | 58 ------------------- 2 files changed, 116 deletions(-) delete mode 100644 elements/app-hax/lib/assets/images/LMBackgroundImage (1).svg delete mode 100644 elements/app-hax/lib/assets/images/LMBackgroundImage.svg diff --git a/elements/app-hax/lib/assets/images/LMBackgroundImage (1).svg b/elements/app-hax/lib/assets/images/LMBackgroundImage (1).svg deleted file mode 100644 index 861c0a9195..0000000000 --- a/elements/app-hax/lib/assets/images/LMBackgroundImage (1).svg +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/elements/app-hax/lib/assets/images/LMBackgroundImage.svg b/elements/app-hax/lib/assets/images/LMBackgroundImage.svg deleted file mode 100644 index 576f5df74d..0000000000 --- a/elements/app-hax/lib/assets/images/LMBackgroundImage.svg +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 0aa3bcb795188c709b215f9e98ac034689952450 Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Thu, 6 Mar 2025 11:33:36 -0500 Subject: [PATCH 038/166] Add files via upload --- .../lib/assets/images/LMBackgroundImage.svg | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 elements/app-hax/lib/assets/images/LMBackgroundImage.svg diff --git a/elements/app-hax/lib/assets/images/LMBackgroundImage.svg b/elements/app-hax/lib/assets/images/LMBackgroundImage.svg new file mode 100644 index 0000000000..bd14a7f544 --- /dev/null +++ b/elements/app-hax/lib/assets/images/LMBackgroundImage.svg @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 3b27992891a40c9bc02fbe785aeb8d461aba2d47 Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Thu, 6 Mar 2025 11:51:46 -0500 Subject: [PATCH 039/166] Add files via upload --- .../images/lightModeIcon.svg | 8 +++++++ .../wired-darkmode-toggle/images/sunIcon.svg | 21 +++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 elements/app-hax/lib/wired-darkmode-toggle/images/lightModeIcon.svg create mode 100644 elements/app-hax/lib/wired-darkmode-toggle/images/sunIcon.svg diff --git a/elements/app-hax/lib/wired-darkmode-toggle/images/lightModeIcon.svg b/elements/app-hax/lib/wired-darkmode-toggle/images/lightModeIcon.svg new file mode 100644 index 0000000000..156ae5277c --- /dev/null +++ b/elements/app-hax/lib/wired-darkmode-toggle/images/lightModeIcon.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/elements/app-hax/lib/wired-darkmode-toggle/images/sunIcon.svg b/elements/app-hax/lib/wired-darkmode-toggle/images/sunIcon.svg new file mode 100644 index 0000000000..3b5f449c7e --- /dev/null +++ b/elements/app-hax/lib/wired-darkmode-toggle/images/sunIcon.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + From 03999bb467ac3cabb8fc8798d2f9ca4540e1952c Mon Sep 17 00:00:00 2001 From: izzabizz5 Date: Thu, 6 Mar 2025 11:57:53 -0500 Subject: [PATCH 040/166] button functionality (select -> selected & continue) --- .../app-hax/lib/v2/app-hax-use-case-filter.js | 27 +++++++++++ elements/app-hax/lib/v2/app-hax-use-case.js | 47 ++++++++++++++++--- 2 files changed, 67 insertions(+), 7 deletions(-) diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index 3142d0bb19..7cf656b345 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -103,6 +103,7 @@ export class AppHaxUseCaseFilter extends LitElement { background-color: var(--ddd-theme-default-white); border: solid var(--ddd-theme-default-limestoneGray) 1px; width: px; + color: black; } .filterButtons { text-align: left; @@ -195,6 +196,10 @@ export class AppHaxUseCaseFilter extends LitElement { .description=${item.useCaseDescription || ""} .demoLink=${item.demoLink || ""} .iconImage=${item.useCaseIcon || []} + .isSelected=${item.isSelected || false} + .showContinue=${item.showContinue || false} + @toggle-display=${(e) => this.toggleDisplay(index, e)} + @continue-action=${() => this.continueAction(index)} >
@@ -232,6 +237,15 @@ export class AppHaxUseCaseFilter extends LitElement { } } + toggleSelection(index) { + if (this.activeUseCase === index) { + this.activeUseCase = false; // Deselect if the same card is clicked + } else { + this.activeUseCase = index; // Select the new card + } + this.requestUpdate(); + } + handleSearch(event) { this.searchQuery = event.target.value.toLowerCase(); @@ -350,5 +364,18 @@ export class AppHaxUseCaseFilter extends LitElement { this.requestUpdate(); }); } + + toggleDisplay(index, event) { + const isSelected = event.detail.isSelected; + this.filteredItems[index].isSelected = isSelected; + this.filteredItems[index].showContinue = isSelected; + this.requestUpdate(); + } + + continueAction(index) { + console.log(`Continue action for item at index ${index}`); + // Implement the continue action for the selected item + } + } customElements.define("app-hax-use-case-filter", AppHaxUseCaseFilter); diff --git a/elements/app-hax/lib/v2/app-hax-use-case.js b/elements/app-hax/lib/v2/app-hax-use-case.js index c824046cb4..eb11f6a016 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case.js +++ b/elements/app-hax/lib/v2/app-hax-use-case.js @@ -16,6 +16,8 @@ export class AppHaxUseCase extends LitElement { this.source = ''; this.demoLink = ''; this.iconImage = []; + this.isSelected = false; + this.showContinue = false; } static get properties() { @@ -24,7 +26,9 @@ export class AppHaxUseCase extends LitElement { description: { type: String }, source: { type: String }, demoLink: { type: String }, - iconImage: {type: Array } + iconImage: { type: Array }, + isSelected: { type: Boolean }, + showContinue: { type: Boolean } }; } @@ -76,7 +80,6 @@ export class AppHaxUseCase extends LitElement { height: 16px; align-items: center; justify-content: center; - } #haxIcons { position: absolute; @@ -87,15 +90,41 @@ export class AppHaxUseCase extends LitElement { gap: var(--ddd-spacing-3); color: var(--ddd-primary-8); } + + .cardBottom { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 8px; + } + + .cardBottom button, .cardBottom a { + flex: 1; + margin: 0 4px; + } `, ]; } + toggleDisplay() { + this.isSelected = !this.isSelected; + this.showContinue = this.isSelected; + this.dispatchEvent(new CustomEvent('toggle-display', { + detail: { isSelected: this.isSelected }, + bubbles: true, + composed: true + })); + } + + continueAction() { + this.dispatchEvent(new CustomEvent('continue-action')); + } + render() { return html`
- + ${this.title}

${this.title}

@@ -108,10 +137,14 @@ export class AppHaxUseCase extends LitElement { > ` )} -
- - - Demo-> +
+ + ${this.isSelected + ? html`` + : html`Demo -> ` + }
From 1fef11282c699e2be61bfe0c70ab5dadc2a80513 Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Thu, 6 Mar 2025 11:59:28 -0500 Subject: [PATCH 041/166] chnaging darkmode --- .../app-hax/lib/v2/app-hax-use-case-filter.js | 10 ++++++--- .../images/lightModeIcon.svg | 8 ------- .../wired-darkmode-toggle/images/sunIcon.svg | 21 ------------------- .../wired-darkmode-toggle.js | 2 +- 4 files changed, 8 insertions(+), 33 deletions(-) delete mode 100644 elements/app-hax/lib/wired-darkmode-toggle/images/lightModeIcon.svg delete mode 100644 elements/app-hax/lib/wired-darkmode-toggle/images/sunIcon.svg diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index 40f8440d58..b0d7d3c1e2 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -73,14 +73,14 @@ export class AppHaxUseCaseFilter extends LitElement { background-color: var(--simple-colors-default-theme-accent-1, var(--app-hax-accent-color)); width: 500px; height: 50px; - text-align: center; + text-align: left; font-family: "Press Start 2P"; display: flex; justify-content: center; align-items: center; color: var(--app-hax-accent-color, var(--accent-color)); } - .startNew { + .startNew, .returnTo { display: flex; justify-content: center; align-items: center; @@ -106,7 +106,7 @@ export class AppHaxUseCaseFilter extends LitElement { height: 300px; justify-self: flex-start; display:flex; - background-color: var(--simple-colors-default-theme-accent-2, var(--accent-color)); + background-color: var(--simple-colors-default-theme-accent-1, var(--accent-color)); color: var(--simple-colors-default-theme-accent-12, var(--accent-color)); flex-direction: column; margin: var(--ddd-spacing-2); @@ -185,6 +185,10 @@ export class AppHaxUseCaseFilter extends LitElement {
+
+

Return to...

+
+
diff --git a/elements/app-hax/lib/wired-darkmode-toggle/images/lightModeIcon.svg b/elements/app-hax/lib/wired-darkmode-toggle/images/lightModeIcon.svg deleted file mode 100644 index 156ae5277c..0000000000 --- a/elements/app-hax/lib/wired-darkmode-toggle/images/lightModeIcon.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/elements/app-hax/lib/wired-darkmode-toggle/images/sunIcon.svg b/elements/app-hax/lib/wired-darkmode-toggle/images/sunIcon.svg deleted file mode 100644 index 3b5f449c7e..0000000000 --- a/elements/app-hax/lib/wired-darkmode-toggle/images/sunIcon.svg +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/elements/app-hax/lib/wired-darkmode-toggle/wired-darkmode-toggle.js b/elements/app-hax/lib/wired-darkmode-toggle/wired-darkmode-toggle.js index 1496bf4f3e..8d52a50ae7 100644 --- a/elements/app-hax/lib/wired-darkmode-toggle/wired-darkmode-toggle.js +++ b/elements/app-hax/lib/wired-darkmode-toggle/wired-darkmode-toggle.js @@ -8,7 +8,7 @@ import { WiredToggle } from "wired-elements/lib/wired-toggle.js"; import { html, css, unsafeCSS } from "lit"; // need to highjack in order to alter the scale so we can fit our icon // for states -const sun = new URL("./images/sun.svg", import.meta.url).href; +const sun = new URL("./images/sunIcon.svg", import.meta.url).href; const moon = new URL("./images/moon.svg", import.meta.url).href; export class WiredDarkmodeToggle extends WiredToggle { From b7f08d23feab2f1687c855d03c5b1ec841564a8e Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Thu, 6 Mar 2025 12:00:13 -0500 Subject: [PATCH 042/166] Add files via upload --- .../images/lightModeIcon.png | Bin 0 -> 589 bytes .../lib/wired-darkmode-toggle/images/sunIcon.png | Bin 0 -> 1998 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 elements/app-hax/lib/wired-darkmode-toggle/images/lightModeIcon.png create mode 100644 elements/app-hax/lib/wired-darkmode-toggle/images/sunIcon.png diff --git a/elements/app-hax/lib/wired-darkmode-toggle/images/lightModeIcon.png b/elements/app-hax/lib/wired-darkmode-toggle/images/lightModeIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..943094d61aebfc317a0ba9158db4da57510f55fc GIT binary patch literal 589 zcmV-T0Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0pdwSK~z{r?Uyl5 z#4r#=lT;KmR4Xb(1*hU59DsvxDyR?@+KPsPE-<_P$>e*+u|ty0O1y?CHqO)kMw--Z z+g4Ml>w5Iz-}CD*7E>&zg&rTS!sPSx{28Wl(QG+LvC!T1Wtd`KKfc0r1fsc;S#lz# zrC8|xb{D3em$!YGj%ZPl%n?k=aavl+67tZZkjzQZmGjcFq;7T>Vd{C`e}}0DlDR3G za$3ww%M$X?qF#!YU?gXWaatu}fRp4DEx{)Ijj+T-YKoY^&*EI&3^S19dp5Pk6qcYM z@5MhL=;XY6Cd?%U_&mIi1*2NI&bh?^&P~;OkW1CMBrGWC^ajZ-UFR75{;1Za>tw9- zK*N=80aV*1XI;ospgjh)u3ahcs*Ud4miU*O%K6A)jjD2VML{uy6mlotYt=2j@ogV*iZb7e3 zotiL6&Z}3D1OF$D|mC2XbTi3zTpfUlsj z6vyz=5>DF?h1fhEd!H8(9ymYl#T0v6TqWzR`VlPw1zDX^#ogoIovP%Nj>q8_C} bJyrDs)Q^QC_WY7c00000NkvXXu0mjf9+MFp literal 0 HcmV?d00001 diff --git a/elements/app-hax/lib/wired-darkmode-toggle/images/sunIcon.png b/elements/app-hax/lib/wired-darkmode-toggle/images/sunIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..bfad9d2f8d8650a8bebf542fe6ce191779508496 GIT binary patch literal 1998 zcmYjRdpHvc8y_=cEM~~{NG59JR^|wEnb>E>W<#N2Qf?wFxRldbH3+1=Y5{{{k`w+_xt00-alTJE8YPLQGoye04UZGL)=5u zeo6rMY98n?4FC`obH$PD9l~*Y%)bLD`tJ!KDgscD75|5l1pi+K0Y#t?F%yK$-;#v* zKHoqy28sZ5HKhOXUnFaagG434zz81%R7z}*KL`UOwGK#tM9*8QmL;RC4d7HO)xZ5B zBKrsd?=K0H21!W*VF$$hT{YB|B(tv?NlO4*A6n-49&>cRIKIVq5V zI@Cx5s;(%B(wB?D9!iNiZmI{{lav%C_NpgJ$=&3jaA5xs!gnO$klS{T^G-iOI7

E2tCOOF{P$|BM*-S6v{G7H zI)O-f^0aJ|WAB7>c5ra~+1&E&?Gpn7gKceX3kwSyFI3*&G;d}b6c!d26clWeLbLbo z;zA?h-2ftBI1q;o2s=c(St#o=6C|ao!!J_A2V8+*AltS0^es#Aig$4@(Ppvq=d>Y5%3YAkWNQD0rp6)X|pK z=-x{XD!Fd+IpU$e0mk4n>IxjAPu32eIQddp#}Lrt z5#cZSn>bI4n!@xCv@3YdFh@)uId)bM$Z{NP5otX;7|c21M*=unYvqIk*Lzy6FQFfx z=Dm*LdHJ?F7dFO&BnH%36>wwgVSRYd+*aN4H!ZffPV_?RFnR*xO6%j_UgYy#45N_9 zTV+wn7RyevbF;VP9>W8(dS~oD#`&<`6Nap&E>~Rfu?*nmf82}>Egz7MD(nDwWVNNq zg{X8l6`fbf#rYoirY5L&Z)vj8JW`X8*urG=Wycdre{{CCYH_T){+Dr^-mQA_Pm4{3 z=?4AL$a*Zo)dB8%{QFuTL=gYe&+3Utij{TWE=_#h;+jRZ^$@LIC&&wRF7?8e+o`G& zd$)j9`1DMV>6fh+Dt=sD?#Ky)c1qXgP?cq{;L zmcoApbAu^8^??;BMvXkEYR*LIF3G}#eoM}x}|ZZo%d-aqE~f)%D{ YEwN+nL6EBE-a`gp?eUo3ZG98|0yWTj=Kufz literal 0 HcmV?d00001 From f90af69c743d7153f090832c5756aff8fc737ddb Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Thu, 6 Mar 2025 12:03:42 -0500 Subject: [PATCH 043/166] bbbb --- .../lib/wired-darkmode-toggle/images/sunIcon.png | Bin 1998 -> 0 bytes .../wired-darkmode-toggle.js | 6 +++++- 2 files changed, 5 insertions(+), 1 deletion(-) delete mode 100644 elements/app-hax/lib/wired-darkmode-toggle/images/sunIcon.png diff --git a/elements/app-hax/lib/wired-darkmode-toggle/images/sunIcon.png b/elements/app-hax/lib/wired-darkmode-toggle/images/sunIcon.png deleted file mode 100644 index bfad9d2f8d8650a8bebf542fe6ce191779508496..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1998 zcmYjRdpHvc8y_=cEM~~{NG59JR^|wEnb>E>W<#N2Qf?wFxRldbH3+1=Y5{{{k`w+_xt00-alTJE8YPLQGoye04UZGL)=5u zeo6rMY98n?4FC`obH$PD9l~*Y%)bLD`tJ!KDgscD75|5l1pi+K0Y#t?F%yK$-;#v* zKHoqy28sZ5HKhOXUnFaagG434zz81%R7z}*KL`UOwGK#tM9*8QmL;RC4d7HO)xZ5B zBKrsd?=K0H21!W*VF$$hT{YB|B(tv?NlO4*A6n-49&>cRIKIVq5V zI@Cx5s;(%B(wB?D9!iNiZmI{{lav%C_NpgJ$=&3jaA5xs!gnO$klS{T^G-iOI7

E2tCOOF{P$|BM*-S6v{G7H zI)O-f^0aJ|WAB7>c5ra~+1&E&?Gpn7gKceX3kwSyFI3*&G;d}b6c!d26clWeLbLbo z;zA?h-2ftBI1q;o2s=c(St#o=6C|ao!!J_A2V8+*AltS0^es#Aig$4@(Ppvq=d>Y5%3YAkWNQD0rp6)X|pK z=-x{XD!Fd+IpU$e0mk4n>IxjAPu32eIQddp#}Lrt z5#cZSn>bI4n!@xCv@3YdFh@)uId)bM$Z{NP5otX;7|c21M*=unYvqIk*Lzy6FQFfx z=Dm*LdHJ?F7dFO&BnH%36>wwgVSRYd+*aN4H!ZffPV_?RFnR*xO6%j_UgYy#45N_9 zTV+wn7RyevbF;VP9>W8(dS~oD#`&<`6Nap&E>~Rfu?*nmf82}>Egz7MD(nDwWVNNq zg{X8l6`fbf#rYoirY5L&Z)vj8JW`X8*urG=Wycdre{{CCYH_T){+Dr^-mQA_Pm4{3 z=?4AL$a*Zo)dB8%{QFuTL=gYe&+3Utij{TWE=_#h;+jRZ^$@LIC&&wRF7?8e+o`G& zd$)j9`1DMV>6fh+Dt=sD?#Ky)c1qXgP?cq{;L zmcoApbAu^8^??;BMvXkEYR*LIF3G}#eoM}x}|ZZo%d-aqE~f)%D{ YEwN+nL6EBE-a`gp?eUo3ZG98|0yWTj=Kufz diff --git a/elements/app-hax/lib/wired-darkmode-toggle/wired-darkmode-toggle.js b/elements/app-hax/lib/wired-darkmode-toggle/wired-darkmode-toggle.js index 8d52a50ae7..3ec6e45798 100644 --- a/elements/app-hax/lib/wired-darkmode-toggle/wired-darkmode-toggle.js +++ b/elements/app-hax/lib/wired-darkmode-toggle/wired-darkmode-toggle.js @@ -8,7 +8,7 @@ import { WiredToggle } from "wired-elements/lib/wired-toggle.js"; import { html, css, unsafeCSS } from "lit"; // need to highjack in order to alter the scale so we can fit our icon // for states -const sun = new URL("./images/sunIcon.svg", import.meta.url).href; +const sun = new URL("./images/sunIcon.png", import.meta.url).href; const moon = new URL("./images/moon.svg", import.meta.url).href; export class WiredDarkmodeToggle extends WiredToggle { @@ -110,6 +110,10 @@ export class WiredDarkmodeToggle extends WiredToggle { white-space: nowrap; width: 1px; } + sun { + width: 51; + height: 30; + } `, ]; } From 0d71e90c93eb06acc268f7c54c6bbb868eca23d5 Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Thu, 6 Mar 2025 12:04:22 -0500 Subject: [PATCH 044/166] Add files via upload --- .../lib/wired-darkmode-toggle/images/sunIcon.png | Bin 0 -> 656 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 elements/app-hax/lib/wired-darkmode-toggle/images/sunIcon.png diff --git a/elements/app-hax/lib/wired-darkmode-toggle/images/sunIcon.png b/elements/app-hax/lib/wired-darkmode-toggle/images/sunIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..6b94b10568502ed104882a5381ef86715a6e463e GIT binary patch literal 656 zcmV;B0&o3^P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0wqaAK~z{rotD9I z+%OD9wOc}b*mU8^EjMossUkV0mfT#0Yj95X&EqbTLuyd?Abc5uNNK4zgAoXj07yaH zJ&ofy9OZOk`FQeSH)nr#L*hTb9_;C+ZVo4h%k|E+V>FYqBZ-^3xM@A_ye7EHv5w>W zHwML2pObBf*~>cCx8@+54M)`_$fVytv0%5kde-cAyN)desU2m_zgO&T^2i+2cP9Qm z{~JF4{B8PP!pI_dtKwGD%vKS#*mJkzEpi?dbJWmL z9U*?}Zd$SW)JTZ^BBqzB Date: Thu, 6 Mar 2025 12:07:17 -0500 Subject: [PATCH 045/166] yay! --- elements/app-hax/lib/v2/app-hax-use-case.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elements/app-hax/lib/v2/app-hax-use-case.js b/elements/app-hax/lib/v2/app-hax-use-case.js index eb11f6a016..36d8e36920 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case.js +++ b/elements/app-hax/lib/v2/app-hax-use-case.js @@ -142,7 +142,7 @@ export class AppHaxUseCase extends LitElement { ${this.isSelected ? 'Selected' : 'Select'} ${this.isSelected - ? html`` + ? html`` : html`Demo -> ` }

From 30c261f64fa5ce7a6297cfe08d704a16012f4391 Mon Sep 17 00:00:00 2001 From: izzabizz5 Date: Thu, 6 Mar 2025 12:13:59 -0500 Subject: [PATCH 046/166] only one card can be selected at a time. --- .../app-hax/lib/v2/app-hax-use-case-filter.js | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index 7cf656b345..9daee8ed0c 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -24,6 +24,7 @@ export class AppHaxUseCaseFilter extends LitElement { this.demoLink = ""; this.errorMessage = ""; this.loading = false; + this.selectedCardIndex = null; } // Site.json is coming from @@ -40,7 +41,8 @@ export class AppHaxUseCaseFilter extends LitElement { searchQuery: { type: String }, demoLink: { type: String}, errorMessage: { type: String }, - loading: { type: Boolean } + loading: { type: Boolean }, + selectedCardIndex: { type: Number } }; } @@ -367,6 +369,21 @@ export class AppHaxUseCaseFilter extends LitElement { toggleDisplay(index, event) { const isSelected = event.detail.isSelected; + + if (this.selectedCardIndex !== null && this.selectedCardIndex !== index) { + // Deselect the previously selected card + this.filteredItems[this.selectedCardIndex].isSelected = false; + this.filteredItems[this.selectedCardIndex].showContinue = false; + } + + if (isSelected) { + // Select the new card + this.selectedCardIndex = index; + } else { + // Deselect the current card + this.selectedCardIndex = null; + } + this.filteredItems[index].isSelected = isSelected; this.filteredItems[index].showContinue = isSelected; this.requestUpdate(); From c58a16540352085965014ad3e54d91ca0550085c Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Thu, 6 Mar 2025 13:10:57 -0500 Subject: [PATCH 047/166] sun icon --- .../images/lightModeIcon.png | Bin 589 -> 0 bytes .../wired-darkmode-toggle.js | 40 ++++++++++++++---- 2 files changed, 31 insertions(+), 9 deletions(-) delete mode 100644 elements/app-hax/lib/wired-darkmode-toggle/images/lightModeIcon.png diff --git a/elements/app-hax/lib/wired-darkmode-toggle/images/lightModeIcon.png b/elements/app-hax/lib/wired-darkmode-toggle/images/lightModeIcon.png deleted file mode 100644 index 943094d61aebfc317a0ba9158db4da57510f55fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 589 zcmV-T0Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0pdwSK~z{r?Uyl5 z#4r#=lT;KmR4Xb(1*hU59DsvxDyR?@+KPsPE-<_P$>e*+u|ty0O1y?CHqO)kMw--Z z+g4Ml>w5Iz-}CD*7E>&zg&rTS!sPSx{28Wl(QG+LvC!T1Wtd`KKfc0r1fsc;S#lz# zrC8|xb{D3em$!YGj%ZPl%n?k=aavl+67tZZkjzQZmGjcFq;7T>Vd{C`e}}0DlDR3G za$3ww%M$X?qF#!YU?gXWaatu}fRp4DEx{)Ijj+T-YKoY^&*EI&3^S19dp5Pk6qcYM z@5MhL=;XY6Cd?%U_&mIi1*2NI&bh?^&P~;OkW1CMBrGWC^ajZ-UFR75{;1Za>tw9- zK*N=80aV*1XI;ospgjh)u3ahcs*Ud4miU*O%K6A)jjD2VML{uy6mlotYt=2j@ogV*iZb7e3 zotiL6&Z}3D1OF$D|mC2XbTi3zTpfUlsj z6vyz=5>DF?h1fhEd!H8(9ymYl#T0v6TqWzR`VlPw1zDX^#ogoIovP%Nj>q8_C} bJyrDs)Q^QC_WY7c00000NkvXXu0mjf9+MFp diff --git a/elements/app-hax/lib/wired-darkmode-toggle/wired-darkmode-toggle.js b/elements/app-hax/lib/wired-darkmode-toggle/wired-darkmode-toggle.js index 3ec6e45798..a82f6be7dd 100644 --- a/elements/app-hax/lib/wired-darkmode-toggle/wired-darkmode-toggle.js +++ b/elements/app-hax/lib/wired-darkmode-toggle/wired-darkmode-toggle.js @@ -9,6 +9,7 @@ import { html, css, unsafeCSS } from "lit"; // need to highjack in order to alter the scale so we can fit our icon // for states const sun = new URL("./images/sunIcon.png", import.meta.url).href; +const lightModeCircle = new URL("./images/lightModeIcon.png", import.meta.url).href; const moon = new URL("./images/moon.svg", import.meta.url).href; export class WiredDarkmodeToggle extends WiredToggle { @@ -16,6 +17,7 @@ export class WiredDarkmodeToggle extends WiredToggle { super(); this.checked = false; this.label = "Dark mode"; + this.knobFill = svgNode("circle"); } // eslint-disable-next-line class-methods-use-this @@ -33,12 +35,30 @@ export class WiredDarkmodeToggle extends WiredToggle { this.knob = svgNode("g"); this.knob.classList.add("knob"); svg.appendChild(this.knob); - const knobFill = hachureEllipseFill(26, 26, 40, 40, this.seed); - knobFill.classList.add("knobfill"); - this.knob.appendChild(knobFill); + + this.knobFill.setAttribute("cx", 26); + this.knobFill.setAttribute("cy", 26); + this.knobFill.setAttribute("r", 20); + this.knobFill.setAttribute("style", "fill: var(--wired-toggle-off-color); transition: fill 0.3s ease-in-out;"); + this.knobFill.classList.add("knobfill"); + this.knob.appendChild(this.knobFill); ellipse(this.knob, 26, 26, 40, 40, this.seed); } + toggleMode(checked) { + if (checked) { + this.knobFill.setAttribute("style", "fill: var(--wired-toggle-on-color);"); + } else { + this.knobFill.setAttribute("style", "fill: var(--wired-toggle-off-color);"); + } + } + + onChange(event) { + this.checked = event.target.checked; + this.toggleMode(this.checked); + this.dispatchEvent(new Event("change", { bubbles: true, composed: true })); +} + static get properties() { return { checked: { @@ -58,7 +78,7 @@ export class WiredDarkmodeToggle extends WiredToggle { render() { return html`
- + Date: Thu, 6 Mar 2025 13:11:34 -0500 Subject: [PATCH 048/166] Add files via upload --- .../lib/wired-darkmode-toggle/images/moonIcon.png | Bin 0 -> 370 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 elements/app-hax/lib/wired-darkmode-toggle/images/moonIcon.png diff --git a/elements/app-hax/lib/wired-darkmode-toggle/images/moonIcon.png b/elements/app-hax/lib/wired-darkmode-toggle/images/moonIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..315dec05311b21f4a06eb217c7bf0ee5e86a0285 GIT binary patch literal 370 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE-VV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}c0*}aI1_r*vAk26?e?QDnj$5z0=li?)DXq_^uih(D z9wXSUwQ7RP>%WF)RJ(7Qe3`aG>59wUIQzbRHuB}cXPizHDS4RuOtDzu5vo|r!8t*R zLnW(a7LSKwXV0C&d#7%!c5pH3XyIYXVmN Date: Thu, 6 Mar 2025 13:21:45 -0500 Subject: [PATCH 049/166] moon --- .../lib/wired-darkmode-toggle/images/moonIcon.png | Bin 370 -> 0 bytes .../wired-darkmode-toggle.js | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 elements/app-hax/lib/wired-darkmode-toggle/images/moonIcon.png diff --git a/elements/app-hax/lib/wired-darkmode-toggle/images/moonIcon.png b/elements/app-hax/lib/wired-darkmode-toggle/images/moonIcon.png deleted file mode 100644 index 315dec05311b21f4a06eb217c7bf0ee5e86a0285..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 370 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE-VV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}c0*}aI1_r*vAk26?e?QDnj$5z0=li?)DXq_^uih(D z9wXSUwQ7RP>%WF)RJ(7Qe3`aG>59wUIQzbRHuB}cXPizHDS4RuOtDzu5vo|r!8t*R zLnW(a7LSKwXV0C&d#7%!c5pH3XyIYXVmN Date: Thu, 6 Mar 2025 13:22:13 -0500 Subject: [PATCH 050/166] Add files via upload --- .../lib/wired-darkmode-toggle/images/moonIcon.png | Bin 0 -> 369 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 elements/app-hax/lib/wired-darkmode-toggle/images/moonIcon.png diff --git a/elements/app-hax/lib/wired-darkmode-toggle/images/moonIcon.png b/elements/app-hax/lib/wired-darkmode-toggle/images/moonIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..88eb0794354a9d3f7d10f8545330dfc145890017 GIT binary patch literal 369 zcmV-%0gnEOP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0R~A#K~y+Tt&=ed z!Y~+x(;mRpMS2kz7Z)eN$s!I;qUX`kNpNy?adGh?;^OKBD(}%3{-jMs@Pm-p@V-8q zHmj=2{ew=?qW2U!(9(M zuGh=bo}v%(SAw9?c(tVrGcd9M+eC*#k&YX!Bst&ioQrA6kR5hk`1eRB_vN8`W}_kJ zpb@aGFj8PImVm}562DVuXvL|wKKN)Q16HW8h$SEp2`dzBVN0v%cbxkGC0&-lH>fvI P00000NkvXXu0mjfUYwXC literal 0 HcmV?d00001 From 666717959c5d31ad96312db4aedbe7fd50bacbf6 Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Thu, 6 Mar 2025 13:25:39 -0500 Subject: [PATCH 051/166] changed toggle --- .../lib/wired-darkmode-toggle/wired-darkmode-toggle.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/elements/app-hax/lib/wired-darkmode-toggle/wired-darkmode-toggle.js b/elements/app-hax/lib/wired-darkmode-toggle/wired-darkmode-toggle.js index e7281c8b16..7de8a7147b 100644 --- a/elements/app-hax/lib/wired-darkmode-toggle/wired-darkmode-toggle.js +++ b/elements/app-hax/lib/wired-darkmode-toggle/wired-darkmode-toggle.js @@ -114,7 +114,9 @@ export class WiredDarkmodeToggle extends WiredToggle { } :host([checked]) div { background-image: url("${unsafeCSS(moon)}"); - background-position: left; + background-position-x: 12px; + background-position-y: 12px; + background-size: 22px, 22px; } input { width: 100px; From 9ffcccad995086a0942dcf70ca2c10f7d0485bb6 Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Tue, 18 Mar 2025 10:47:06 -0400 Subject: [PATCH 052/166] changed site image --- elements/app-hax/lib/v2/app-hax-site-bar.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/elements/app-hax/lib/v2/app-hax-site-bar.js b/elements/app-hax/lib/v2/app-hax-site-bar.js index b3ce7dddfe..2e5c3eea2b 100644 --- a/elements/app-hax/lib/v2/app-hax-site-bar.js +++ b/elements/app-hax/lib/v2/app-hax-site-bar.js @@ -80,6 +80,9 @@ export class AppHaxSiteBars extends SimpleColors { box-shadow: 4px 4px 4px rgba(0, 0, 0, 0.6); } + .imageLink{ + position: relative; + } .imageLink img{ display: block; width: 240px; @@ -144,11 +147,21 @@ export class AppHaxSiteBars extends SimpleColors { flex: 6; overflow: hidden; text-overflow: ellipsis; + margin-top: 30px; } #icon { --simple-icon-width: 49px; --simple-icon-height: 49px; color: var(--simple-colors-default-theme-accent-11); + background-color: var(--simple-colors-default-theme-accent-3); + } + .imageLink .iconContainer { + background-color: var(--simple-colors-default-theme-accent-3); + width: 55px; + height: 55px; + position: absolute; + bottom: -24px; + right: 95px; } #icon:hover, #icon:focus, @@ -196,6 +209,7 @@ export class AppHaxSiteBars extends SimpleColors {
From 91309904b119332cd66f740606bc3b9c6b59d543 Mon Sep 17 00:00:00 2001 From: Skyler Koba Date: Tue, 18 Mar 2025 10:49:21 -0400 Subject: [PATCH 053/166] Add files via upload --- .../lib/assets/images/pixilart-drawing.png | Bin 0 -> 982 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 elements/app-hax/lib/assets/images/pixilart-drawing.png diff --git a/elements/app-hax/lib/assets/images/pixilart-drawing.png b/elements/app-hax/lib/assets/images/pixilart-drawing.png new file mode 100644 index 0000000000000000000000000000000000000000..c1c91aec40255ed12ee57d41cfe8181bbb408110 GIT binary patch literal 982 zcmeAS@N?(olHy`uVBq!ia0y~yVEh7P8*#7!$yEZH(}5IYage(c!@6@aFBuq^CwRIz zhE&A8z5CE_b$~!?;O~F@y_v1gIz$?q4$XU-pF7i3CEjmmRlfZ3y3*tO_JpfDG%zqS zO&8iBTe`J+|A*}j<#XrBZ?#zO4HCXCyyI?NO8Iua_aB|kXL0}dnx_};1Csc!Zou^? z+PCg`yS$?K$N#$p_ZTxWv2Z-$Fe$u$<(aO%$`i}){hk~G3Jwoan4%BwGkY;t_~%Kp z_eCHfg`frezaRPO|2wwc|N39$?I(603t$0C6nHh72F6R37}`Hw6)OTVZwa?f@2`Bv z?|W?i`WecDMCQaLoGkvjbAk2L`E^J2CIFqnqQ!Y;?lsoEm*ysf0Tl@B*m7Xn0_(Z) zRZsQifuw_2<6LWBwdg%tS>Cu4Y`s&0)~m-0x+{;Y;&lXh<|WhP72H+7j-7P}@g_1A zJC1Vtj@i&2jn#Y%?oUIkH4L$4bc`NxWoPLKc3hNt8?zmfygVon3!z} zHZw$6;7gXYxjx9dE?gW{Poj8TK@Pjh!m{_)v9sWanaI>6w=>KcY^5oqo(Ua4YnMIz?=1dh3GeJykgvTs_HgZ5F+E~GM1|vm-k(2O^j>gEn=yl& zIYr=y?u$inkIW2IK-`$f1ewn(g?|~$w>K$%>btuP6fYg3GrE4pT$p<$IiIx|^q;*zgw*Goi+^{&E(!YI%v!|_Qme2*?OAlwKZ}*$ zkC)y8@qsp+~fT9LFzpF>)7X#)pw&W zJ^>pNwxILJHUG2o^LM&mxc&NnSV?32?x_3zAcvo1THLT-_T#mz_Y3^%bms4o*$gs_ gp;45nz4W`VaM>Yk%cp$Xff<#-)78&qol`;+01AVG9RL6T literal 0 HcmV?d00001 From 3837b9f169caecef331597892958ab053d520ff2 Mon Sep 17 00:00:00 2001 From: Skyler Koba Date: Tue, 18 Mar 2025 10:59:10 -0400 Subject: [PATCH 054/166] Add files via upload --- .../lib/assets/images/h3-background-DM.png | Bin 0 -> 960 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 elements/app-hax/lib/assets/images/h3-background-DM.png diff --git a/elements/app-hax/lib/assets/images/h3-background-DM.png b/elements/app-hax/lib/assets/images/h3-background-DM.png new file mode 100644 index 0000000000000000000000000000000000000000..e8ef3a4c3f17186f25910bd41fd8ff74a0df7c1e GIT binary patch literal 960 zcmeAS@N?(olHy`uVBq!ia0y~yVEh7P8*#7!$yEZH(}5IYage(c!@6@aFBuq^t2|vC zLn`9l-nrYiT0z3$;;(=FZ(Wpmqe>6d7tDRVvi0cnHwLzIpA|pazb*H+u>AXrEF1y~ z4hu9Imu1e{ELQWPc{!tf;obDg3Oz<9pp=DgLe+U&qYt~A<=kTq_|InKS954!Xyjsj zbl`pO?`I3zCv;b|3a5F4Oexsu(DD1)hIIDW6Z-ba`5p}nj7<7MH>AF;Sx|0Ru3UdH zNw z^X=WafdW9o=1)0)RlNCKSY8vz%?$@Ovs}x2-SltG=1o!{w<>JVm>^rSz4)>VNHNPi z%?%=7=S%OJVgH$7Z5K#{gQaojivA|OXKk%u?i59X-dzi(7v_a|f_1ntbvu?@n`=UX zM5oc>)qQE8d}&9RH(0(7q_qj6Ra0Qmz55qf_nvXyk_EP0;YAu)5l4uE!V6KEMY%muQGDoATJe-g97OYKl9k zc#8?-ash!7V{jO-XbA{>;o`d}22msbrSD+)bslE08jaus@m<=V@2r^xHn)d`<*oz7 zW-b<%y-m(rSivqe;M#TmA}i@(B=J<*l_=RacEyT^G;5=4P?Nuap|Bot&CEuJj~ zg+g&hm>1ZCVa>@k+gawj zgRNt0+!|fkGezV}L3DYrc|6#F2Ud+&W_;iNeNO7mmCrMNMuJ_vAyz^C*-b}&^RExT z|F|9gaw=G9!+|vpr=CA8)<3gr;c@;Kd9M%UNpXTxk0DdEv)sMf;tPkFoo*ccJA?VF z2-vax4jn%(T!{6(_w|uxrA&Ea{dtF5njkkW;XJ}^jMJT;I|6U82B^f+j{an^LB{Ts5m3m{E literal 0 HcmV?d00001 From afbc603f7207dfd6c8b56674832e84f47c746a2c Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Tue, 18 Mar 2025 10:59:32 -0400 Subject: [PATCH 055/166] background image --- elements/app-hax/lib/v2/app-hax-use-case-filter.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index b0d7d3c1e2..7f16ee5f28 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -71,6 +71,7 @@ export class AppHaxUseCaseFilter extends LitElement { } h3 { background-color: var(--simple-colors-default-theme-accent-1, var(--app-hax-accent-color)); + background-image: url("/elements/app-hax/lib/assets/images/pixilart-drawing.png"); width: 500px; height: 50px; text-align: left; @@ -84,6 +85,7 @@ export class AppHaxUseCaseFilter extends LitElement { display: flex; justify-content: center; align-items: center; + } input[type="text"]{ opacity: 1; From 79189fe4aba0be20efa499ba63c3f2c1a2b368bb Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Tue, 18 Mar 2025 11:18:37 -0400 Subject: [PATCH 056/166] added bg images --- elements/app-hax/demo/index.html | 1 - .../app-hax/lib/v2/app-hax-use-case-filter.js | 26 +++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/elements/app-hax/demo/index.html b/elements/app-hax/demo/index.html index edf2f2ac5b..2118ff77c7 100644 --- a/elements/app-hax/demo/index.html +++ b/elements/app-hax/demo/index.html @@ -70,7 +70,6 @@ body.app-loaded.dark-mode { background-image: url('../lib/assets/images/DMBackgroundImage.svg'), url('../lib/assets/images/DesignDarkModeLeft.svg'), url('../lib/assets/images/DesignDarkModeRight.svg'); } - #loading { font-family: 'Press Start 2P', sans-serif; text-align: center; diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index 7f16ee5f28..d3c3a79341 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -24,6 +24,7 @@ export class AppHaxUseCaseFilter extends LitElement { this.demoLink = ""; this.errorMessage = ""; this.loading = false; + this.isDarkMode = document.body.classList.contains("dark-mode"); } // Site.json is coming from @@ -40,10 +41,27 @@ export class AppHaxUseCaseFilter extends LitElement { searchQuery: { type: String }, demoLink: { type: String}, errorMessage: { type: String }, - loading: { type: Boolean } + loading: { type: Boolean }, + isDarkMode: {type: Boolean, reflect: true} }; } + //detecting darkmode to change background images ->> there is probably an easier way to do this + connectedCallback() { + super.connectedCallback(); + this._darkModeObserver = new MutationObserver(() => { + this.isDarkMode = document.body.classList.contains("dark-mode"); + }); + this._darkModeObserver.observe(document.body, { attributes: true, attributeFilter: ["class"] }); + } + + disconnectedCallback() { + super.disconnectedCallback(); + if (this._darkModeObserver) { + this._darkModeObserver.disconnect(); + } + } + static get styles() { return [ css` @@ -70,7 +88,7 @@ export class AppHaxUseCaseFilter extends LitElement { margin: 8px; } h3 { - background-color: var(--simple-colors-default-theme-accent-1, var(--app-hax-accent-color)); + background-image: url("/elements/app-hax/lib/assets/images/pixilart-drawing.png"); width: 500px; height: 50px; @@ -81,6 +99,9 @@ export class AppHaxUseCaseFilter extends LitElement { align-items: center; color: var(--app-hax-accent-color, var(--accent-color)); } + :host([isDarkMode]) h3 { + background-image: url("/elements/app-hax/lib/assets/images/h3-background-DM.png"); + } .startNew, .returnTo { display: flex; justify-content: center; @@ -140,6 +161,7 @@ export class AppHaxUseCaseFilter extends LitElement { `, ]; } + testKeydown(e) { if (e.key === "Escape" || e.key === "Enter") { this.toggleSearch(); From a117c95db012bda41f055746d81944dfeb93d9f4 Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Tue, 18 Mar 2025 11:19:37 -0400 Subject: [PATCH 057/166] renamed file --- .../{pixilart-drawing.png => h3-background-LM.png} | Bin elements/app-hax/lib/v2/app-hax-use-case-filter.js | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename elements/app-hax/lib/assets/images/{pixilart-drawing.png => h3-background-LM.png} (100%) diff --git a/elements/app-hax/lib/assets/images/pixilart-drawing.png b/elements/app-hax/lib/assets/images/h3-background-LM.png similarity index 100% rename from elements/app-hax/lib/assets/images/pixilart-drawing.png rename to elements/app-hax/lib/assets/images/h3-background-LM.png diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index d3c3a79341..7ed2c85cd3 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -89,7 +89,7 @@ export class AppHaxUseCaseFilter extends LitElement { } h3 { - background-image: url("/elements/app-hax/lib/assets/images/pixilart-drawing.png"); + background-image: url("/elements/app-hax/lib/assets/images/h3-background-LM.png"); width: 500px; height: 50px; text-align: left; From 8359931be2cfd4387e9bbbf149bc3a678773b178 Mon Sep 17 00:00:00 2001 From: izzabizz5 Date: Tue, 18 Mar 2025 11:31:54 -0400 Subject: [PATCH 058/166] reset button on bottom --- elements/app-hax/app-hax.js | 2 +- elements/app-hax/demo/home.html | 6 +-- elements/app-hax/demo/index.html | 17 ++++---- .../app-hax/lib/v2/app-hax-use-case-filter.js | 40 +++++++++---------- elements/app-hax/src/app-hax.js | 2 +- .../app-hax/test-use-cases/app-hax-copy.js | 17 +++++++- 6 files changed, 49 insertions(+), 35 deletions(-) diff --git a/elements/app-hax/app-hax.js b/elements/app-hax/app-hax.js index cee8532fa6..9d77553d4c 100644 --- a/elements/app-hax/app-hax.js +++ b/elements/app-hax/app-hax.js @@ -1405,4 +1405,4 @@ globalThis.AppHax.requestAvailability = () => { globalThis.AppHax.instance = globalThis.document.querySelector(AppHax.tag); } return globalThis.AppHax.instance; -}; +}; \ No newline at end of file diff --git a/elements/app-hax/demo/home.html b/elements/app-hax/demo/home.html index 3989bada5a..9c2261543e 100644 --- a/elements/app-hax/demo/home.html +++ b/elements/app-hax/demo/home.html @@ -28,10 +28,10 @@ margin: 0; padding: 0; overflow-x: hidden; - background-image: url('../assets/LMGridBox.svg'); + background-image: url('../assets/LMGridBox.svg'); background-repeat: repeat; background-position: center center; - background-size: auto, 20% auto, 20% auto; + background-size: auto, 20% auto, 20% auto; --app-hax-accent-color: black; --app-hax-background-color: white; --simple-tooltip-background: #000000; @@ -242,4 +242,4 @@

Get involved!

HAX is supported by a collaboration of multiple Penn State colleges and departmens.

- + \ No newline at end of file diff --git a/elements/app-hax/demo/index.html b/elements/app-hax/demo/index.html index 048b3c76a4..898ad3ed66 100644 --- a/elements/app-hax/demo/index.html +++ b/elements/app-hax/demo/index.html @@ -31,10 +31,10 @@ padding: 0; font-family: 'Press Start 2P', sans-serif; overflow-x: hidden; - background-image: url('../lib/assets/images/LMGridBox.svg'); + background-image: url('../lib/assets/images/LMBackgroundImage.svg'); background-repeat: repeat; background-position: center center; - background-size: auto, 20% auto, 20% auto; + background-size: auto, 20% auto, 20% auto; --app-hax-accent-color: black; --app-hax-background-color: white; --simple-tooltip-background: #000000; @@ -51,16 +51,15 @@ } body.dark-mode { background-color: black; - background-image: url('../lib/assets/images/DMGridBox.svg'); + background-image: url('../lib/assets/images/DMBackgroundImage.svg'); --app-hax-accent-color: white; --app-hax-background-color: black; } body.app-loaded:not(.bad-device) { - background-image: url('../lib/assets/images/LMGridBox.svg'), url('../lib/assets/images/DesignLightModeLeft.svg'), url('../lib/assets/images/DesignLightModeRight.svg'); - background-repeat: repeat, repeat-y, repeat-y; - background-position: center center, top left, top right; + background-image: url('../lib/assets/images/LMBackgroundImage.svg'), url('../lib/assets/images/DesignLightModeLeft.svg'), url('../lib/assets/images/DesignLightModeRight.svg'); + background-position: top; background-size: auto, 20% auto, 20% auto; - background-attachment: fixed, fixed, fixed; + } div[slot="externalproviders"] { display: none; @@ -69,7 +68,7 @@ display: unset; } body.app-loaded.dark-mode { - background-image: url('../lib/assets/images/DMGridBox.svg'), url('../lib/assets/images/DesignDarkModeLeft.svg'), url('../lib/assets/images/DesignDarkModeRight.svg'); + background-image: url('../lib/assets/images/DMBackgroundImage.svg'), url('../lib/assets/images/DesignDarkModeLeft.svg'), url('../lib/assets/images/DesignDarkModeRight.svg'); } #loading { @@ -382,4 +381,4 @@ }; - + \ No newline at end of file diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index fb34580764..e96ebf5429 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -67,9 +67,11 @@ export class AppHaxUseCaseFilter extends LitElement { margin-left: 365px; } .reset-button { - width: 50px; - height: 24px; - margin: 8px; + font-family: "Press Start 2P"; + font-size: 16px; + display: flex; + align-items: center; + padding: 8px; } h3 { background-color: var(--simple-colors-default-theme-accent-1, var(--app-hax-accent-color)); @@ -166,25 +168,23 @@ export class AppHaxUseCaseFilter extends LitElement { type="text" placeholder="Search Templates" /> - -
- -
+
${this.filters.map( - (filter) => html` - - ` - )} -
+ (filter) => html` + + ` + )} +
+
diff --git a/elements/app-hax/src/app-hax.js b/elements/app-hax/src/app-hax.js index cee8532fa6..9d77553d4c 100644 --- a/elements/app-hax/src/app-hax.js +++ b/elements/app-hax/src/app-hax.js @@ -1405,4 +1405,4 @@ globalThis.AppHax.requestAvailability = () => { globalThis.AppHax.instance = globalThis.document.querySelector(AppHax.tag); } return globalThis.AppHax.instance; -}; +}; \ No newline at end of file diff --git a/elements/app-hax/test-use-cases/app-hax-copy.js b/elements/app-hax/test-use-cases/app-hax-copy.js index 5b45815f73..6e2cee568e 100644 --- a/elements/app-hax/test-use-cases/app-hax-copy.js +++ b/elements/app-hax/test-use-cases/app-hax-copy.js @@ -1263,6 +1263,7 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight}
+
${this.activeItem && !this.siteReady @@ -1294,6 +1295,7 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} @click="${this.getNewWord}" >
${this.appBody(this.appMode)}
+
`; } @@ -1345,6 +1347,19 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} >`; } + siteReadyToGo(e) { + import("@haxtheweb/multiple-choice/lib/confetti-container.js").then( + (module) => { + setTimeout(() => { + this.shadowRoot.querySelector("#confetti").setAttribute("popped", ""); + }, 0); + }, + ); + if (e.detail) { + store.siteReady = true; + } + } + template404() { return html`
{ globalThis.AppHax.instance = globalThis.document.querySelector(AppHax.tag); } return globalThis.AppHax.instance; -}; +}; \ No newline at end of file From 4d458daf463f6a9d815efddc9d299db9fffe1905 Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Tue, 18 Mar 2025 11:34:44 -0400 Subject: [PATCH 059/166] bleh --- elements/app-hax/demo/index.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/elements/app-hax/demo/index.html b/elements/app-hax/demo/index.html index 1a6fc9a0a5..b5a0899f06 100644 --- a/elements/app-hax/demo/index.html +++ b/elements/app-hax/demo/index.html @@ -31,7 +31,7 @@ padding: 0; font-family: 'Press Start 2P', sans-serif; overflow-x: hidden; - background-image: url('../lib/assets/images/LMGridBox.svg'); + background-image: url('../lib/assets/images/LMBackgroundImage.svg'); background-repeat: repeat; background-position: center center; background-size: auto, 20% auto, 20% auto; @@ -51,12 +51,12 @@ } body.dark-mode { background-color: black; - background-image: url('../lib/assets/images/DMGridBox.svg'); + background-image: url('../lib/assets/images/DMBackgroundImage.svg'); --app-hax-accent-color: white; --app-hax-background-color: black; } body.app-loaded:not(.bad-device) { - background-image: url('../lib/assets/images/LMGridBox.svg'), url('../lib/assets/images/DesignLightModeLeft.svg'), url('../lib/assets/images/DesignLightModeRight.svg'); + background-image: url('../lib/assets/images/LMBackgroundImage.svg'), url('../lib/assets/images/DesignLightModeLeft.svg'), url('../lib/assets/images/DesignLightModeRight.svg'); background-repeat: repeat, repeat-y, repeat-y; background-position: center center, top left, top right; background-size: auto, 20% auto, 20% auto; @@ -69,7 +69,7 @@ display: unset; } body.app-loaded.dark-mode { - background-image: url('../lib/assets/images/DMGridBox.svg'), url('../lib/assets/images/DesignDarkModeLeft.svg'), url('../lib/assets/images/DesignDarkModeRight.svg'); + background-image: url('../lib/assets/images/DMBackgroundImage.svg'), url('../lib/assets/images/DesignDarkModeLeft.svg'), url('../lib/assets/images/DesignDarkModeRight.svg'); } #loading { font-family: 'Press Start 2P', sans-serif; From a06fb91920a346b298535e9ac094c55c8e4af95a Mon Sep 17 00:00:00 2001 From: izzabizz5 Date: Tue, 18 Mar 2025 11:51:28 -0400 Subject: [PATCH 060/166] styling filter section a tad --- .../app-hax/lib/v2/app-hax-use-case-filter.js | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index e96ebf5429..809322216c 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -68,9 +68,11 @@ export class AppHaxUseCaseFilter extends LitElement { } .reset-button { font-family: "Press Start 2P"; - font-size: 16px; - display: flex; + font-size: 12px; + width: 100px; + display: inline-flex; align-items: center; + justify-content: center; padding: 8px; } h3 { @@ -116,7 +118,8 @@ export class AppHaxUseCaseFilter extends LitElement { margin: var(--ddd-spacing-2); padding: var(--ddd-spacing-4); border: solid var(--ddd-theme-default-limestoneGray) 1px; - width: 300px; + width: 250px; + border-radius: 10px; } .filterButtons { margin-top: 8px; @@ -172,19 +175,19 @@ export class AppHaxUseCaseFilter extends LitElement {
${this.filters.map( (filter) => html` - - ` - )} -
- + + ` + )} + +
From 1de790ea7037923cfbae4d8176dc09b42a9f4717 Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Tue, 18 Mar 2025 13:14:22 -0400 Subject: [PATCH 061/166] tags and use case stuff --- elements/app-hax/demo/index.html | 7 +- elements/app-hax/lib/v2/app-hax-filter-tag.js | 73 +++++++++++++++++++ .../app-hax/lib/v2/app-hax-use-case-filter.js | 66 ++++++++++++----- elements/app-hax/lib/v2/app-hax-use-case.js | 20 ++++- 4 files changed, 138 insertions(+), 28 deletions(-) create mode 100644 elements/app-hax/lib/v2/app-hax-filter-tag.js diff --git a/elements/app-hax/demo/index.html b/elements/app-hax/demo/index.html index 8abc0fd2e9..22d06335fe 100644 --- a/elements/app-hax/demo/index.html +++ b/elements/app-hax/demo/index.html @@ -57,12 +57,9 @@ } body.app-loaded:not(.bad-device) { background-image: url('../lib/assets/images/LMBackgroundImage.svg'), url('../lib/assets/images/DesignLightModeLeft.svg'), url('../lib/assets/images/DesignLightModeRight.svg'); -<<<<<<< HEAD - background-repeat: repeat, repeat-y, repeat-y; - background-position: center center, top left, top right; -======= background-position: top; ->>>>>>> 8359931be2cfd4387e9bbbf149bc3a678773b178 + background-repeat: repeat; + background-blend-mode: normal; background-size: auto, 20% auto, 20% auto; } diff --git a/elements/app-hax/lib/v2/app-hax-filter-tag.js b/elements/app-hax/lib/v2/app-hax-filter-tag.js new file mode 100644 index 0000000000..c6736e0a76 --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-filter-tag.js @@ -0,0 +1,73 @@ +/* eslint-disable no-return-assign */ +import { LitElement, html, css } from "lit"; +import "@haxtheweb/simple-tooltip/simple-tooltip.js"; + +export class AppHaxFilterTag extends LitElement { + + static get tag() { + return "app-hax-filter-tag"; + } + + constructor() { + super(); + this.label = ''; + + } + + static get properties() { + return { + label: { type: String }, + + }; + } + + updated(changedProperties) { + + } + + static get styles() { + return [ + css` + :host { + display: inline-flex; + font-family: "Press Start 2P"; + color: white; + padding-left: 8px; + padding-right: 8px; + background-color: black; + border-radius: 8px; + font-size: 12px; + align-items: center; + justify-content: flex-start; + } + div { + display: flex; + align-items: center; + } + .remove { + cursor: pointer; + margin-left: 6px; + font-weight: bold; + display: inline-block; + } + `, + ]; + } + + removeTag() { + this.dispatchEvent(new CustomEvent("remove-tag", { detail: this.label, bubbles: true, composed: true })); + } + + render() { + return html` +
+

${this.label}

+ + +
+ + `; + } + +} +customElements.define(AppHaxFilterTag.tag, AppHaxFilterTag); diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index ad287e74e5..125bed5219 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -4,6 +4,7 @@ import "@haxtheweb/simple-tooltip/simple-tooltip.js"; import { store } from "./AppHaxStore.js"; import "./app-hax-use-case.js"; import "./app-hax-search-results.js"; +import "./app-hax-filter-tag.js"; export class AppHaxUseCaseFilter extends LitElement { // a convention I enjoy so you can change the tag name in 1 place @@ -72,9 +73,12 @@ export class AppHaxUseCaseFilter extends LitElement { display: block; width: 100%; } + .rightSection{ + display: block; + margin-left: 336px; + } .results { display: flex; - margin-left: 360px; justify-content: flex-start; align-items: flex-start; } @@ -82,17 +86,18 @@ export class AppHaxUseCaseFilter extends LitElement { display: flex; justify-content: flex-start; align-items: flex-start; - margin-left: 365px; + margin-left: 60px; } .reset-button { + display: flex; font-family: "Press Start 2P"; font-size: 16px; display: flex; align-items: center; + justify-content: center; padding: 8px; } h3 { - background-image: url("/elements/app-hax/lib/assets/images/h3-background-LM.png"); width: 500px; height: 50px; @@ -127,18 +132,18 @@ export class AppHaxUseCaseFilter extends LitElement { display: flex; } .filter { - position: fixed; - top: 215px; + position: absolute; left: 16px; height: 300px; justify-self: flex-start; display:flex; background-color: var(--simple-colors-default-theme-accent-1, var(--accent-color)); color: var(--simple-colors-default-theme-accent-12, var(--accent-color)); + border-radius: 8px; flex-direction: column; margin: var(--ddd-spacing-2); padding: var(--ddd-spacing-4); - border: solid var(--ddd-theme-default-limestoneGray) 1px; + border: solid var(--ddd-theme-default-nittanyNavy, var(--ddd-theme-default-limestoneGray)) 1px; width: 300px; } .filterButtons { @@ -162,6 +167,9 @@ export class AppHaxUseCaseFilter extends LitElement { input[type="checkbox"] { width: 30px; } + .newJourneySection { + display: inline-flex; + } `, ]; } @@ -179,7 +187,19 @@ export class AppHaxUseCaseFilter extends LitElement { render() { return html` -
+
+

Return to...

+
+ +
+ +
+ +
+

Start New Journey

+
+
+
Reset
-
-

Return to...

-
- -
- -
- -
-

Start New Journey

+
+
+ ${this.activeFilters.map( + (filter) => html` + + ` + )}
-
+ ${this.filteredItems.length > 0 ? this.filteredItems.map( (item, index) => html` @@ -247,6 +264,11 @@ export class AppHaxUseCaseFilter extends LitElement { ) : html`

No templates match the filters specified.

`}
+
+ + +
+ `; } @@ -330,7 +352,13 @@ export class AppHaxUseCaseFilter extends LitElement { }); this.requestUpdate(); } - + + removeFilter(event) { + const filterToRemove = event.detail; + this.activeFilters = this.activeFilters.filter((f) => f !== filterToRemove); + this.applyFilters(); // Re-filter results + this.requestUpdate(); + } resetFilters() { this.searchQuery = ""; diff --git a/elements/app-hax/lib/v2/app-hax-use-case.js b/elements/app-hax/lib/v2/app-hax-use-case.js index e6ca11b08d..e79e1f052e 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case.js +++ b/elements/app-hax/lib/v2/app-hax-use-case.js @@ -27,7 +27,7 @@ export class AppHaxUseCase extends LitElement { source: { type: String }, demoLink: { type: String }, iconImage: { type: Array }, - isSelected: { type: Boolean }, + isSelected: { type: Boolean , reflect: true}, showContinue: { type: Boolean } }; } @@ -56,7 +56,7 @@ export class AppHaxUseCase extends LitElement { .image img{ display: block; width: 220px; - height: 200px; + height: 150px; overflow: clip; justify-self: center; } @@ -69,11 +69,15 @@ export class AppHaxUseCase extends LitElement { a:link { color: var(--ddd-theme-defaut-slateMaxLight); text-decoration: none; - font-size: 16px; + font-family: 'Press Start 2P'; + font-size: 12px; } button { display: flex; - background-color: #D9D9D9; + background-color: var(--simple-colors-default-theme-light-blue-1, var(--accent-color)); + color: var(--simple-colors-default-theme-light-blue-12, var(--accent-color)); + border: 2px solid var(--simple-colors-default-theme-light-blue-12, var(--accent-color)); + border-radius: 2px; font-family: 'Press Start 2P'; font-size: 8px; padding: 8px; @@ -103,6 +107,14 @@ export class AppHaxUseCase extends LitElement { flex: 1; margin: 0 4px; } + .cardBottom a:visited { + color: var(--simple-colors-default-theme-light-blue-9); + } + + :host([isSelected]) button.select { + background-color: var(--simple-colors-default-theme-light-blue-12, --accent-color); + color: var(--simple-colors-default-theme-light-blue-1, --accent-color); + } `, ]; } From c366cd5f9be1f43f097d3e0ced06ae1356df531e Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Tue, 18 Mar 2025 13:16:20 -0400 Subject: [PATCH 062/166] fix background repeat --- elements/app-hax/demo/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elements/app-hax/demo/index.html b/elements/app-hax/demo/index.html index 22d06335fe..c91e5a5ddf 100644 --- a/elements/app-hax/demo/index.html +++ b/elements/app-hax/demo/index.html @@ -59,7 +59,7 @@ background-image: url('../lib/assets/images/LMBackgroundImage.svg'), url('../lib/assets/images/DesignLightModeLeft.svg'), url('../lib/assets/images/DesignLightModeRight.svg'); background-position: top; background-repeat: repeat; - background-blend-mode: normal; + /*background-blend-mode: normal;*/ background-size: auto, 20% auto, 20% auto; } From 589ba3fe462a0a81b64d318f701399467a55c0c5 Mon Sep 17 00:00:00 2001 From: izzabizz5 Date: Tue, 18 Mar 2025 13:20:23 -0400 Subject: [PATCH 063/166] styling --- elements/app-hax/lib/v2/app-hax-use-case-filter.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index b6e34713d8..8735c53fa7 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -87,14 +87,15 @@ export class AppHaxUseCaseFilter extends LitElement { .reset-button { font-family: "Press Start 2P"; font-size: 12px; - width: 100px; + width: 216px; display: inline-flex; align-items: center; + text-align: center; justify-content: center; padding: 8px; + margin: 2px 0 0 16px; } h3 { - background-image: url("/elements/app-hax/lib/assets/images/h3-background-LM.png"); width: 500px; height: 50px; @@ -132,7 +133,6 @@ export class AppHaxUseCaseFilter extends LitElement { position: fixed; top: 215px; left: 16px; - height: 300px; justify-self: flex-start; display:flex; background-color: var(--simple-colors-default-theme-accent-1, var(--accent-color)); From 51d03a367fcc4adba7cc36baf3c300d9b1e2d0df Mon Sep 17 00:00:00 2001 From: izzabizz5 Date: Tue, 25 Mar 2025 11:47:10 -0400 Subject: [PATCH 064/166] added 'brochure' to receipes --- elements/app-hax/lib/v2/app-hax-recipes.json | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/elements/app-hax/lib/v2/app-hax-recipes.json b/elements/app-hax/lib/v2/app-hax-recipes.json index 4395a05d12..9563e4a513 100644 --- a/elements/app-hax/lib/v2/app-hax-recipes.json +++ b/elements/app-hax/lib/v2/app-hax-recipes.json @@ -60,5 +60,25 @@ { "icon": "icons:language", "tooltip": "Translatable"}, { "icon": "icons:thumb-up", "tooltip": "Popular"} ] + }, + { + "uuid": "1b4132dd-c557-4576-89c7-f89446feda4a", + "title": "Brochure", + "category": ["Brochure"], + "recipe": "recipes/brochure/brochure.recipe", + "theme": { + "element": "clean-blog", + "path": "@haxtheweb/clean-brochure/clean-brochure.js" + }, + "author": "haxtheweb", + "image": "/elements/app-hax/lib/assets/screenshots/clean-one.jpg", + "description": "Art gallery, blog posts, any collection of work and self presentation", + "icon": "hax:hax2022", + "demo-url": "https://playground.hax.cloud/site.html?recipe=", + "attributes": [ + { "icon": "icons:favorite", "tooltip": "Mark as Favorite" }, + { "icon": "icons:language", "tooltip": "Translatable"}, + { "icon": "icons:thumb-up", "tooltip": "Popular"} + ] }] } \ No newline at end of file From 9e2f064f62ef9acfc9f039b7bbfd5816f2a9a00c Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Tue, 25 Mar 2025 11:59:26 -0400 Subject: [PATCH 065/166] messing around --- elements/app-hax/app-hax.js | 59 +++++-------- .../lib/assets/images/h3-background-DM.png | Bin 960 -> 0 bytes .../lib/assets/images/h3-background-LM.png | Bin 982 -> 0 bytes elements/app-hax/lib/v2/app-hax-label.js | 5 +- .../app-hax/lib/v2/app-hax-scroll-button.js | 78 ++++++++++++++++++ .../app-hax/lib/v2/app-hax-use-case-filter.js | 41 ++------- elements/app-hax/src/app-hax.js | 59 +++++-------- 7 files changed, 129 insertions(+), 113 deletions(-) delete mode 100644 elements/app-hax/lib/assets/images/h3-background-DM.png delete mode 100644 elements/app-hax/lib/assets/images/h3-background-LM.png create mode 100644 elements/app-hax/lib/v2/app-hax-scroll-button.js diff --git a/elements/app-hax/app-hax.js b/elements/app-hax/app-hax.js index 9d77553d4c..fab1b8a567 100644 --- a/elements/app-hax/app-hax.js +++ b/elements/app-hax/app-hax.js @@ -17,6 +17,7 @@ import { SimpleTourFinder } from "@haxtheweb/simple-popover/lib/SimpleTourFinder import "./lib/v2/app-hax-use-case.js"; import "./lib/v2/app-hax-use-case-filter.js"; import "./lib/v2/app-hax-search-results.js"; +import "./lib/v2/app-hax-scroll-button.js"; const logoutBtn = new URL("./lib/assets/images/Logout.svg", import.meta.url) .href; @@ -475,7 +476,6 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} const badDevice = toJS(store.badDevice); if (badDevice === false) { import("@haxtheweb/rpg-character/rpg-character.js"); - import("./lib/random-word/random-word.js"); } else if (badDevice === true) { globalThis.document.body.classList.add("bad-device"); } @@ -862,13 +862,17 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} } } .label { - text-align: center; + display: inline-flex; + text-align: flex-start; } app-hax-label { animation: 0.8s ease-in-out 0s scrollin; -webkit-animation: 0.8s ease-in-out 0s scrollin; - display: block; + display: flex; + align-self: flex-start; overflow: hidden; + margin-left: 24px; + margin-right: 24px; } app-hax-label h1 { font-weight: normal; @@ -936,29 +940,6 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} font-family: "Press Start 2P", sans-serif; font-size: 12px; } - - random-word:not(:defined) { - display: none; - } - random-word { - transform: rotate(25deg); - position: absolute; - right: 10px; - top: 120px; - padding: 12px; - font-size: 12px; - border: 4px solid var(--simple-colors-default-theme-grey-12); - background-color: var(--ddd-theme-default-nittanyNavy); - color: var(--ddd-theme-default-slateMaxLight); - width: 100px; - word-wrap: break-word; - text-align: center; - cursor: pointer; - user-select: none; - opacity: 1; - visibility: visible; - transition: all 0.3s ease-in-out; - } #helpbtn { --simple-icon-height: 50px; --simple-icon-width: 50px; @@ -994,9 +975,6 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} } } @media (max-width: 640px) { - random-word { - display: none; - } .content { margin-top: 4px; } @@ -1291,22 +1269,24 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} ` : ``} + +
+ +
+
+ +
- +
${this.appBody(this.appMode)}
`; } - getNewWord() { - this.shadowRoot.querySelector("random-word").getNewWord(); - store.appEl.playSound("click"); - } - appBody(routine) { let template = html``; switch (routine) { @@ -1331,6 +1311,7 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight}
+ `; } diff --git a/elements/app-hax/lib/assets/images/h3-background-DM.png b/elements/app-hax/lib/assets/images/h3-background-DM.png deleted file mode 100644 index e8ef3a4c3f17186f25910bd41fd8ff74a0df7c1e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 960 zcmeAS@N?(olHy`uVBq!ia0y~yVEh7P8*#7!$yEZH(}5IYage(c!@6@aFBuq^t2|vC zLn`9l-nrYiT0z3$;;(=FZ(Wpmqe>6d7tDRVvi0cnHwLzIpA|pazb*H+u>AXrEF1y~ z4hu9Imu1e{ELQWPc{!tf;obDg3Oz<9pp=DgLe+U&qYt~A<=kTq_|InKS954!Xyjsj zbl`pO?`I3zCv;b|3a5F4Oexsu(DD1)hIIDW6Z-ba`5p}nj7<7MH>AF;Sx|0Ru3UdH zNw z^X=WafdW9o=1)0)RlNCKSY8vz%?$@Ovs}x2-SltG=1o!{w<>JVm>^rSz4)>VNHNPi z%?%=7=S%OJVgH$7Z5K#{gQaojivA|OXKk%u?i59X-dzi(7v_a|f_1ntbvu?@n`=UX zM5oc>)qQE8d}&9RH(0(7q_qj6Ra0Qmz55qf_nvXyk_EP0;YAu)5l4uE!V6KEMY%muQGDoATJe-g97OYKl9k zc#8?-ash!7V{jO-XbA{>;o`d}22msbrSD+)bslE08jaus@m<=V@2r^xHn)d`<*oz7 zW-b<%y-m(rSivqe;M#TmA}i@(B=J<*l_=RacEyT^G;5=4P?Nuap|Bot&CEuJj~ zg+g&hm>1ZCVa>@k+gawj zgRNt0+!|fkGezV}L3DYrc|6#F2Ud+&W_;iNeNO7mmCrMNMuJ_vAyz^C*-b}&^RExT z|F|9gaw=G9!+|vpr=CA8)<3gr;c@;Kd9M%UNpXTxk0DdEv)sMf;tPkFoo*ccJA?VF z2-vax4jn%(T!{6(_w|uxrA&Ea{dtF5njkkW;XJ}^jMJT;I|6U82B^f+j{an^LB{Ts5m3m{E diff --git a/elements/app-hax/lib/assets/images/h3-background-LM.png b/elements/app-hax/lib/assets/images/h3-background-LM.png deleted file mode 100644 index c1c91aec40255ed12ee57d41cfe8181bbb408110..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 982 zcmeAS@N?(olHy`uVBq!ia0y~yVEh7P8*#7!$yEZH(}5IYage(c!@6@aFBuq^CwRIz zhE&A8z5CE_b$~!?;O~F@y_v1gIz$?q4$XU-pF7i3CEjmmRlfZ3y3*tO_JpfDG%zqS zO&8iBTe`J+|A*}j<#XrBZ?#zO4HCXCyyI?NO8Iua_aB|kXL0}dnx_};1Csc!Zou^? z+PCg`yS$?K$N#$p_ZTxWv2Z-$Fe$u$<(aO%$`i}){hk~G3Jwoan4%BwGkY;t_~%Kp z_eCHfg`frezaRPO|2wwc|N39$?I(603t$0C6nHh72F6R37}`Hw6)OTVZwa?f@2`Bv z?|W?i`WecDMCQaLoGkvjbAk2L`E^J2CIFqnqQ!Y;?lsoEm*ysf0Tl@B*m7Xn0_(Z) zRZsQifuw_2<6LWBwdg%tS>Cu4Y`s&0)~m-0x+{;Y;&lXh<|WhP72H+7j-7P}@g_1A zJC1Vtj@i&2jn#Y%?oUIkH4L$4bc`NxWoPLKc3hNt8?zmfygVon3!z} zHZw$6;7gXYxjx9dE?gW{Poj8TK@Pjh!m{_)v9sWanaI>6w=>KcY^5oqo(Ua4YnMIz?=1dh3GeJykgvTs_HgZ5F+E~GM1|vm-k(2O^j>gEn=yl& zIYr=y?u$inkIW2IK-`$f1ewn(g?|~$w>K$%>btuP6fYg3GrE4pT$p<$IiIx|^q;*zgw*Goi+^{&E(!YI%v!|_Qme2*?OAlwKZ}*$ zkC)y8@qsp+~fT9LFzpF>)7X#)pw&W zJ^>pNwxILJHUG2o^LM&mxc&NnSV?32?x_3zAcvo1THLT-_T#mz_Y3^%bms4o*$gs_ gp;45nz4W`VaM>Yk%cp$Xff<#-)78&qol`;+01AVG9RL6T diff --git a/elements/app-hax/lib/v2/app-hax-label.js b/elements/app-hax/lib/v2/app-hax-label.js index fcee5f6041..aef727147e 100644 --- a/elements/app-hax/lib/v2/app-hax-label.js +++ b/elements/app-hax/lib/v2/app-hax-label.js @@ -25,7 +25,8 @@ export class AppHaxLabel extends LitElement { return css` :host { font-family: "Press Start 2P", sans-serif; - text-align: center; + text-align: flex-start; + width: 500px; } .title { @@ -38,7 +39,7 @@ export class AppHaxLabel extends LitElement { font-weight: normal; font-size: 3.5vw; display: inline-flex; - align-items: center; + align-items: flex-start; } .subtitle { diff --git a/elements/app-hax/lib/v2/app-hax-scroll-button.js b/elements/app-hax/lib/v2/app-hax-scroll-button.js new file mode 100644 index 0000000000..1a90506509 --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-scroll-button.js @@ -0,0 +1,78 @@ +/* eslint-disable no-return-assign */ +import { LitElement, html, css } from "lit"; +import "@haxtheweb/simple-tooltip/simple-tooltip.js"; + +export class AppHaxScrollButton extends LitElement { + + static get tag() { + return "app-hax-scroll-button"; + } + + constructor() { + super(); + this.label = ''; + this.isDarkMode = document.body.classList.contains("dark-mode"); + } + + static get properties() { + return { + label: { type: String }, + isDarkMode: {type: Boolean, reflect: true}, + }; + } + + connectedCallback() { + super.connectedCallback(); + this._darkModeObserver = new MutationObserver(() => { + this.isDarkMode = document.body.classList.contains("dark-mode"); + }); + this._darkModeObserver.observe(document.body, { attributes: true, attributeFilter: ["class"] }); + } + + disconnectedCallback() { + super.disconnectedCallback(); + if (this._darkModeObserver) { + this._darkModeObserver.disconnect(); + } + } + + + static get styles() { + return [ + css` + :host { + display: flex; + font-family: "Press Start 2P"; + background-image: url("/elements/app-hax/lib/assets/images/scroll-button-LM.png"); + background-size: cover; + background-position: center; + width: 300px; + height: 50px; + color: var(--app-hax-accent-color, var(--accent-color)); + align-items: center; + justify-content: center; + text-align: center; + margin: 8px; + } + :host([isDarkMode]) { + background-image: url("/elements/app-hax/lib/assets/images/scroll-button-DM.png"); + } + div { + display: flex; + align-items: center; + } + `, + ]; + } + + render() { + return html` +
+

${this.label}

+
+ + `; + } + +} +customElements.define(AppHaxScrollButton.tag, AppHaxScrollButton); diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index 125bed5219..cd450a8260 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -5,6 +5,7 @@ import { store } from "./AppHaxStore.js"; import "./app-hax-use-case.js"; import "./app-hax-search-results.js"; import "./app-hax-filter-tag.js"; +import "./app-hax-scroll-button.js"; export class AppHaxUseCaseFilter extends LitElement { // a convention I enjoy so you can change the tag name in 1 place @@ -25,7 +26,6 @@ export class AppHaxUseCaseFilter extends LitElement { this.demoLink = ""; this.errorMessage = ""; this.loading = false; - this.isDarkMode = document.body.classList.contains("dark-mode"); this.selectedCardIndex = null; } @@ -44,27 +44,10 @@ export class AppHaxUseCaseFilter extends LitElement { demoLink: { type: String}, errorMessage: { type: String }, loading: { type: Boolean }, - isDarkMode: {type: Boolean, reflect: true}, - selectedCardIndex: { type: Number } + selectedCardIndex: { type: Number }, }; } - //detecting darkmode to change background images ->> there is probably an easier way to do this - connectedCallback() { - super.connectedCallback(); - this._darkModeObserver = new MutationObserver(() => { - this.isDarkMode = document.body.classList.contains("dark-mode"); - }); - this._darkModeObserver.observe(document.body, { attributes: true, attributeFilter: ["class"] }); - } - - disconnectedCallback() { - super.disconnectedCallback(); - if (this._darkModeObserver) { - this._darkModeObserver.disconnect(); - } - } - static get styles() { return [ css` @@ -97,20 +80,11 @@ export class AppHaxUseCaseFilter extends LitElement { justify-content: center; padding: 8px; } - h3 { - background-image: url("/elements/app-hax/lib/assets/images/h3-background-LM.png"); - width: 500px; - height: 50px; - text-align: left; - font-family: "Press Start 2P"; - display: flex; - justify-content: center; - align-items: center; + h4 { + font-family: "Veranda"; + font-size: 24px; color: var(--app-hax-accent-color, var(--accent-color)); } - :host([isDarkMode]) h3 { - background-image: url("/elements/app-hax/lib/assets/images/h3-background-DM.png"); - } .startNew, .returnTo { display: flex; justify-content: center; @@ -188,15 +162,16 @@ export class AppHaxUseCaseFilter extends LitElement { render() { return html`
-

Return to...

+

Resume Journey

+
-

Start New Journey

+

Start New Journey

diff --git a/elements/app-hax/src/app-hax.js b/elements/app-hax/src/app-hax.js index 9d77553d4c..fab1b8a567 100644 --- a/elements/app-hax/src/app-hax.js +++ b/elements/app-hax/src/app-hax.js @@ -17,6 +17,7 @@ import { SimpleTourFinder } from "@haxtheweb/simple-popover/lib/SimpleTourFinder import "./lib/v2/app-hax-use-case.js"; import "./lib/v2/app-hax-use-case-filter.js"; import "./lib/v2/app-hax-search-results.js"; +import "./lib/v2/app-hax-scroll-button.js"; const logoutBtn = new URL("./lib/assets/images/Logout.svg", import.meta.url) .href; @@ -475,7 +476,6 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} const badDevice = toJS(store.badDevice); if (badDevice === false) { import("@haxtheweb/rpg-character/rpg-character.js"); - import("./lib/random-word/random-word.js"); } else if (badDevice === true) { globalThis.document.body.classList.add("bad-device"); } @@ -862,13 +862,17 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} } } .label { - text-align: center; + display: inline-flex; + text-align: flex-start; } app-hax-label { animation: 0.8s ease-in-out 0s scrollin; -webkit-animation: 0.8s ease-in-out 0s scrollin; - display: block; + display: flex; + align-self: flex-start; overflow: hidden; + margin-left: 24px; + margin-right: 24px; } app-hax-label h1 { font-weight: normal; @@ -936,29 +940,6 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} font-family: "Press Start 2P", sans-serif; font-size: 12px; } - - random-word:not(:defined) { - display: none; - } - random-word { - transform: rotate(25deg); - position: absolute; - right: 10px; - top: 120px; - padding: 12px; - font-size: 12px; - border: 4px solid var(--simple-colors-default-theme-grey-12); - background-color: var(--ddd-theme-default-nittanyNavy); - color: var(--ddd-theme-default-slateMaxLight); - width: 100px; - word-wrap: break-word; - text-align: center; - cursor: pointer; - user-select: none; - opacity: 1; - visibility: visible; - transition: all 0.3s ease-in-out; - } #helpbtn { --simple-icon-height: 50px; --simple-icon-width: 50px; @@ -994,9 +975,6 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} } } @media (max-width: 640px) { - random-word { - display: none; - } .content { margin-top: 4px; } @@ -1291,22 +1269,24 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} ` : ``} + +
+ +
+
+ +
- +
${this.appBody(this.appMode)}
`; } - getNewWord() { - this.shadowRoot.querySelector("random-word").getNewWord(); - store.appEl.playSound("click"); - } - appBody(routine) { let template = html``; switch (routine) { @@ -1331,6 +1311,7 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight}
+ `; } From 130ff470f451f59eb4091df188c80aa87bc7d632 Mon Sep 17 00:00:00 2001 From: Skyler Koba Date: Tue, 25 Mar 2025 12:00:18 -0400 Subject: [PATCH 066/166] Add files via upload --- .../lib/assets/images/scroll-button-DM.png | Bin 0 -> 727 bytes .../lib/assets/images/scroll-button-LM.png | Bin 0 -> 727 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 elements/app-hax/lib/assets/images/scroll-button-DM.png create mode 100644 elements/app-hax/lib/assets/images/scroll-button-LM.png diff --git a/elements/app-hax/lib/assets/images/scroll-button-DM.png b/elements/app-hax/lib/assets/images/scroll-button-DM.png new file mode 100644 index 0000000000000000000000000000000000000000..a5eecd5226042af085b96cc5bf2c84fe81639c1d GIT binary patch literal 727 zcmeAS@N?(olHy`uVBq!ia0y~yVAKJ!jX2nVv>Z=YQM@yE}W>Nzts zK4Y1d8u?D)$BRYjo_GK3u{Pet#>mnoSaGl1ZsPUS#I>80RwkAAT5$L{Buu>?nmLy% zJ0~>7)N!+$!vc-QjfHbNUk5~NTeYaXJ%Yo>>p{-#TcTo-zPDCv6wvT{;1Sglx~Jx& zfQRyjjT>^pGeu{MH%761Tk+ZC4#yRh4_dm1R^8kj z!ZAg`Awo4vgsD-ErL6U7;fCY93aU(*Ec2FbwH2Ba8rAyDb%A)JqVAzrS9fpWa1l~i zbK(|HuY*5R%hk>0D+N1LK4|Ma51;r~QmV0x#Vk`WZ1+7@H-$+IiLTeuGFYmB>gVnC z?sZUMJk+)3>;;Z5Dh?60)zhUKJ(yZVBWEuZeBs%!q3WBSDbqw24(&~5&dL`iGbDa} z6Pv}N#3>M#lH2CCK%Mc>tDC#8V6)sIV&Yby>3|R;RxYQWo$`5WZ%$bN-CZH|H;K zY*Bn5?tVK&SA*#%(Cq!roB|on4I6Gj1paZHwhXIVD5MZD^}v4nAX!J*ec@|k^jM5I z-~0>RtE;^^AXqtICPQLqUbq=Bk}O1~>8_5r{YXK;=Rs&#_LR5Xi`VO?M;_FbmThEW zxpy)vJi=@(Q*U>JgGQrmq+nRa!eed=j2fd4ZAuN@r<&rN;K$^?$?DDqw>e*Jva26| z`nDtc+?8cc42>F0_Ol{wi#2AQ7Aq2vzq&tButTw6Tc|DjPMtL$J1q3J6&}6A&*qw7 z#gx4GS7p`iHw#ba*ZA7Vi7r=8RA3R9G4H_5#rNYH@?9DtnBMQcXAVrM44$rjF6*2U FngGYNE=&Lb literal 0 HcmV?d00001 diff --git a/elements/app-hax/lib/assets/images/scroll-button-LM.png b/elements/app-hax/lib/assets/images/scroll-button-LM.png new file mode 100644 index 0000000000000000000000000000000000000000..6dd1fbf3d697c9c587b2850b1c822a9e628fd039 GIT binary patch literal 727 zcmV;|0x127P)Px%kx4{BRCr$P-9c`HKoCSxxc{Mvu#80z228AIYWiiBg-N=8jlSBmu*c#4&vgG$ zPa=RoaRTF={GUGblGHTu)g9oTK>&ea7{_1gx$L3KFC2zpA}L1=0R+BH;3=<5F1qrf z$0|iu->%8uLjZw=z-r?i$IeE_N28H7Fjh}ouLq@Nnk52!m4== zq(&fu0AWScWJm-Mm7=btfgcVnrff1-nfUxRz zFF68n1PCjxG6N$}mjGea?Ot*O;s_8{TxAAEpe_Nzs@uKf2*eQ}thmYyj6huigjKhD z$q|SnKv;2=85n`O1PH5c_mU$JM}V;6Dl;$wbqNqw-R>nvAdUcG#Z_it1nLqXth(Jx zjzAoNMOgFTK4K=WJ_93Ahk%bruG6)o2*eX0toRBAK%fo*!m87?qzJ?l*b2)%R(z!b zAkZg)y)RN-lDd5Fvva8sh$L|IRrR*4$Vv^3K)(bCtKV)VL!dhXXTq{&byvAS2xJo2 z%4$wAe=p(QkGrhQj!lg~7X_QK=%ah3d@$&{m~E* zfwl-7$?9ywT9QmpbG4PsGzcKj4S}bqPM!4b(%nUTH%CDb1llHWwpFdC|3p}iMeDV8 zO|M_ureQh+5NM9TYNI;cs{SIZ^|OrC+%Yf^0x<+WU6vlfegJm(!Xsm2B8dP1002ov JPDHLkV1oGQGdchO literal 0 HcmV?d00001 From 89f54b583ed8963bda59df9a444727c0d10b53f6 Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Tue, 25 Mar 2025 13:21:45 -0400 Subject: [PATCH 067/166] stuff --- elements/app-hax/app-hax.js | 4 +- .../app-hax/lib/v2/app-hax-scroll-button.js | 15 ++++- .../app-hax/lib/v2/app-hax-search-results.js | 61 ++++++++++++++++--- elements/app-hax/lib/v2/app-hax-site-bar.js | 32 +--------- .../app-hax/lib/v2/app-hax-use-case-filter.js | 50 +++++++-------- elements/app-hax/lib/v2/app-hax-use-case.js | 55 ++++++++++------- elements/app-hax/src/app-hax.js | 4 +- 7 files changed, 131 insertions(+), 90 deletions(-) diff --git a/elements/app-hax/app-hax.js b/elements/app-hax/app-hax.js index fab1b8a567..57eeb10b1d 100644 --- a/elements/app-hax/app-hax.js +++ b/elements/app-hax/app-hax.js @@ -1273,11 +1273,13 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight}
diff --git a/elements/app-hax/lib/v2/app-hax-scroll-button.js b/elements/app-hax/lib/v2/app-hax-scroll-button.js index 1a90506509..cea344766a 100644 --- a/elements/app-hax/lib/v2/app-hax-scroll-button.js +++ b/elements/app-hax/lib/v2/app-hax-scroll-button.js @@ -11,16 +11,26 @@ export class AppHaxScrollButton extends LitElement { constructor() { super(); this.label = ''; + this.targetId = ''; this.isDarkMode = document.body.classList.contains("dark-mode"); } static get properties() { return { label: { type: String }, + targetId: { type: String }, isDarkMode: {type: Boolean, reflect: true}, }; } + scrollToTarget() { + if (this.targetId) { + const targetElement = document.getElementById(this.targetId); + if (targetElement) { + targetElement.scrollIntoView({ behavior: "smooth", block: "start" }); + } + } + } connectedCallback() { super.connectedCallback(); this._darkModeObserver = new MutationObserver(() => { @@ -67,10 +77,9 @@ export class AppHaxScrollButton extends LitElement { render() { return html` -
-

${this.label}

+
+
${this.label}
- `; } diff --git a/elements/app-hax/lib/v2/app-hax-search-results.js b/elements/app-hax/lib/v2/app-hax-search-results.js index a398d182c9..862bbaaca6 100644 --- a/elements/app-hax/lib/v2/app-hax-search-results.js +++ b/elements/app-hax/lib/v2/app-hax-search-results.js @@ -72,16 +72,50 @@ export class AppHaxSearchResults extends SimpleColors { return [ super.styles, css` - :host { + + .carousel-container { + display: flex; + align-items: center; + justify-content: center; + gap: 10px; overflow: hidden; + margin: 0px; + } + .scroll-left, + .scroll-right { + background: var(--app-hax-accent-color, black); + color: white; + border: none; + padding: 10px; + cursor: pointer; + } + + #results { + display: flex; + flex-wrap: nowrap; + overflow-x: auto; + overflow-y: hidden; + scroll-snap-type: x mandatory; + gap: 36px; + padding: 8px; + white-space: nowrap; + scrollbar-width: none; + -ms-overflow-style: none; + } + + #results::-webkit-scrollbar { + display: none; } - ul, + li { - margin: 4px; - padding: 0; - list-style: none; + flex: 0 0 auto; + scroll-snap-align: start; + width: 240px; + height: 300px; display: flex; - flex-wrap: wrap; + flex-direction: column; + align-items: center; + justify-content: center; } app-hax-site-bar { margin: 8px 0; @@ -126,6 +160,8 @@ export class AppHaxSearchResults extends SimpleColors { } render() { return html` + `} + +
+ `; } + scrollLeft() { + this.shadowRoot.querySelector("#results").scrollBy({ left: -300, behavior: "smooth" }); + } + + scrollRight() { + this.shadowRoot.querySelector("#results").scrollBy({ left: 300, behavior: "smooth" }); + } + getItemDetails(item) { const details = { created: varGet(item, "metadata.site.created", new Date() / 1000), diff --git a/elements/app-hax/lib/v2/app-hax-site-bar.js b/elements/app-hax/lib/v2/app-hax-site-bar.js index 2e5c3eea2b..a5dad86721 100644 --- a/elements/app-hax/lib/v2/app-hax-site-bar.js +++ b/elements/app-hax/lib/v2/app-hax-site-bar.js @@ -79,13 +79,9 @@ export class AppHaxSiteBars extends SimpleColors { border-width: 5px 10px 5px 10px; box-shadow: 4px 4px 4px rgba(0, 0, 0, 0.6); } - - .imageLink{ - position: relative; - } .imageLink img{ display: block; - width: 240px; + width: 200px; height: 150px; overflow: clip; justify-self: center; @@ -149,26 +145,6 @@ export class AppHaxSiteBars extends SimpleColors { text-overflow: ellipsis; margin-top: 30px; } - #icon { - --simple-icon-width: 49px; - --simple-icon-height: 49px; - color: var(--simple-colors-default-theme-accent-11); - background-color: var(--simple-colors-default-theme-accent-3); - } - .imageLink .iconContainer { - background-color: var(--simple-colors-default-theme-accent-3); - width: 55px; - height: 55px; - position: absolute; - bottom: -24px; - right: 95px; - } - #icon:hover, - #icon:focus, - #icon:active { - color: var(--simple-colors-default-theme-accent-3); - background-color: var(--simple-colors-default-theme-accent-11); - } #dots { --simple-icon-width: 24px; --simple-icon-height: 24px; @@ -206,12 +182,6 @@ export class AppHaxSiteBars extends SimpleColors {
diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index cd450a8260..cd75717cc7 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -70,10 +70,11 @@ export class AppHaxUseCaseFilter extends LitElement { justify-content: flex-start; align-items: flex-start; margin-left: 60px; + width: 750px; } .reset-button { display: flex; - font-family: "Press Start 2P"; + font-family: var(--ddd-font-primary); font-size: 16px; display: flex; align-items: center; @@ -81,14 +82,17 @@ export class AppHaxUseCaseFilter extends LitElement { padding: 8px; } h4 { - font-family: "Veranda"; + font-family: var(--ddd-font-primary); font-size: 24px; color: var(--app-hax-accent-color, var(--accent-color)); } .startNew, .returnTo { - display: flex; - justify-content: center; - align-items: center; + display: inline-flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + margin-left: 48px; + margin-right: 48px; } input[type="text"]{ @@ -97,7 +101,7 @@ export class AppHaxUseCaseFilter extends LitElement { max-width: 25vw; transition: all ease-in-out 0.3s; padding: 4px; - font-family: "Press Start 2P"; + font-family: var(--ddd-font-primary); font-size: 12px; margin: 2px 0 0 16px; height: 20px; @@ -131,7 +135,7 @@ export class AppHaxUseCaseFilter extends LitElement { width: 150px; } .filterButtons label { - font-family: "Press Start 2P"; + font-family: var(--ddd-font-primary); font-size: 16px; display: flex; align-items: center; @@ -153,26 +157,9 @@ export class AppHaxUseCaseFilter extends LitElement { this.toggleSearch(); } } - // eslint-disable-next-line class-methods-use-this - search() { - store.appEl.playSound("click"); - this.searchTerm = this.shadowRoot.querySelector("#searchField").value; - } render() { return html` -
-

Resume Journey

-
- - -
- -
- -
-

Start New Journey

-
@@ -214,7 +201,18 @@ export class AppHaxUseCaseFilter extends LitElement { ` )}
-
+ + +
+

Return to...

+ +
+ + + +
+

Start New Journey

+
${this.filteredItems.length > 0 ? this.filteredItems.map( @@ -241,6 +239,8 @@ export class AppHaxUseCaseFilter extends LitElement {
+
+
diff --git a/elements/app-hax/lib/v2/app-hax-use-case.js b/elements/app-hax/lib/v2/app-hax-use-case.js index e79e1f052e..f1670a3ea4 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case.js +++ b/elements/app-hax/lib/v2/app-hax-use-case.js @@ -42,21 +42,22 @@ export class AppHaxUseCase extends LitElement { :host { display: flex; flex-direction: column; + text-align: flex-start; max-width: 240px; margin:16px; font-family: var(--ddd-font-primary); - color: var(--simple-colors-default-theme-light-blue-12, var(--accent-color)); - background-color: var(--simple-colors-default-theme-light-blue-1, var(--accent-color)); + color: var(--ddd-theme-default-nittanyNavy); + background-color: white; padding: 4px; min-height: 270px; - border: solid var(--simple-colors-default-theme-light-blue-12, var(--accent-9)) 8px; box-shadow: var(--ddd-boxShadow-md); - text-align: center; + border-radius: 8px; } .image img{ display: block; - width: 220px; + width: 100%; height: 150px; + border-bottom: solid var(--ddd-theme-default-nittanyNavy) 12px; overflow: clip; justify-self: center; } @@ -67,19 +68,20 @@ export class AppHaxUseCase extends LitElement { font-size: 12px; } a:link { - color: var(--ddd-theme-defaut-slateMaxLight); + color: var(--ddd-theme-defaut-skyBlue); text-decoration: none; - font-family: 'Press Start 2P'; + font-family: var(--ddd-font-primary); font-size: 12px; } button { display: flex; - background-color: var(--simple-colors-default-theme-light-blue-1, var(--accent-color)); - color: var(--simple-colors-default-theme-light-blue-12, var(--accent-color)); - border: 2px solid var(--simple-colors-default-theme-light-blue-12, var(--accent-color)); - border-radius: 2px; - font-family: 'Press Start 2P'; - font-size: 8px; + background-color: white; + color: var(--ddd-theme-default-nittanyNavy); + border: 2px solid var(--ddd-theme-default-nittanyNavy); + border-radius: 4px; + font-family: var(--ddd-font-primary); + font-size: 12px; + font-weight: 20px; padding: 8px; margin: 0px 2px 0px 2px; height: 16px; @@ -115,6 +117,11 @@ export class AppHaxUseCase extends LitElement { background-color: var(--simple-colors-default-theme-light-blue-12, --accent-color); color: var(--simple-colors-default-theme-light-blue-1, --accent-color); } + .titleBar { + display: inline-flex; + align-items: center; + text-align: flex-start; + } `, ]; } @@ -140,16 +147,20 @@ export class AppHaxUseCase extends LitElement { ${this.title}
-

${this.title}

+
+

${this.title}

+ ${this.iconImage.map( + (icon) => html` + + ` + )} +
+

${this.description}

- ${this.iconImage.map( - (icon) => html` - - ` - )} +
From cfaf8690650112b55f6f62b99b094c5b39b07245 Mon Sep 17 00:00:00 2001 From: izzabizz5 Date: Thu, 27 Mar 2025 12:17:20 -0400 Subject: [PATCH 068/166] icons on image and tooltips of icons appearing below in a list format --- elements/app-hax/lib/v2/app-hax-recipes.json | 7 +- .../app-hax/lib/v2/app-hax-use-case-filter.js | 37 +++--- elements/app-hax/lib/v2/app-hax-use-case.js | 110 +++++++++++++----- 3 files changed, 98 insertions(+), 56 deletions(-) diff --git a/elements/app-hax/lib/v2/app-hax-recipes.json b/elements/app-hax/lib/v2/app-hax-recipes.json index 9563e4a513..47b2373a60 100644 --- a/elements/app-hax/lib/v2/app-hax-recipes.json +++ b/elements/app-hax/lib/v2/app-hax-recipes.json @@ -18,7 +18,8 @@ "attributes": [ { "icon": "icons:favorite", "tooltip": "Mark as Favorite" }, { "icon": "icons:language", "tooltip": "Translatable"}, - { "icon": "icons:thumb-up", "tooltip": "Popular"} + { "icon": "icons:thumb-up", "tooltip": "Popular"}, + { "icon": "icons:accessibility", "tooltip": "Accessible"} ] }, { @@ -77,8 +78,8 @@ "demo-url": "https://playground.hax.cloud/site.html?recipe=", "attributes": [ { "icon": "icons:favorite", "tooltip": "Mark as Favorite" }, - { "icon": "icons:language", "tooltip": "Translatable"}, - { "icon": "icons:thumb-up", "tooltip": "Popular"} + { "icon": "icons:language", "tooltip": "Translatable" }, + { "icon": "icons:thumb-up", "tooltip": "Popular" } ] }] } \ No newline at end of file diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index 4260b44b52..818c2b3e37 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -74,20 +74,12 @@ export class AppHaxUseCaseFilter extends LitElement { } .reset-button { display: flex; -<<<<<<< HEAD - font-family: "Press Start 2P"; - font-size: 12px; - width: 216px; - display: inline-flex; -======= font-family: var(--ddd-font-primary); font-size: 16px; display: flex; ->>>>>>> 89f54b583ed8963bda59df9a444727c0d10b53f6 align-items: center; justify-content: center; padding: 8px; - margin: 2px 0 0 16px; } h4 { font-family: var(--ddd-font-primary); @@ -120,6 +112,7 @@ export class AppHaxUseCaseFilter extends LitElement { .filter { position: absolute; left: 16px; + height: 300px; justify-self: flex-start; display:flex; background-color: var(--simple-colors-default-theme-accent-1, var(--accent-color)); @@ -185,19 +178,19 @@ export class AppHaxUseCaseFilter extends LitElement {
${this.filters.map( (filter) => html` - - ` - )} - -
+ + ` + )} +
+
@@ -443,4 +436,4 @@ export class AppHaxUseCaseFilter extends LitElement { } } -customElements.define("app-hax-use-case-filter", AppHaxUseCaseFilter); +customElements.define("app-hax-use-case-filter", AppHaxUseCaseFilter); \ No newline at end of file diff --git a/elements/app-hax/lib/v2/app-hax-use-case.js b/elements/app-hax/lib/v2/app-hax-use-case.js index f1670a3ea4..981522db6e 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case.js +++ b/elements/app-hax/lib/v2/app-hax-use-case.js @@ -53,14 +53,67 @@ export class AppHaxUseCase extends LitElement { box-shadow: var(--ddd-boxShadow-md); border-radius: 8px; } - .image img{ - display: block; + .image img { width: 100%; - height: 150px; + height: 125px; border-bottom: solid var(--ddd-theme-default-nittanyNavy) 12px; overflow: clip; justify-self: center; } + .image { + position: relative; + display: inline-block; + } + #haxicons { + position: absolute; + bottom: var(--ddd-spacing-2); + left: var(--ddd-spacing-2); + padding: var(--ddd-spacing-1) var(--ddd-spacing-1); + opacity: 0.8; + gap: var(--ddd-spacing-3); + color: var(--ddd-primary-8); + position: absolute; + width: 40px; /* Adjust size as needed */ + display: flex; + } + .icons { + position: absolute; + bottom: 15px; + left: 50%; + transform: translateX(-50%); + display: flex; + gap: 8px; + } + .icon-wrapper { + position: relative; + } + .tooltip-container { + display: none; + flex-direction: column; + position: absolute; + top: 100%; + left: 50%; + transform: translateX(-50%); + background-color: white; + color: black; + padding: 8px; + border-radius: 6px; + box-shadow: rgba(0, 0, 0, 0.2) 0px 4px 6px; + width: max-content; + } + .tooltip { + font-size: 12px; + padding: 4px 8px; + border-bottom: 1px solid #ccc; + text-align: left; + white-space: nowrap; + } + .tooltip:last-child { + border-bottom: none; + } + .icons:hover .tooltip-container { + display: block; + } h3, p { margin: 8px; } @@ -88,16 +141,6 @@ export class AppHaxUseCase extends LitElement { align-items: center; justify-content: center; } - #haxIcons { - position: absolute; - bottom: var(--ddd-spacing-2); - left: var(--ddd-spacing-2); - padding: var(--ddd-spacing-1) var(--ddd-spacing-1); - opacity: 0.8; - gap: var(--ddd-spacing-3); - color: var(--ddd-primary-8); - } - .cardBottom { display: flex; justify-content: space-between; @@ -146,30 +189,35 @@ export class AppHaxUseCase extends LitElement {
${this.title} +
+ ${this.iconImage.map( + (icon) => html` +
+ +
+ ` + )} +
+ ${this.iconImage.map( + (icon) => html`
${icon.tooltip}
` + )} +
+

${this.title}

- ${this.iconImage.map( - (icon) => html` - - ` - )}
-

${this.description}

+

${this.description}

-
- - ${this.isSelected - ? html`` - : html`Demo -> ` - } -
+
+ + ${this.isSelected + ? html`` + : html`Demo -> ` + }
`; From d00c418257be5d4aba60a652f11dc70edf2b735c Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Thu, 27 Mar 2025 12:33:49 -0400 Subject: [PATCH 069/166] fixed scroll buttons --- elements/app-hax/app-hax.js | 1 + elements/app-hax/lib/v2/app-hax-filter-tag.js | 5 ++- .../app-hax/lib/v2/app-hax-scroll-button.js | 25 +++++++++-- .../app-hax/lib/v2/app-hax-search-results.js | 17 +++++--- elements/app-hax/lib/v2/app-hax-site-bar.js | 41 ++++++++++--------- .../app-hax/lib/v2/app-hax-use-case-filter.js | 33 +++++++++++---- elements/app-hax/lib/v2/app-hax-use-case.js | 3 +- elements/app-hax/src/app-hax.js | 1 + 8 files changed, 86 insertions(+), 40 deletions(-) diff --git a/elements/app-hax/app-hax.js b/elements/app-hax/app-hax.js index 57eeb10b1d..fc6efc2d09 100644 --- a/elements/app-hax/app-hax.js +++ b/elements/app-hax/app-hax.js @@ -864,6 +864,7 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} .label { display: inline-flex; text-align: flex-start; + align-items: center; } app-hax-label { animation: 0.8s ease-in-out 0s scrollin; diff --git a/elements/app-hax/lib/v2/app-hax-filter-tag.js b/elements/app-hax/lib/v2/app-hax-filter-tag.js index c6736e0a76..dc0cd9f493 100644 --- a/elements/app-hax/lib/v2/app-hax-filter-tag.js +++ b/elements/app-hax/lib/v2/app-hax-filter-tag.js @@ -30,13 +30,14 @@ export class AppHaxFilterTag extends LitElement { css` :host { display: inline-flex; - font-family: "Press Start 2P"; + font-family: var(--ddd-font-primary); color: white; padding-left: 8px; padding-right: 8px; + height: 32px; background-color: black; border-radius: 8px; - font-size: 12px; + font-size: 16px; align-items: center; justify-content: flex-start; } diff --git a/elements/app-hax/lib/v2/app-hax-scroll-button.js b/elements/app-hax/lib/v2/app-hax-scroll-button.js index cea344766a..2b55c6e188 100644 --- a/elements/app-hax/lib/v2/app-hax-scroll-button.js +++ b/elements/app-hax/lib/v2/app-hax-scroll-button.js @@ -25,9 +25,28 @@ export class AppHaxScrollButton extends LitElement { scrollToTarget() { if (this.targetId) { - const targetElement = document.getElementById(this.targetId); + let targetElement = null; + let appHax = this.closest('app-hax') || document.querySelector('app-hax'); + + if (appHax) { + + let useCaseFilter = appHax.shadowRoot + ? appHax.shadowRoot.querySelector('app-hax-use-case-filter') + : appHax.querySelector('app-hax-use-case-filter'); + if (useCaseFilter) { + targetElement = useCaseFilter.shadowRoot + ? useCaseFilter.shadowRoot.getElementById(this.targetId) + : useCaseFilter.querySelector(`#${this.targetId}`); + } + } + if (!targetElement) { + targetElement = document.getElementById(this.targetId); + } if (targetElement) { + console.log(`Scrolling to:`, targetElement); targetElement.scrollIntoView({ behavior: "smooth", block: "start" }); + } else { + console.warn(`Element with id '${this.targetId}' not found inside app-hax-use-case-filter.`); } } } @@ -77,9 +96,9 @@ export class AppHaxScrollButton extends LitElement { render() { return html` -
+
${this.label}
-
+
`; } diff --git a/elements/app-hax/lib/v2/app-hax-search-results.js b/elements/app-hax/lib/v2/app-hax-search-results.js index 862bbaaca6..fa2d05675b 100644 --- a/elements/app-hax/lib/v2/app-hax-search-results.js +++ b/elements/app-hax/lib/v2/app-hax-search-results.js @@ -80,6 +80,9 @@ export class AppHaxSearchResults extends SimpleColors { gap: 10px; overflow: hidden; margin: 0px; + height: 300px; + justify-self: flex-start; + align-self: flex-start; } .scroll-left, .scroll-right { @@ -88,6 +91,9 @@ export class AppHaxSearchResults extends SimpleColors { border: none; padding: 10px; cursor: pointer; + height: 240px; + opacity: 50%; + color: var(--simple-colors-default-theme-accent-1, var(--simple-colors-default-theme-accent-12)); } #results { @@ -97,10 +103,11 @@ export class AppHaxSearchResults extends SimpleColors { overflow-y: hidden; scroll-snap-type: x mandatory; gap: 36px; - padding: 8px; white-space: nowrap; scrollbar-width: none; -ms-overflow-style: none; + padding: 16px; + scroll-padding-left: 16px; } #results::-webkit-scrollbar { @@ -109,7 +116,7 @@ export class AppHaxSearchResults extends SimpleColors { li { flex: 0 0 auto; - scroll-snap-align: start; + scroll-snap-align: center; width: 240px; height: 300px; display: flex; @@ -118,7 +125,7 @@ export class AppHaxSearchResults extends SimpleColors { justify-content: center; } app-hax-site-bar { - margin: 8px 0; + margin: 12px 0; } .description { max-height: 64px; @@ -212,11 +219,11 @@ export class AppHaxSearchResults extends SimpleColors { } scrollLeft() { - this.shadowRoot.querySelector("#results").scrollBy({ left: -300, behavior: "smooth" }); + this.shadowRoot.querySelector("#results").scrollBy({ left: -250, behavior: "smooth" }); } scrollRight() { - this.shadowRoot.querySelector("#results").scrollBy({ left: 300, behavior: "smooth" }); + this.shadowRoot.querySelector("#results").scrollBy({ left: 250, behavior: "smooth" }); } getItemDetails(item) { diff --git a/elements/app-hax/lib/v2/app-hax-site-bar.js b/elements/app-hax/lib/v2/app-hax-site-bar.js index a5dad86721..07deb11a2d 100644 --- a/elements/app-hax/lib/v2/app-hax-site-bar.js +++ b/elements/app-hax/lib/v2/app-hax-site-bar.js @@ -69,23 +69,23 @@ export class AppHaxSiteBars extends SimpleColors { css` :host { --main-banner-width: 240px; - --main-banner-height: 240px; - --band-banner-height: 240px; + --main-banner-height: 220px; + --band-banner-height: 220px; display: block; - background-color: var(--simple-colors-default-theme-accent-3); - color: var(--simple-colors-default-theme-grey-12); - border-color: var(--simple-colors-default-theme-accent-4); - border-style: solid; - border-width: 5px 10px 5px 10px; - box-shadow: 4px 4px 4px rgba(0, 0, 0, 0.6); + background-color: var(--simple-colors-default-theme-light-blue-3); + color: var(--simple-colors-default-theme-grey-3); + outline: 5px solid var(--simple-colors-default-theme-light-blue-4); + outline-offset: -5px; + border-radius: 8px; } .imageLink img{ display: block; - width: 200px; - height: 150px; + width: 240px; + height: 125px; overflow: clip; justify-self: center; - border-radius: 4px; + border-top-right-radius: 8px; + border-top-left-radius: 8px; } #labels { @@ -95,22 +95,23 @@ export class AppHaxSiteBars extends SimpleColors { white-space: nowrap; } #labels ::slotted(*) { - font-family: "Press Start 2P", sans-serif; - font-size: 16px; + font-family: var(--ddd-font-primary); + font-size: 20px; + font-weight: bold; } #labels ::slotted(a) { - color: var(--simple-colors-default-theme-accent-11); + color: var(--simple-colors-default-theme-light-blue-11); padding: 8px 0; display: block; } #labels ::slotted(a:focus), #labels ::slotted(a:hover) { - color: var(--simple-colors-default-theme-accent-3); - background-color: var(--simple-colors-default-theme-accent-11); + color: var(--simple-colors-default-theme-light-blue-3); + background-color: var(--simple-colors-default-theme-light-blue-11); } :host([opened]) { - background-color: var(--simple-colors-default-theme-accent-3); + background-color: var(--simple-colors-default-theme-light-blue-3); } #mainCard { display: block; @@ -143,13 +144,13 @@ export class AppHaxSiteBars extends SimpleColors { flex: 6; overflow: hidden; text-overflow: ellipsis; - margin-top: 30px; + margin-top: 20px; } #dots { --simple-icon-width: 24px; --simple-icon-height: 24px; - color: var(--simple-colors-default-theme-accent-11); - border: solid var(--simple-colors-default-theme-accent-11); + color: var(--simple-colors-default-theme-light-blue-11); + border: solid var(--simple-colors-default-theme-light-blue-11); border-radius: 4px; margin-left: 8px; } diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index cd75717cc7..981220e30d 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -69,22 +69,23 @@ export class AppHaxUseCaseFilter extends LitElement { display: flex; justify-content: flex-start; align-items: flex-start; - margin-left: 60px; - width: 750px; + width: 800px; } .reset-button { display: flex; font-family: var(--ddd-font-primary); - font-size: 16px; + font-size: 12px; display: flex; align-items: center; justify-content: center; padding: 8px; + margin-top: 16px; } h4 { font-family: var(--ddd-font-primary); font-size: 24px; color: var(--app-hax-accent-color, var(--accent-color)); + margin: 16px; } .startNew, .returnTo { display: inline-flex; @@ -97,17 +98,27 @@ export class AppHaxUseCaseFilter extends LitElement { } input[type="text"]{ opacity: 1; - width: 216px; + width: 250px; + padding: 4px; + padding-left: 35px; max-width: 25vw; transition: all ease-in-out 0.3s; - padding: 4px; font-family: var(--ddd-font-primary); - font-size: 12px; - margin: 2px 0 0 16px; + font-size: 16px; + margin: 4px 0 0 4px; height: 20px; } .upper-filter { - display: flex; + position: relative; + display: inline-block; + } + .search-icon { + position: absolute; + left: 12px; + top: 50%; + transform: translateY(-50%); + font-size: 16px; + align-self: center; } .filter { position: absolute; @@ -121,7 +132,7 @@ export class AppHaxUseCaseFilter extends LitElement { flex-direction: column; margin: var(--ddd-spacing-2); padding: var(--ddd-spacing-4); - border: solid var(--ddd-theme-default-nittanyNavy, var(--ddd-theme-default-limestoneGray)) 1px; + border: solid 1px var(--simple-colors-default-theme-accent-12, var(--accent-color)); width: 300px; } .filterButtons { @@ -164,6 +175,9 @@ export class AppHaxUseCaseFilter extends LitElement {
+ + + +
${this.filters.map( diff --git a/elements/app-hax/lib/v2/app-hax-use-case.js b/elements/app-hax/lib/v2/app-hax-use-case.js index f1670a3ea4..c5f972b2d5 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case.js +++ b/elements/app-hax/lib/v2/app-hax-use-case.js @@ -48,7 +48,6 @@ export class AppHaxUseCase extends LitElement { font-family: var(--ddd-font-primary); color: var(--ddd-theme-default-nittanyNavy); background-color: white; - padding: 4px; min-height: 270px; box-shadow: var(--ddd-boxShadow-md); border-radius: 8px; @@ -57,6 +56,8 @@ export class AppHaxUseCase extends LitElement { display: block; width: 100%; height: 150px; + border-top-right-radius: 8px; + border-top-left-radius: 8px; border-bottom: solid var(--ddd-theme-default-nittanyNavy) 12px; overflow: clip; justify-self: center; diff --git a/elements/app-hax/src/app-hax.js b/elements/app-hax/src/app-hax.js index 57eeb10b1d..fc6efc2d09 100644 --- a/elements/app-hax/src/app-hax.js +++ b/elements/app-hax/src/app-hax.js @@ -864,6 +864,7 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} .label { display: inline-flex; text-align: flex-start; + align-items: center; } app-hax-label { animation: 0.8s ease-in-out 0s scrollin; From a78a26cf0af1478018b67126cde53bfca282006e Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Thu, 27 Mar 2025 12:57:00 -0400 Subject: [PATCH 070/166] bcgrnd stuff --- .../lib/assets/images/DMBackgroundImage.svg | 56 ------------------ .../lib/assets/images/LMBackgroundImage.svg | 57 ------------------- .../app-hax/lib/v2/app-hax-search-results.js | 2 +- elements/app-hax/lib/v2/app-hax-site-bar.js | 1 + .../app-hax/lib/v2/app-hax-use-case-filter.js | 1 + elements/app-hax/lib/v2/app-hax-use-case.js | 18 +++--- 6 files changed, 12 insertions(+), 123 deletions(-) delete mode 100644 elements/app-hax/lib/assets/images/DMBackgroundImage.svg delete mode 100644 elements/app-hax/lib/assets/images/LMBackgroundImage.svg diff --git a/elements/app-hax/lib/assets/images/DMBackgroundImage.svg b/elements/app-hax/lib/assets/images/DMBackgroundImage.svg deleted file mode 100644 index d71bfb600e..0000000000 --- a/elements/app-hax/lib/assets/images/DMBackgroundImage.svg +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/elements/app-hax/lib/assets/images/LMBackgroundImage.svg b/elements/app-hax/lib/assets/images/LMBackgroundImage.svg deleted file mode 100644 index bd14a7f544..0000000000 --- a/elements/app-hax/lib/assets/images/LMBackgroundImage.svg +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/elements/app-hax/lib/v2/app-hax-search-results.js b/elements/app-hax/lib/v2/app-hax-search-results.js index fa2d05675b..26ad6f0386 100644 --- a/elements/app-hax/lib/v2/app-hax-search-results.js +++ b/elements/app-hax/lib/v2/app-hax-search-results.js @@ -89,7 +89,7 @@ export class AppHaxSearchResults extends SimpleColors { background: var(--app-hax-accent-color, black); color: white; border: none; - padding: 10px; + padding: 20px; cursor: pointer; height: 240px; opacity: 50%; diff --git a/elements/app-hax/lib/v2/app-hax-site-bar.js b/elements/app-hax/lib/v2/app-hax-site-bar.js index 07deb11a2d..024a2d4b7f 100644 --- a/elements/app-hax/lib/v2/app-hax-site-bar.js +++ b/elements/app-hax/lib/v2/app-hax-site-bar.js @@ -77,6 +77,7 @@ export class AppHaxSiteBars extends SimpleColors { outline: 5px solid var(--simple-colors-default-theme-light-blue-4); outline-offset: -5px; border-radius: 8px; + box-shadow: var(--ddd-boxShadow-lg); } .imageLink img{ display: block; diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index e72e978ffa..4f9a9adf1a 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -64,6 +64,7 @@ export class AppHaxUseCaseFilter extends LitElement { display: flex; justify-content: flex-start; align-items: flex-start; + flex-wrap: wrap; } app-hax-search-results { display: flex; diff --git a/elements/app-hax/lib/v2/app-hax-use-case.js b/elements/app-hax/lib/v2/app-hax-use-case.js index 7ac8cce5ff..6bd91ac768 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case.js +++ b/elements/app-hax/lib/v2/app-hax-use-case.js @@ -49,14 +49,14 @@ export class AppHaxUseCase extends LitElement { color: var(--ddd-theme-default-nittanyNavy); background-color: white; min-height: 270px; - box-shadow: var(--ddd-boxShadow-md); + box-shadow: var(--ddd-boxShadow-lg); border-radius: 8px; } .image img { - width: 100%; + width: 240px; + height: 142px; border-top-right-radius: 8px; border-top-left-radius: 8px; - height: 125px; border-bottom: solid var(--ddd-theme-default-nittanyNavy) 12px; overflow: clip; justify-self: center; @@ -79,8 +79,8 @@ export class AppHaxUseCase extends LitElement { } .icons { position: absolute; - bottom: 15px; - left: 50%; + bottom: 16px; + left: 27%; transform: translateX(-50%); display: flex; gap: 8px; @@ -116,7 +116,7 @@ export class AppHaxUseCase extends LitElement { display: block; } h3, p { - margin: 8px; + margin: 4px; } p { font-size: 12px; @@ -125,7 +125,7 @@ export class AppHaxUseCase extends LitElement { color: var(--ddd-theme-defaut-skyBlue); text-decoration: none; font-family: var(--ddd-font-primary); - font-size: 12px; + font-size: 16px; } button { display: flex; @@ -137,7 +137,7 @@ export class AppHaxUseCase extends LitElement { font-size: 12px; font-weight: 20px; padding: 8px; - margin: 0px 2px 0px 2px; + margin: 0px 4px 0px 4px; height: 16px; align-items: center; justify-content: center; @@ -146,7 +146,7 @@ export class AppHaxUseCase extends LitElement { display: flex; justify-content: space-between; align-items: center; - margin-top: 8px; + margin-top: 16px; } .cardBottom button, .cardBottom a { From 5aa8c31cf9bd9386c38c0b52a674047ba6998663 Mon Sep 17 00:00:00 2001 From: Skyler Koba Date: Thu, 27 Mar 2025 12:57:42 -0400 Subject: [PATCH 071/166] Add files via upload --- .../lib/assets/images/DMBackgroundImage.svg | 88 ++++++++++++++++++ .../lib/assets/images/LMBackgroundImage.svg | 90 +++++++++++++++++++ 2 files changed, 178 insertions(+) create mode 100644 elements/app-hax/lib/assets/images/DMBackgroundImage.svg create mode 100644 elements/app-hax/lib/assets/images/LMBackgroundImage.svg diff --git a/elements/app-hax/lib/assets/images/DMBackgroundImage.svg b/elements/app-hax/lib/assets/images/DMBackgroundImage.svg new file mode 100644 index 0000000000..999cf8de68 --- /dev/null +++ b/elements/app-hax/lib/assets/images/DMBackgroundImage.svg @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/elements/app-hax/lib/assets/images/LMBackgroundImage.svg b/elements/app-hax/lib/assets/images/LMBackgroundImage.svg new file mode 100644 index 0000000000..5fba01d7f3 --- /dev/null +++ b/elements/app-hax/lib/assets/images/LMBackgroundImage.svg @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 2c030a12070640c880b7a6a99b2081bbc8ce0de3 Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Thu, 27 Mar 2025 13:08:39 -0400 Subject: [PATCH 072/166] carousel --- elements/app-hax/demo/index.html | 4 +--- elements/app-hax/lib/v2/app-hax-search-results.js | 13 ++++++------- elements/app-hax/lib/v2/app-hax-site-bar.js | 4 ++-- elements/app-hax/lib/v2/app-hax-use-case-filter.js | 4 ++-- 4 files changed, 11 insertions(+), 14 deletions(-) diff --git a/elements/app-hax/demo/index.html b/elements/app-hax/demo/index.html index c91e5a5ddf..f8e9351ea1 100644 --- a/elements/app-hax/demo/index.html +++ b/elements/app-hax/demo/index.html @@ -58,9 +58,7 @@ body.app-loaded:not(.bad-device) { background-image: url('../lib/assets/images/LMBackgroundImage.svg'), url('../lib/assets/images/DesignLightModeLeft.svg'), url('../lib/assets/images/DesignLightModeRight.svg'); background-position: top; - background-repeat: repeat; - /*background-blend-mode: normal;*/ - background-size: auto, 20% auto, 20% auto; + background-size: auto; } div[slot="externalproviders"] { diff --git a/elements/app-hax/lib/v2/app-hax-search-results.js b/elements/app-hax/lib/v2/app-hax-search-results.js index 26ad6f0386..b7f6a6ce62 100644 --- a/elements/app-hax/lib/v2/app-hax-search-results.js +++ b/elements/app-hax/lib/v2/app-hax-search-results.js @@ -89,7 +89,7 @@ export class AppHaxSearchResults extends SimpleColors { background: var(--app-hax-accent-color, black); color: white; border: none; - padding: 20px; + padding: 16px; cursor: pointer; height: 240px; opacity: 50%; @@ -102,12 +102,11 @@ export class AppHaxSearchResults extends SimpleColors { overflow-x: auto; overflow-y: hidden; scroll-snap-type: x mandatory; - gap: 36px; + gap: 20px; white-space: nowrap; scrollbar-width: none; -ms-overflow-style: none; - padding: 16px; - scroll-padding-left: 16px; + padding: 4px; } #results::-webkit-scrollbar { @@ -117,7 +116,7 @@ export class AppHaxSearchResults extends SimpleColors { li { flex: 0 0 auto; scroll-snap-align: center; - width: 240px; + width: 220px; height: 300px; display: flex; flex-direction: column; @@ -219,11 +218,11 @@ export class AppHaxSearchResults extends SimpleColors { } scrollLeft() { - this.shadowRoot.querySelector("#results").scrollBy({ left: -250, behavior: "smooth" }); + this.shadowRoot.querySelector("#results").scrollBy({ left: -750, behavior: "smooth" }); } scrollRight() { - this.shadowRoot.querySelector("#results").scrollBy({ left: 250, behavior: "smooth" }); + this.shadowRoot.querySelector("#results").scrollBy({ left: 750, behavior: "smooth" }); } getItemDetails(item) { diff --git a/elements/app-hax/lib/v2/app-hax-site-bar.js b/elements/app-hax/lib/v2/app-hax-site-bar.js index 024a2d4b7f..b8eb830149 100644 --- a/elements/app-hax/lib/v2/app-hax-site-bar.js +++ b/elements/app-hax/lib/v2/app-hax-site-bar.js @@ -68,7 +68,7 @@ export class AppHaxSiteBars extends SimpleColors { super.styles, css` :host { - --main-banner-width: 240px; + --main-banner-width: 220px; --main-banner-height: 220px; --band-banner-height: 220px; display: block; @@ -81,7 +81,7 @@ export class AppHaxSiteBars extends SimpleColors { } .imageLink img{ display: block; - width: 240px; + width: 216px; height: 125px; overflow: clip; justify-self: center; diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index 4f9a9adf1a..502db53865 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -70,7 +70,7 @@ export class AppHaxUseCaseFilter extends LitElement { display: flex; justify-content: flex-start; align-items: flex-start; - width: 800px; + width: 816px; } .reset-button { display: flex; @@ -80,7 +80,7 @@ export class AppHaxUseCaseFilter extends LitElement { align-items: center; justify-content: center; padding: 8px; - margin-top: 16px; + margin-top: 36px; } h4 { font-family: var(--ddd-font-primary); From 495bbdcf8e4f916706b169b7d59aa6b2f624738e Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Tue, 1 Apr 2025 11:49:54 -0400 Subject: [PATCH 073/166] fixed site details overlay --- elements/app-hax/lib/v2/app-hax-site-bar.js | 34 +++++++++++++++---- .../app-hax/lib/v2/app-hax-site-details.js | 22 +++++++----- elements/app-hax/lib/v2/app-hax-use-case.js | 6 +++- 3 files changed, 46 insertions(+), 16 deletions(-) diff --git a/elements/app-hax/lib/v2/app-hax-site-bar.js b/elements/app-hax/lib/v2/app-hax-site-bar.js index b8eb830149..0256c76cc6 100644 --- a/elements/app-hax/lib/v2/app-hax-site-bar.js +++ b/elements/app-hax/lib/v2/app-hax-site-bar.js @@ -5,7 +5,6 @@ import "@haxtheweb/simple-icon/lib/simple-icons.js"; import "@haxtheweb/simple-icon/lib/simple-icon-button-lite"; import { SimpleColors } from "@haxtheweb/simple-colors/simple-colors.js"; import "@haxtheweb/simple-tooltip/simple-tooltip.js"; -import { animate } from "@lit-labs/motion"; const DropDownBorder = new URL( "../assets/images/DropDownBorder.svg", @@ -78,6 +77,7 @@ export class AppHaxSiteBars extends SimpleColors { outline-offset: -5px; border-radius: 8px; box-shadow: var(--ddd-boxShadow-lg); + position: relative; } .imageLink img{ display: block; @@ -124,16 +124,36 @@ export class AppHaxSiteBars extends SimpleColors { padding: 2px 4px; } - #band-container { - display: block; + #overlay { + display: flex; + position: absolute; + top: 0; + left: 0; visibility: hidden; + justify-content: center; + align-items: center; height: 1px; width: var(--main-banner-width); + z-index: 999; + } + #closeButton { + position: absolute; + top: 10px; + right: 5px; + background: var(--simple-colors-default-theme-light-blue-1, var(--simple-colors-default-theme-light-blue-11)); + color: var(--simple-colors-default-theme-light-blue-11, var(--simple-colors-default-theme-light-blue-1)); + border: none; + font-size: 12px; + cursor: pointer; + z-index: 1001; + border-radius: 100; } - :host([opened]) #band-container { - height: var(--band-banner-height); + :host([opened]) #overlay { + height: var(--main-banner-height); visibility: visible; + width: 100%; + height: 100%; } a { flex: 1; @@ -196,9 +216,11 @@ export class AppHaxSiteBars extends SimpleColors {
-
+
+
+ Access site More options `; diff --git a/elements/app-hax/lib/v2/app-hax-site-details.js b/elements/app-hax/lib/v2/app-hax-site-details.js index 2f736d74b0..f18dea42a4 100644 --- a/elements/app-hax/lib/v2/app-hax-site-details.js +++ b/elements/app-hax/lib/v2/app-hax-site-details.js @@ -76,13 +76,16 @@ export class AppHaxSiteDetails extends SimpleColors { justify-content: center; font-size: 12px; align-items: stretch; - background-color: var(--simple-colors-default-theme-grey-2); + background-color: var(--simple-colors-default-theme-light-blue-11); + color: var(--simple-colors-default-theme-light-blue-1); + max-width: 220px; height: 208px; + border-radius: 8px; } .flex-container { flex: 1; - background-color: var(--simple-colors-default-theme-grey-2); + background-color: var(--simple-colors-default-theme-light-blue-11); margin: 8px; display: flex; flex-direction: row; @@ -102,8 +105,8 @@ export class AppHaxSiteDetails extends SimpleColors { simple-icon-button-lite:active, simple-icon-button-lite:hover, simple-icon-button-lite:focus { - background-color: var(--simple-colors-default-theme-grey-4, #eeeeee); - outline: 2px solid var(--simple-colors-default-theme-grey-12); + background-color: var(--simple-colors-default-theme-light-blue-8, #cde8ff); + outline: 2px solid var(--simple-colors-default-theme-light-blue-1); outline-offset: 1px; } @@ -111,14 +114,14 @@ export class AppHaxSiteDetails extends SimpleColors { font-size: 12px; } .info-item { - font-family: "Press Start 2P", sans-serif; + font-family: sans-serif; display: block; text-overflow: ellipsis; overflow: hidden; - color: var(--simple-colors-default-theme-grey-12); + color: var(--simple-colors-default-theme-light-blue-1); line-height: 12px; max-width: 100%; - font-size: 12px; + font-size: 14px; } .pre ::slotted(*) { padding: 12px; @@ -131,7 +134,7 @@ export class AppHaxSiteDetails extends SimpleColors { text-decoration: underline; } .info-date { - color: var(--simple-colors-default-theme-grey-12); + color: var(--simple-colors-default-theme-light-blue-1); line-height: 12px; font-size: 12px; } @@ -142,7 +145,7 @@ export class AppHaxSiteDetails extends SimpleColors { --simple-icon-button-border-radius: 0px; --simple-icon-button-border: 0px; outline: 0; - border: 2px solid var(--simple-colors-default-theme-grey-12); + border: 2px solid var(--simple-colors-default-theme-light-blue-1); border-radius: 4px; padding: 4px; width: 80%; @@ -253,6 +256,7 @@ export class AppHaxSiteDetails extends SimpleColors { elements: { content: div, buttons: bcontainer }, invokedBy: target, styles: { + "font-weight": "bold", "--simple-modal-titlebar-background": "orange", "--simple-modal-titlebar-color": "black", "--simple-modal-width": "30vw", diff --git a/elements/app-hax/lib/v2/app-hax-use-case.js b/elements/app-hax/lib/v2/app-hax-use-case.js index 6bd91ac768..a9f038a7bb 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case.js +++ b/elements/app-hax/lib/v2/app-hax-use-case.js @@ -181,7 +181,11 @@ export class AppHaxUseCase extends LitElement { } continueAction() { - this.dispatchEvent(new CustomEvent('continue-action')); + window.confirm("Are you sure?"); + if (confirm("Are you sure?")) { + this.dispatchEvent(new CustomEvent('continue-action')); + } + } render() { From 237d16e10a4e10acf122a5b2bf9ac6e928e1be35 Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Tue, 1 Apr 2025 12:25:10 -0400 Subject: [PATCH 074/166] fixed search bar for existing sites --- elements/app-hax/lib/v2/app-hax-search-bar.js | 52 +++++++------------ .../app-hax/lib/v2/app-hax-site-details.js | 1 - .../app-hax/lib/v2/app-hax-use-case-filter.js | 16 +++--- elements/app-hax/lib/v2/app-hax-use-case.js | 1 - 4 files changed, 29 insertions(+), 41 deletions(-) diff --git a/elements/app-hax/lib/v2/app-hax-search-bar.js b/elements/app-hax/lib/v2/app-hax-search-bar.js index 7806cf9878..143d1f91ef 100644 --- a/elements/app-hax/lib/v2/app-hax-search-bar.js +++ b/elements/app-hax/lib/v2/app-hax-search-bar.js @@ -45,23 +45,19 @@ export class AppHaxSearchBar extends LitElement { css` :host { overflow: hidden; + position: relative; + display: inline-block; } input { - visibility: none; - opacity: 0; - width: 0; + opacity: 1; + width: 750px; transition: all ease-in-out 0.3s; padding: 4px; - font-family: "Press Start 2P", sans-serif; - font-size: 20px; + padding-left: 35px; + font-family: sans-serif; + font-size: 16px; margin: 2px 0 0 16px; } - :host([show-search]) input { - visibility: visible; - opacity: 1; - width: 250px; - max-width: 25vw; - } @media (max-width: 780px) { :host([show-search]) input { width: 250px; @@ -101,6 +97,14 @@ export class AppHaxSearchBar extends LitElement { simple-toolbar-button:focus { --simple-toolbar-border-color: var(--hax-ui-color-accent); } + .search-icon { + position: absolute; + left: 24px; + top: 50%; + transform: translateY(-50%); + font-size: 16px; + align-self: center; + } `, ]; } @@ -111,32 +115,21 @@ export class AppHaxSearchBar extends LitElement { } // eslint-disable-next-line class-methods-use-this search() { - store.appEl.playSound("click"); this.searchTerm = this.shadowRoot.querySelector("#searchField").value; } render() { return html` - - Toggle Search + + + `; } @@ -144,11 +137,6 @@ export class AppHaxSearchBar extends LitElement { toggleSearch() { if (!this.disabled) { this.shadowRoot.querySelector("#searchField").value = ""; - store.appEl.playSound("click"); - this.showSearch = !this.showSearch; - setTimeout(() => { - this.shadowRoot.querySelector("#searchField").focus(); - }, 300); } } } diff --git a/elements/app-hax/lib/v2/app-hax-site-details.js b/elements/app-hax/lib/v2/app-hax-site-details.js index f18dea42a4..a92503d41e 100644 --- a/elements/app-hax/lib/v2/app-hax-site-details.js +++ b/elements/app-hax/lib/v2/app-hax-site-details.js @@ -256,7 +256,6 @@ export class AppHaxSiteDetails extends SimpleColors { elements: { content: div, buttons: bcontainer }, invokedBy: target, styles: { - "font-weight": "bold", "--simple-modal-titlebar-background": "orange", "--simple-modal-titlebar-color": "black", "--simple-modal-width": "30vw", diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index 502db53865..467516d383 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -210,17 +210,11 @@ export class AppHaxUseCaseFilter extends LitElement {
-
- ${this.activeFilters.map( - (filter) => html` - - ` - )} -

Return to...

+
@@ -228,6 +222,14 @@ export class AppHaxUseCaseFilter extends LitElement {

Start New Journey

+ +
+ ${this.activeFilters.map( + (filter) => html` + + ` + )} +
${this.filteredItems.length > 0 diff --git a/elements/app-hax/lib/v2/app-hax-use-case.js b/elements/app-hax/lib/v2/app-hax-use-case.js index a9f038a7bb..c2d46397ce 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case.js +++ b/elements/app-hax/lib/v2/app-hax-use-case.js @@ -181,7 +181,6 @@ export class AppHaxUseCase extends LitElement { } continueAction() { - window.confirm("Are you sure?"); if (confirm("Are you sure?")) { this.dispatchEvent(new CustomEvent('continue-action')); } From 155de30a6266ad4ed9e160c807caf9e690e4a026 Mon Sep 17 00:00:00 2001 From: izzabizz5 Date: Tue, 1 Apr 2025 12:25:49 -0400 Subject: [PATCH 075/166] search bar --- elements/app-hax/app-hax.js | 4 - elements/app-hax/lib/v2/app-hax-search-bar.js | 75 ++----------------- .../app-hax/lib/v2/app-hax-use-case-filter.js | 5 +- elements/app-hax/src/app-hax.js | 4 - 4 files changed, 12 insertions(+), 76 deletions(-) diff --git a/elements/app-hax/app-hax.js b/elements/app-hax/app-hax.js index fc6efc2d09..e0571ea086 100644 --- a/elements/app-hax/app-hax.js +++ b/elements/app-hax/app-hax.js @@ -1146,10 +1146,6 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} data-event="super-daemon" show-text-label > - - Toggle Search { - this.shadowRoot.querySelector("#searchField").focus(); - }, 300); - } - } } customElements.define(AppHaxSearchBar.tag, AppHaxSearchBar); diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index 502db53865..b64dd6d815 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -6,6 +6,7 @@ import "./app-hax-use-case.js"; import "./app-hax-search-results.js"; import "./app-hax-filter-tag.js"; import "./app-hax-scroll-button.js"; +import "./app-hax-search-bar.js"; export class AppHaxUseCaseFilter extends LitElement { // a convention I enjoy so you can change the tag name in 1 place @@ -124,7 +125,7 @@ export class AppHaxUseCaseFilter extends LitElement { .filter { position: absolute; left: 16px; - height: 300px; + height: auto; justify-self: flex-start; display:flex; background-color: var(--simple-colors-default-theme-accent-1, var(--accent-color)); @@ -176,6 +177,8 @@ export class AppHaxUseCaseFilter extends LitElement {
+ + diff --git a/elements/app-hax/src/app-hax.js b/elements/app-hax/src/app-hax.js index fc6efc2d09..e0571ea086 100644 --- a/elements/app-hax/src/app-hax.js +++ b/elements/app-hax/src/app-hax.js @@ -1146,10 +1146,6 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} data-event="super-daemon" show-text-label > - Date: Tue, 1 Apr 2025 12:42:52 -0400 Subject: [PATCH 076/166] fixed colors and spacing --- elements/app-hax/lib/v2/app-hax-filter-tag.js | 4 ++-- elements/app-hax/lib/v2/app-hax-use-case-filter.js | 11 +++++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/elements/app-hax/lib/v2/app-hax-filter-tag.js b/elements/app-hax/lib/v2/app-hax-filter-tag.js index dc0cd9f493..bfbc12855c 100644 --- a/elements/app-hax/lib/v2/app-hax-filter-tag.js +++ b/elements/app-hax/lib/v2/app-hax-filter-tag.js @@ -31,11 +31,11 @@ export class AppHaxFilterTag extends LitElement { :host { display: inline-flex; font-family: var(--ddd-font-primary); - color: white; + color: var(--simple-colors-default-theme-grey-1, var(--accent-color)); padding-left: 8px; padding-right: 8px; height: 32px; - background-color: black; + background-color: var(--app-hax-accent-color, var(--accent-color)); border-radius: 8px; font-size: 16px; align-items: center; diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index 467516d383..4e855f3cb5 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -71,6 +71,7 @@ export class AppHaxUseCaseFilter extends LitElement { justify-content: flex-start; align-items: flex-start; width: 816px; + z-index: 5; } .reset-button { display: flex; @@ -89,13 +90,17 @@ export class AppHaxUseCaseFilter extends LitElement { margin: 16px; } .startNew, .returnTo { - display: inline-flex; + padding-top: 40px; + position: relative; + display: flex; flex-direction: column; justify-content: flex-start; align-items: flex-start; margin-left: 48px; margin-right: 48px; - + } + .startNew h4, .returnTo h4 { + flex-shrink: 0; } input[type="text"]{ opacity: 1; @@ -180,8 +185,6 @@ export class AppHaxUseCaseFilter extends LitElement { Date: Tue, 8 Apr 2025 11:41:00 -0400 Subject: [PATCH 077/166] icons and tooltip looking prrreeeetty good now --- elements/app-hax/lib/v2/app-hax-recipes.json | 2 +- elements/app-hax/lib/v2/app-hax-search-bar.js | 51 +++++------ .../app-hax/lib/v2/app-hax-use-case-filter.js | 7 +- elements/app-hax/lib/v2/app-hax-use-case.js | 88 ++++++++++++------- 4 files changed, 78 insertions(+), 70 deletions(-) diff --git a/elements/app-hax/lib/v2/app-hax-recipes.json b/elements/app-hax/lib/v2/app-hax-recipes.json index 47b2373a60..fa0850dbc7 100644 --- a/elements/app-hax/lib/v2/app-hax-recipes.json +++ b/elements/app-hax/lib/v2/app-hax-recipes.json @@ -19,7 +19,7 @@ { "icon": "icons:favorite", "tooltip": "Mark as Favorite" }, { "icon": "icons:language", "tooltip": "Translatable"}, { "icon": "icons:thumb-up", "tooltip": "Popular"}, - { "icon": "icons:accessibility", "tooltip": "Accessible"} + { "icon": "icons:accessibility", "tooltip": "Accessible"} ] }, { diff --git a/elements/app-hax/lib/v2/app-hax-search-bar.js b/elements/app-hax/lib/v2/app-hax-search-bar.js index be4167f9a5..b7a9ec7cf4 100644 --- a/elements/app-hax/lib/v2/app-hax-search-bar.js +++ b/elements/app-hax/lib/v2/app-hax-search-bar.js @@ -12,6 +12,8 @@ export class AppHaxSearchBar extends LitElement { constructor() { super(); this.searchTerm = ""; + this.disabled = false; + this.showSearch = false; } // Site.json is coming from @@ -19,6 +21,8 @@ export class AppHaxSearchBar extends LitElement { static get properties() { return { searchTerm: { type: String }, + showSearch: { type: Boolean, reflect: true, attribute: "show-search" }, + disabled: { type: Boolean, reflect: true }, }; } @@ -45,21 +49,15 @@ export class AppHaxSearchBar extends LitElement { display: inline-block; } input { - visibility: none; - opacity: 0; - width: 0; + opacity: 1; + width: 750px; transition: all ease-in-out 0.3s; padding: 4px; - font-family: "Press Start 2P", sans-serif; - font-size: 20px; + padding-left: 35px; + font-family: sans-serif; + font-size: 16px; margin: 2px 0 0 16px; } - :host([show-search]) input { - visibility: visible; - opacity: 1; - width: 250px; - max-width: 25vw; - } @media (max-width: 780px) { :host([show-search]) input { width: 250px; @@ -99,6 +97,14 @@ export class AppHaxSearchBar extends LitElement { simple-toolbar-button:focus { --simple-toolbar-border-color: var(--hax-ui-color-accent); } + .search-icon { + position: absolute; + left: 24px; + top: 50%; + transform: translateY(-50%); + font-size: 16px; + align-self: center; + } `, ]; } @@ -114,19 +120,9 @@ export class AppHaxSearchBar extends LitElement { render() { return html` - - Toggle Search + + + { - this.shadowRoot.querySelector("#searchField").focus(); - }, 300); } } } -customElements.define(AppHaxSearchBar.tag, AppHaxSearchBar); +customElements.define(AppHaxSearchBar.tag, AppHaxSearchBar); \ No newline at end of file diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index 6472ac3362..eb6d2acf48 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -182,8 +182,6 @@ export class AppHaxUseCaseFilter extends LitElement {
- - @@ -260,12 +258,9 @@ export class AppHaxUseCaseFilter extends LitElement { ` ) : html`

No templates match the filters specified.

`} +
- -
- -
`; diff --git a/elements/app-hax/lib/v2/app-hax-use-case.js b/elements/app-hax/lib/v2/app-hax-use-case.js index c2d46397ce..965c98b8a2 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case.js +++ b/elements/app-hax/lib/v2/app-hax-use-case.js @@ -65,42 +65,45 @@ export class AppHaxUseCase extends LitElement { position: relative; display: inline-block; } - #haxicons { - position: absolute; - bottom: var(--ddd-spacing-2); - left: var(--ddd-spacing-2); - padding: var(--ddd-spacing-1) var(--ddd-spacing-1); - opacity: 0.8; - gap: var(--ddd-spacing-3); - color: var(--ddd-primary-8); - position: absolute; - width: 40px; /* Adjust size as needed */ - display: flex; - } .icons { position: absolute; - bottom: 16px; - left: 27%; - transform: translateX(-50%); + bottom: 18px; + left: 10px; display: flex; - gap: 8px; + gap: 6px; + z-index: 10; } .icon-wrapper { position: relative; + width: 32px; + height: 32px; + flex-shrink: 0; + display: flex; + align-items: center; + justify-content: center; + } + .icon-wrapper::before { + content: ''; + position: absolute; + width: 100%; + height: 100%; + background-color: white; + border-radius: 50%; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); } .tooltip-container { display: none; flex-direction: column; position: absolute; - top: 100%; - left: 50%; - transform: translateX(-50%); + top: 32px; + left: 0; /* Align with first icon */ background-color: white; color: black; padding: 8px; border-radius: 6px; box-shadow: rgba(0, 0, 0, 0.2) 0px 4px 6px; width: max-content; + z-index: 20; } .tooltip { font-size: 12px; @@ -115,6 +118,22 @@ export class AppHaxUseCase extends LitElement { .icons:hover .tooltip-container { display: block; } + .tooltip-row { + display: flex; + align-items: center; + gap: 8px; + padding: 4px 8px; + border-bottom: 1px solid #ccc; + } + + .tooltip-row:last-child { + border-bottom: none; + } + + .tooltip-icon { + width: 20px; + height: 20px; + } h3, p { margin: 4px; } @@ -189,31 +208,34 @@ export class AppHaxUseCase extends LitElement { render() { return html` -
-
- - ${this.title} -
+
+
+ + ${this.title} +
+ ${this.iconImage.map( + (icon) => html` +
+ +
+ ` + )} +
${this.iconImage.map( (icon) => html` -
- +
+ +
${icon.tooltip}
` )} -
- ${this.iconImage.map( - (icon) => html`
${icon.tooltip}
` - )} -
+

${this.title}

-

${this.description}

-
@@ -218,7 +216,6 @@ export class AppHaxUseCaseFilter extends LitElement {

Return to...

-
@@ -303,20 +300,28 @@ export class AppHaxUseCaseFilter extends LitElement { } handleSearch(event) { - this.searchQuery = event.target.value.toLowerCase(); - - const matchingFilter = this.filters.find(filter => - filter.toLowerCase() === this.searchQuery + const searchTerm = event.target.value.toLowerCase(); + this.searchTerm = searchTerm; + store.searchTerm = searchTerm; // Update store with search term + + // Filter templates + this.filteredItems = this.items.filter(item => + item.useCaseTitle.toLowerCase().includes(searchTerm) || + item.useCaseTag.some(tag => tag.toLowerCase().includes(searchTerm)) ); - - const checkbox = this.shadowRoot.querySelector(`input[value="${matchingFilter}"]`); - if (checkbox) { - checkbox.checked = true; + + // Filter returning sites (assuming you have access to sites data) + if (this.returningSites) { + this.filteredSites = this.returningSites.filter(site => + site.title.toLowerCase().includes(searchTerm) + ); } - - this.applyFilters(); + + this.requestUpdate(); } + + toggleFilter(event) { const filterValue = event.target.value; @@ -329,24 +334,28 @@ export class AppHaxUseCaseFilter extends LitElement { } applyFilters() { - const lowerCaseQuery = this.searchQuery.toLowerCase(); + const lowerCaseQuery = this.searchTerm.toLowerCase(); - console.log("Active Filters:", this.activeFilters); - + // Combined filter logic this.filteredItems = this.items.filter((item) => { const matchesSearch = lowerCaseQuery === "" || item.useCaseTitle.toLowerCase().includes(lowerCaseQuery) || - item.useCaseTag.some(tag => tag.toLowerCase() === lowerCaseQuery); - + item.useCaseTag.some(tag => tag.toLowerCase().includes(lowerCaseQuery)); + const matchesFilters = this.activeFilters.length === 0 || - this.activeFilters.some(filter => - item.useCaseTag.includes(filter)); - + this.activeFilters.some(filter => item.useCaseTag.includes(filter)); + return matchesSearch && matchesFilters; - }); - this.requestUpdate(); + }); + + // Update search results in store + store.searchResults = { + templates: this.filteredItems, + sites: this.filteredSites || [] + }; } + removeFilter(event) { const filterToRemove = event.detail; this.activeFilters = this.activeFilters.filter((f) => f !== filterToRemove); @@ -355,23 +364,23 @@ export class AppHaxUseCaseFilter extends LitElement { } resetFilters() { - this.searchQuery = ""; - this.activeFilters = []; // Clear active filters - this.filteredItems = this.items; // Reset to show all items - this.requestUpdate(); // Trigger an update - - // Uncheck checkboxes - const checkboxes = this.shadowRoot.querySelectorAll( - '.filterButtons input[type="checkbox"]' - ); - checkboxes.forEach((checkbox) => (checkbox.checked = false)); - - // Clear search bar - const searchInput = this.shadowRoot.querySelector('#searchField'); - if (searchInput) { - searchInput.value = ""; + this.searchTerm = ""; + store.searchTerm = ""; + this.activeFilters = []; + this.filteredItems = this.items; + + if (this.returningSites) { + this.filteredSites = this.returningSites; } + + // Clear UI elements + this.shadowRoot.querySelector("#searchField").value = ""; + this.shadowRoot.querySelectorAll('input[type="checkbox"]').forEach(cb => cb.checked = false); + + this.requestUpdate(); } + + updateResults() { this.loading = true; From c346c4f13cceeedaa5f91a95cd824f621a9a824a Mon Sep 17 00:00:00 2001 From: izzabizz5 Date: Tue, 8 Apr 2025 12:59:53 -0400 Subject: [PATCH 079/166] fixed sizing issues --- .../app-hax/lib/v2/app-hax-use-case-filter.js | 188 +++++++++--------- 1 file changed, 96 insertions(+), 92 deletions(-) diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index 530a3c3013..4510515b40 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -56,9 +56,20 @@ export class AppHaxUseCaseFilter extends LitElement { display: block; width: 100%; } - .rightSection{ + .contentSection { + display: flex; + align-items: flex-start; + justify-content: flex-start; + gap: 16px; + width: 100%; + } + .leftSection { + display: block; + width: 460px; + margin-left: 12px; + } + .rightSection { display: block; - margin-left: 336px; } .results { display: flex; @@ -119,7 +130,7 @@ export class AppHaxUseCaseFilter extends LitElement { display: inline-block; } .search-icon { - position: absolute; + position: absolute; left: 12px; top: 50%; transform: translateY(-50%); @@ -127,11 +138,10 @@ export class AppHaxUseCaseFilter extends LitElement { align-self: center; } .filter { - position: absolute; - left: 16px; - height: auto; - justify-self: flex-start; - display:flex; + position: sticky; + top: 0; + height: 280px; + display: flex; background-color: var(--simple-colors-default-theme-accent-1, var(--accent-color)); color: var(--simple-colors-default-theme-accent-12, var(--accent-color)); border-radius: 8px; @@ -162,9 +172,6 @@ export class AppHaxUseCaseFilter extends LitElement { input[type="checkbox"] { width: 30px; } - .newJourneySection { - display: inline-flex; - } `, ]; } @@ -177,91 +184,88 @@ export class AppHaxUseCaseFilter extends LitElement { render() { return html` -
-
- -
- - - - - -
-
- ${this.filters.map( - (filter) => html` - - ` - )} -
- -
- -
- - -
-

Return to...

- -
- - - -
-

Start New Journey

- -
- ${this.activeFilters.map( - (filter) => html` - - ` - )} -
-
- - ${this.filteredItems.length > 0 - ? this.filteredItems.map( - (item, index) => html` -
- - this.toggleDisplay(index, e)} - @continue-action=${() => this.continueAction(index)} - > - +
+
+
+ +
+ + + + +
+ +
+ ${this.filters.map( + (filter) => html` + + ` + )} +
+
- ` - ) - : html`

No templates match the filters specified.

`} +
+ +
+ +
+

Return to...

+ +
+ + +
+

Start New Journey

+
+ ${this.activeFilters.map( + (filter) => html` + + ` + )} +
+
+ ${this.filteredItems.length > 0 + ? this.filteredItems.map( + (item, index) => html` +
+ + this.toggleDisplay(index, e)} + @continue-action=${() => this.continueAction(index)} + > +
+ ` + ) + : html`

No templates match the filters specified.

`} +
+
+
-
-
-
- `; } + firstUpdated() { super.firstUpdated(); From 6f0df4787aac1eb85f5ea81df53a4d305a5ae185 Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Thu, 10 Apr 2025 12:17:40 -0400 Subject: [PATCH 080/166] professional return cards --- .../app-hax/lib/v2/app-hax-search-results.js | 7 - elements/app-hax/lib/v2/app-hax-site-bar.js | 283 +++++++++--------- .../app-hax/lib/v2/app-hax-use-case-filter.js | 39 ++- 3 files changed, 184 insertions(+), 145 deletions(-) diff --git a/elements/app-hax/lib/v2/app-hax-search-results.js b/elements/app-hax/lib/v2/app-hax-search-results.js index b7f6a6ce62..2a50985045 100644 --- a/elements/app-hax/lib/v2/app-hax-search-results.js +++ b/elements/app-hax/lib/v2/app-hax-search-results.js @@ -174,7 +174,6 @@ export class AppHaxSearchResults extends SimpleColors { (item) => html`
  • ${item.title} ${item.author} diff --git a/elements/app-hax/lib/v2/app-hax-site-bar.js b/elements/app-hax/lib/v2/app-hax-site-bar.js index 0256c76cc6..d8327ae8bc 100644 --- a/elements/app-hax/lib/v2/app-hax-site-bar.js +++ b/elements/app-hax/lib/v2/app-hax-site-bar.js @@ -21,44 +21,47 @@ export class AppHaxSiteBars extends SimpleColors { // HTMLElement life-cycle, built in; use this for setting defaults constructor() { super(); - this.icon = "link"; - this.opened = false; + this.showOptions = false; this.inprogress = false; - this.iconLink = "/"; this.textInfo = {}; this.siteId = ""; + this.description = ''; } // properties that you wish to use as data in HTML, CSS, and the updated life-cycle static get properties() { return { ...super.properties, - opened: { type: Boolean, reflect: true }, - icon: { type: String }, + showOptions: { type: Boolean }, inprogress: { type: Boolean, reflect: true }, - iconLink: { type: String, attribute: "icon-link" }, textInfo: { type: Object }, siteId: { type: String, reflect: true, attribute: "site-id" }, + title: { type: String }, + description: { type: String }, }; } // updated fires every time a property defined above changes // this allows you to react to variables changing and use javascript to perform logic updated(changedProperties) { - if (super.updated) { - super.updated(changedProperties); - } - changedProperties.forEach((oldValue, propName) => { - if (propName === "opened" && oldValue !== undefined) { - this.dispatchEvent( - new CustomEvent(`${propName}-changed`, { - detail: { - value: this[propName], - }, - }), - ); - } - }); + } + + toggleOptionsMenu() { + this.showOptions = !this.showOptions; + } + copySite() { + console.log("Copy clicked"); + // implement logic + } + + downloadSite() { + console.log("Download clicked"); + // implement logic + } + + archiveSite() { + console.log("Archive clicked"); + // implement logic } // CSS - specific to Lit @@ -67,128 +70,106 @@ export class AppHaxSiteBars extends SimpleColors { super.styles, css` :host { - --main-banner-width: 220px; - --main-banner-height: 220px; - --band-banner-height: 220px; - display: block; - background-color: var(--simple-colors-default-theme-light-blue-3); - color: var(--simple-colors-default-theme-grey-3); - outline: 5px solid var(--simple-colors-default-theme-light-blue-4); - outline-offset: -5px; - border-radius: 8px; + text-align: left; + max-width: 240px; + margin: 16px; + font-family: var(--ddd-font-primary); + color: var(--ddd-theme-default-nittanyNavy); + background-color: white; + min-height: 240px; box-shadow: var(--ddd-boxShadow-lg); - position: relative; + border-radius: 8px; } - .imageLink img{ - display: block; - width: 216px; - height: 125px; - overflow: clip; - justify-self: center; - border-top-right-radius: 8px; - border-top-left-radius: 8px; - } - - #labels { - display: block; - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; + #mainCard { + display: flex; + flex-direction: column; } - #labels ::slotted(*) { - font-family: var(--ddd-font-primary); - font-size: 20px; - font-weight: bold; + .cardContent { + padding: 12px 16px 20px; } - #labels ::slotted(a) { - color: var(--simple-colors-default-theme-light-blue-11); - padding: 8px 0; - display: block; + .imageLink img { + width: 220px; + height: 125px; + border-top-right-radius: 8px; + border-top-left-radius: 8px; + border-bottom: solid var(--ddd-theme-default-nittanyNavy) 12px; + overflow: clip; + justify-self: center; } - #labels ::slotted(a:focus), - #labels ::slotted(a:hover) { - color: var(--simple-colors-default-theme-light-blue-3); - background-color: var(--simple-colors-default-theme-light-blue-11); + .imageLink { + position: relative; + display: inline-block; + } + .settings-button { + position: relative; + display: inline-block; + align-self: center; } - :host([opened]) { - background-color: var(--simple-colors-default-theme-light-blue-3); + .options-menu { + position: absolute; + top: -110px; + right: 0; + background: var(--haxcms-color-ui-white, #fff); + border: 1px solid var(--haxcms-color-ui-1, #ccc); + box-shadow: 0 4px 6px rgba(0,0,0,0.1); + border-radius: 8px; + padding: 8px 8px 6px 10px; + display: flex; + flex-direction: column; + z-index: 1000; + overflow:visible; } - #mainCard { - display: block; - flex-direction: row; - justify-content: space-between; - align-items: center; - width: var(--main-banner-width); - height: var(--main-banner-height); - padding: 2px 4px; + .options-menu simple-icon-button-lite { + margin: 4px 0; } - #overlay { + .titleBar { display: flex; - position: absolute; - top: 0; - left: 0; - visibility: hidden; - justify-content: center; + justify-content: space-between; align-items: center; - height: 1px; - width: var(--main-banner-width); - z-index: 999; + font-size: 20px; + color: var(--ddd-theme-default-nittanyNavy); } - #closeButton { - position: absolute; - top: 10px; - right: 5px; - background: var(--simple-colors-default-theme-light-blue-1, var(--simple-colors-default-theme-light-blue-11)); - color: var(--simple-colors-default-theme-light-blue-11, var(--simple-colors-default-theme-light-blue-1)); - border: none; + p { font-size: 12px; - cursor: pointer; - z-index: 1001; - border-radius: 100; + padding: 8px 8px 6px 10px; } - - :host([opened]) #overlay { - height: var(--main-banner-height); - visibility: visible; - width: 100%; - height: 100%; - } - a { - flex: 1; + ::slotted([slot="heading"]) { + font-size: 20px; + font-weight: bold; + color: var(--ddd-theme-default-nittanyNavy); + text-decoration: none; + display: block; } - #labels { + button { display: flex; - text-align: center; + background-color: white; + color: var(--ddd-theme-default-nittanyNavy); + border: 2px solid var(--ddd-theme-default-nittanyNavy); + border-radius: 4px; + font-family: var(--ddd-font-primary); + font-size: 12px; + font-weight: 20px; + padding: 12px 16px 12px 24px; + height: 16px; + align-items: center; justify-content: center; - flex: 6; - overflow: hidden; - text-overflow: ellipsis; - margin-top: 20px; } - #dots { - --simple-icon-width: 24px; - --simple-icon-height: 24px; - color: var(--simple-colors-default-theme-light-blue-11); - border: solid var(--simple-colors-default-theme-light-blue-11); - border-radius: 4px; - margin-left: 8px; + .cardBottom { + display: flex; + justify-content: space-between; + align-items: center; + padding: 8px 8px 6px 10px; } - @media (max-width: 640px) { - :host { - --main-banner-height: 40px; - --band-banner-height: 140px; - } - #icon, - #dots { - --simple-icon-width: 30px; - --simple-icon-height: 30px; - } - #mainCard { - padding: 0; - } - + .cardBottom button{ + flex: 1; + margin: 0 4px; + } + ::slotted(a[slot="heading"]), + ::slotted(span[slot="subHeading"]), + ::slotted(div[slot="pre"]) { + display: block; } `, ]; @@ -203,26 +184,54 @@ export class AppHaxSiteBars extends SimpleColors { return html`
    -
    - - +
    +
    + +
    + + Options + + + + ${this.showOptions + ? html` +
    + + + Copy + + + + Download + + + + Archive + +
    + ` + : ''} +
    +
    + + + +
    + +
    -
    - - -
    - - Access site - More options `; } diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index 4e855f3cb5..3fd5332885 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -35,6 +35,7 @@ export class AppHaxUseCaseFilter extends LitElement { return { searchTerm: { type: String }, showSearch: { type: Boolean, reflect: true, attribute: "show-search" }, + showFilter: {type: Boolean, reflect: true, attribute: "show-filter"}, disabled: { type: Boolean, reflect: true }, items: { type: Array }, filteredItems: { type: Array }, @@ -76,7 +77,7 @@ export class AppHaxUseCaseFilter extends LitElement { .reset-button { display: flex; font-family: var(--ddd-font-primary); - font-size: 12px; + font-size: 16px; display: flex; align-items: center; justify-content: center; @@ -141,6 +142,35 @@ export class AppHaxUseCaseFilter extends LitElement { border: solid 1px var(--simple-colors-default-theme-accent-12, var(--accent-color)); width: 300px; } + .collapseFilter { + display: none; + } + @media (max-width: 780px) { + :host .filter { + display: none; + } + :host([show-filter]) .filter { + display: flex; + width: 250px; + max-width: 20vw; + } + :host .collapseFilter { + display: flex; + } + } + @media (max-width: 600px) { + :host .filter { + display: none; + } + :host([show-filter]) .filter { + display: flex; + width: 200px; + max-width: 20vw; + } + :host .collapseFilter { + display: flex; + } + } .filterButtons { margin-top: 8px; text-align: left; @@ -175,9 +205,16 @@ export class AppHaxUseCaseFilter extends LitElement { } } + toggleFilterVisibility() { + this.showFilter = !this.showFilter; + } + render() { return html`
    +
    + +
    From d61d88273f55c41039a057a7efc9661b2c56941f Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Thu, 10 Apr 2025 12:32:41 -0400 Subject: [PATCH 081/166] more background stuff --- .../lib/assets/images/DMBackgroundImage.svg | 88 ------------------ .../lib/assets/images/LMBackgroundImage.svg | 90 ------------------- 2 files changed, 178 deletions(-) delete mode 100644 elements/app-hax/lib/assets/images/DMBackgroundImage.svg delete mode 100644 elements/app-hax/lib/assets/images/LMBackgroundImage.svg diff --git a/elements/app-hax/lib/assets/images/DMBackgroundImage.svg b/elements/app-hax/lib/assets/images/DMBackgroundImage.svg deleted file mode 100644 index 999cf8de68..0000000000 --- a/elements/app-hax/lib/assets/images/DMBackgroundImage.svg +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/elements/app-hax/lib/assets/images/LMBackgroundImage.svg b/elements/app-hax/lib/assets/images/LMBackgroundImage.svg deleted file mode 100644 index 5fba01d7f3..0000000000 --- a/elements/app-hax/lib/assets/images/LMBackgroundImage.svg +++ /dev/null @@ -1,90 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From f0ec58a148aa7b42f7f5315a81866b25218961a5 Mon Sep 17 00:00:00 2001 From: Skyler Koba Date: Thu, 10 Apr 2025 12:33:34 -0400 Subject: [PATCH 082/166] Add files via upload --- .../lib/assets/images/DMBackgroundImage.svg | 88 +++++++++++++++++++ .../lib/assets/images/LMBackgroundImage.svg | 87 ++++++++++++++++++ 2 files changed, 175 insertions(+) create mode 100644 elements/app-hax/lib/assets/images/DMBackgroundImage.svg create mode 100644 elements/app-hax/lib/assets/images/LMBackgroundImage.svg diff --git a/elements/app-hax/lib/assets/images/DMBackgroundImage.svg b/elements/app-hax/lib/assets/images/DMBackgroundImage.svg new file mode 100644 index 0000000000..ad5739bebc --- /dev/null +++ b/elements/app-hax/lib/assets/images/DMBackgroundImage.svg @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/elements/app-hax/lib/assets/images/LMBackgroundImage.svg b/elements/app-hax/lib/assets/images/LMBackgroundImage.svg new file mode 100644 index 0000000000..e160fd480b --- /dev/null +++ b/elements/app-hax/lib/assets/images/LMBackgroundImage.svg @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 1db1bcc6dedfdfd076fde649f067fb6105b1a1e6 Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Thu, 10 Apr 2025 12:53:35 -0400 Subject: [PATCH 083/166] muy professional --- elements/app-hax/lib/v2/app-hax-site-bar.js | 14 +++-- elements/app-hax/lib/v2/app-hax-use-case.js | 62 +++++++++++++-------- 2 files changed, 48 insertions(+), 28 deletions(-) diff --git a/elements/app-hax/lib/v2/app-hax-site-bar.js b/elements/app-hax/lib/v2/app-hax-site-bar.js index d8327ae8bc..615f6f4367 100644 --- a/elements/app-hax/lib/v2/app-hax-site-bar.js +++ b/elements/app-hax/lib/v2/app-hax-site-bar.js @@ -76,7 +76,7 @@ export class AppHaxSiteBars extends SimpleColors { font-family: var(--ddd-font-primary); color: var(--ddd-theme-default-nittanyNavy); background-color: white; - min-height: 240px; + min-height: 220px; box-shadow: var(--ddd-boxShadow-lg); border-radius: 8px; } @@ -144,9 +144,9 @@ export class AppHaxSiteBars extends SimpleColors { } button { display: flex; - background-color: white; - color: var(--ddd-theme-default-nittanyNavy); - border: 2px solid var(--ddd-theme-default-nittanyNavy); + background-color: #005fa9; + color: white; + border: 0px; border-radius: 4px; font-family: var(--ddd-font-primary); font-size: 12px; @@ -156,15 +156,17 @@ export class AppHaxSiteBars extends SimpleColors { align-items: center; justify-content: center; } + button:hover { + background-color: var(--ddd-theme-default-nittanyNavy); + } .cardBottom { display: flex; justify-content: space-between; align-items: center; - padding: 8px 8px 6px 10px; } .cardBottom button{ flex: 1; - margin: 0 4px; + margin-top: 8px; } ::slotted(a[slot="heading"]), ::slotted(span[slot="subHeading"]), diff --git a/elements/app-hax/lib/v2/app-hax-use-case.js b/elements/app-hax/lib/v2/app-hax-use-case.js index c2d46397ce..705839758c 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case.js +++ b/elements/app-hax/lib/v2/app-hax-use-case.js @@ -42,9 +42,9 @@ export class AppHaxUseCase extends LitElement { :host { display: flex; flex-direction: column; - text-align: flex-start; + text-align: left; max-width: 240px; - margin:16px; + margin:12px; font-family: var(--ddd-font-primary); color: var(--ddd-theme-default-nittanyNavy); background-color: white; @@ -52,6 +52,9 @@ export class AppHaxUseCase extends LitElement { box-shadow: var(--ddd-boxShadow-lg); border-radius: 8px; } + .cardContent { + padding: 12px 16px 20px; + } .image img { width: 240px; height: 142px; @@ -116,7 +119,7 @@ export class AppHaxUseCase extends LitElement { display: block; } h3, p { - margin: 4px; + margin: 2px; } p { font-size: 12px; @@ -129,24 +132,27 @@ export class AppHaxUseCase extends LitElement { } button { display: flex; - background-color: white; - color: var(--ddd-theme-default-nittanyNavy); - border: 2px solid var(--ddd-theme-default-nittanyNavy); + background-color: #005fa9; + color: white; + border: 0px; border-radius: 4px; font-family: var(--ddd-font-primary); font-size: 12px; font-weight: 20px; - padding: 8px; + padding: 12px 16px 12px 24px; margin: 0px 4px 0px 4px; height: 16px; align-items: center; justify-content: center; } + button:hover { + background-color: var(--ddd-theme-default-nittanyNavy); + } .cardBottom { display: flex; justify-content: space-between; align-items: center; - margin-top: 16px; + margin-top: 8px; } .cardBottom button, .cardBottom a { @@ -158,14 +164,23 @@ export class AppHaxUseCase extends LitElement { } :host([isSelected]) button.select { - background-color: var(--simple-colors-default-theme-light-blue-12, --accent-color); - color: var(--simple-colors-default-theme-light-blue-1, --accent-color); + background-color: var(--ddd-theme-default-nittanyNavy); } .titleBar { display: inline-flex; align-items: center; text-align: flex-start; } + @media (max-width: 1440px) { + :host, .image img { + display: flex; + width: 250px; + max-width: 20vw; + } + :host .collapseFilter { + display: flex; + } + } `, ]; } @@ -208,21 +223,24 @@ export class AppHaxUseCase extends LitElement {
    -
    -

    ${this.title}

    -
    +
    +
    +

    ${this.title}

    +
    -

    ${this.description}

    +

    ${this.description}

    -
    - - ${this.isSelected - ? html`` - : html`Demo -> ` - } +
    + + ${this.isSelected + ? html`` + : html`Demo -> ` + } +
    +
    `; } From 5c5e158cdf757d3fbf408141fb05134e325aaef3 Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Tue, 15 Apr 2025 12:35:16 -0400 Subject: [PATCH 084/166] some design stuff --- elements/app-hax/lib/v2/app-hax-filter-tag.js | 2 +- .../app-hax/lib/v2/app-hax-search-results.js | 16 ++++++++++------ elements/app-hax/lib/v2/app-hax-site-bar.js | 4 ++-- .../app-hax/lib/v2/app-hax-use-case-filter.js | 6 ++++-- elements/app-hax/lib/v2/app-hax-use-case.js | 2 +- 5 files changed, 18 insertions(+), 12 deletions(-) diff --git a/elements/app-hax/lib/v2/app-hax-filter-tag.js b/elements/app-hax/lib/v2/app-hax-filter-tag.js index bfbc12855c..65a8b3426c 100644 --- a/elements/app-hax/lib/v2/app-hax-filter-tag.js +++ b/elements/app-hax/lib/v2/app-hax-filter-tag.js @@ -35,7 +35,7 @@ export class AppHaxFilterTag extends LitElement { padding-left: 8px; padding-right: 8px; height: 32px; - background-color: var(--app-hax-accent-color, var(--accent-color)); + background-color: var(--simple-colors-default-theme-light-blue-12, var(--accent-color)); border-radius: 8px; font-size: 16px; align-items: center; diff --git a/elements/app-hax/lib/v2/app-hax-search-results.js b/elements/app-hax/lib/v2/app-hax-search-results.js index 2a50985045..1dc1e05c13 100644 --- a/elements/app-hax/lib/v2/app-hax-search-results.js +++ b/elements/app-hax/lib/v2/app-hax-search-results.js @@ -42,6 +42,7 @@ export class AppHaxSearchResults extends SimpleColors { searchTerm: { type: String, reflect: true }, searchItems: { type: Array }, displayItems: { type: Array }, + siteUrl: { type: String, attribute: "site-url" }, }; } @@ -80,7 +81,7 @@ export class AppHaxSearchResults extends SimpleColors { gap: 10px; overflow: hidden; margin: 0px; - height: 300px; + max-height: 260px; justify-self: flex-start; align-self: flex-start; } @@ -107,6 +108,8 @@ export class AppHaxSearchResults extends SimpleColors { scrollbar-width: none; -ms-overflow-style: none; padding: 4px; + padding-left: 8px; + padding-right: 8px; } #results::-webkit-scrollbar { @@ -117,14 +120,14 @@ export class AppHaxSearchResults extends SimpleColors { flex: 0 0 auto; scroll-snap-align: center; width: 220px; - height: 300px; + height: 260px; display: flex; flex-direction: column; align-items: center; justify-content: center; } app-hax-site-bar { - margin: 12px 0; + margin: 0 12px; } .description { max-height: 64px; @@ -175,6 +178,7 @@ export class AppHaxSearchResults extends SimpleColors { html`
  • - ${item.title} + ${item.title} ${item.author}

    Return to...

    -
    diff --git a/elements/app-hax/lib/v2/app-hax-use-case.js b/elements/app-hax/lib/v2/app-hax-use-case.js index 705839758c..f296f4ff1e 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case.js +++ b/elements/app-hax/lib/v2/app-hax-use-case.js @@ -49,7 +49,7 @@ export class AppHaxUseCase extends LitElement { color: var(--ddd-theme-default-nittanyNavy); background-color: white; min-height: 270px; - box-shadow: var(--ddd-boxShadow-lg); + box-shadow: 2px 2px 12px #1c1c1c; border-radius: 8px; } .cardContent { From 841408d9d577e4e7105928b729f9e74fb8125a66 Mon Sep 17 00:00:00 2001 From: izzabizz5 Date: Tue, 15 Apr 2025 12:35:27 -0400 Subject: [PATCH 085/166] trying to get return cards to filter with tag buttons --- elements/app-hax/demo/sites.json | 12 +- elements/app-hax/lib/v2/app-hax-recipes.json | 2 +- .../app-hax/lib/v2/app-hax-use-case-filter.js | 253 ++++++++++++------ 3 files changed, 178 insertions(+), 89 deletions(-) diff --git a/elements/app-hax/demo/sites.json b/elements/app-hax/demo/sites.json index b504e06024..acd2ef56bb 100644 --- a/elements/app-hax/demo/sites.json +++ b/elements/app-hax/demo/sites.json @@ -25,6 +25,7 @@ "name": "ist402", "created": 1565898366, "updated": 1615262120, + "category": "Course", "git": { "autoPush": false, "branch": "master", @@ -81,6 +82,7 @@ "name": "acctg211", "created": 1610048864, "updated": 1612555993, + "category": "Course", "version": "2.0.9", "domain": "", "logo": "", @@ -149,6 +151,7 @@ "name": "geodz511", "created": 1569349769, "updated": 1640014827, + "category": "Course", "git": { "vendor": "github", "branch": "master", @@ -206,6 +209,7 @@ "logo": "assets/banner.jpg", "created": 1635276018, "updated": 1635276048, + "category": "Course", "git": {} }, "theme": { @@ -246,6 +250,7 @@ "name": "ist210", "created": 1592403069, "updated": 1598281185, + "category": "Course", "git": { "autoPush": false, "branch": "", @@ -296,6 +301,7 @@ "author": "", "description": "", "license": "by-sa", + "category": "Course", "metadata": { "author": { "image": "", @@ -308,6 +314,7 @@ "logo": "assets/banner.jpg", "created": 1594994550, "updated": 1595266163, + "category": "Course", "git": { "autoPush": false, "branch": "", @@ -369,6 +376,7 @@ "logo": "assets/banner.jpg", "created": 1629208877, "updated": 1642013655, + "category": "Course", "git": { "autoPush": false, "branch": "", @@ -425,6 +433,7 @@ "logo": "assets/banner.jpg", "created": 1644856484, "updated": 1644856484, + "category": "Course", "git": {} }, "theme": { @@ -459,7 +468,8 @@ "domain": null, "site": { "created": 1558624482, - "updated": 1558624504 + "updated": 1558624504, + "category": "Course" }, "theme": { "element": "learn-two-theme", diff --git a/elements/app-hax/lib/v2/app-hax-recipes.json b/elements/app-hax/lib/v2/app-hax-recipes.json index fa0850dbc7..8fdaddf835 100644 --- a/elements/app-hax/lib/v2/app-hax-recipes.json +++ b/elements/app-hax/lib/v2/app-hax-recipes.json @@ -3,7 +3,7 @@ "item": [ { "uuid": "72e00632-f4a2-48d5-9b1b-f39ab26ec350", - "title": "Portfolio", + "title": "Art", "category": ["Portfolio"], "recipe": "recipes/portfolio/portfolio.recipe", "theme": { diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index 4510515b40..e455509d85 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -8,7 +8,6 @@ import "./app-hax-filter-tag.js"; import "./app-hax-scroll-button.js"; export class AppHaxUseCaseFilter extends LitElement { - // a convention I enjoy so you can change the tag name in 1 place static get tag() { return "app-hax-use-case-filter"; } @@ -20,6 +19,7 @@ export class AppHaxUseCaseFilter extends LitElement { this.showSearch = false; this.items = []; this.filteredItems = []; + this.filteredSites = []; this.activeFilters = []; this.filters = []; this.searchQuery = ""; @@ -27,10 +27,9 @@ export class AppHaxUseCaseFilter extends LitElement { this.errorMessage = ""; this.loading = false; this.selectedCardIndex = null; + this.returningSites = []; } - // Site.json is coming from - static get properties() { return { searchTerm: { type: String }, @@ -38,6 +37,7 @@ export class AppHaxUseCaseFilter extends LitElement { disabled: { type: Boolean, reflect: true }, items: { type: Array }, filteredItems: { type: Array }, + filteredSites: { type: Array }, activeFilters: { type: Array }, filters: { type: Array }, searchQuery: { type: String }, @@ -45,6 +45,7 @@ export class AppHaxUseCaseFilter extends LitElement { errorMessage: { type: String }, loading: { type: Boolean }, selectedCardIndex: { type: Number }, + returningSites: { type: Array } }; } @@ -71,7 +72,7 @@ export class AppHaxUseCaseFilter extends LitElement { .rightSection { display: block; } - .results { + .template-results { display: flex; justify-content: flex-start; align-items: flex-start; @@ -224,7 +225,7 @@ export class AppHaxUseCaseFilter extends LitElement {

    Return to...

    - +
    @@ -237,7 +238,7 @@ export class AppHaxUseCaseFilter extends LitElement { ` )}
  • -
    +
    ${this.filteredItems.length > 0 ? this.filteredItems.map( (item, index) => html` @@ -265,7 +266,6 @@ export class AppHaxUseCaseFilter extends LitElement {
    `; } - firstUpdated() { super.firstUpdated(); @@ -282,7 +282,6 @@ export class AppHaxUseCaseFilter extends LitElement { } } - toggleSearch() { if (!this.disabled) { this.shadowRoot.querySelector("#searchField").value = ""; @@ -307,25 +306,30 @@ export class AppHaxUseCaseFilter extends LitElement { const searchTerm = event.target.value.toLowerCase(); this.searchTerm = searchTerm; store.searchTerm = searchTerm; // Update store with search term - - // Filter templates - this.filteredItems = this.items.filter(item => - item.useCaseTitle.toLowerCase().includes(searchTerm) || - item.useCaseTag.some(tag => tag.toLowerCase().includes(searchTerm)) + + // Filter templates (recipes) + this.filteredItems = this.items.filter( + item => + item.dataType === "recipe" && + ( + item.useCaseTitle.toLowerCase().includes(searchTerm) || + (item.useCaseTag && item.useCaseTag.some(tag => tag.toLowerCase().includes(searchTerm))) + ) ); - - // Filter returning sites (assuming you have access to sites data) - if (this.returningSites) { - this.filteredSites = this.returningSites.filter(site => - site.title.toLowerCase().includes(searchTerm) - ); - } - + + // Filter returning sites + this.filteredSites = this.items.filter( + item => + item.dataType === "site" && + ( + (item.originalData.title && item.originalData.title.toLowerCase().includes(searchTerm)) || + (item.useCaseTag && item.useCaseTag.some(tag => tag.toLowerCase().includes(searchTerm))) + ) + ); + this.requestUpdate(); } - - - + toggleFilter(event) { const filterValue = event.target.value; @@ -339,116 +343,192 @@ export class AppHaxUseCaseFilter extends LitElement { applyFilters() { const lowerCaseQuery = this.searchTerm.toLowerCase(); - - // Combined filter logic + + // Filter templates (recipes) this.filteredItems = this.items.filter((item) => { - const matchesSearch = lowerCaseQuery === "" || + if (item.dataType !== "recipe") return false; + const matchesSearch = + lowerCaseQuery === "" || item.useCaseTitle.toLowerCase().includes(lowerCaseQuery) || - item.useCaseTag.some(tag => tag.toLowerCase().includes(lowerCaseQuery)); - - const matchesFilters = this.activeFilters.length === 0 || - this.activeFilters.some(filter => item.useCaseTag.includes(filter)); - + (item.useCaseTag && item.useCaseTag.some(tag => tag.toLowerCase().includes(lowerCaseQuery))); + + const matchesFilters = + this.activeFilters.length === 0 || + (item.useCaseTag && this.activeFilters.some(filter => item.useCaseTag.includes(filter))); + return matchesSearch && matchesFilters; }); - + + // Filter returning sites + this.filteredSites = this.items.filter((item) => { + if (item.dataType !== "site") return false; + const matchesSearch = + lowerCaseQuery === "" || + (item.originalData.title && item.originalData.title.toLowerCase().includes(lowerCaseQuery)) || + (item.useCaseTag && item.useCaseTag.some(tag => tag.toLowerCase().includes(lowerCaseQuery))); + + const matchesFilters = + this.activeFilters.length === 0 || + (item.useCaseTag && this.activeFilters.some(filter => item.useCaseTag.includes(filter))); + + return matchesSearch && matchesFilters; + }); + // Update search results in store store.searchResults = { templates: this.filteredItems, - sites: this.filteredSites || [] + sites: this.filteredSites }; + + this.requestUpdate(); } - - + removeFilter(event) { const filterToRemove = event.detail; this.activeFilters = this.activeFilters.filter((f) => f !== filterToRemove); this.applyFilters(); // Re-filter results this.requestUpdate(); } - + resetFilters() { this.searchTerm = ""; store.searchTerm = ""; this.activeFilters = []; - this.filteredItems = this.items; - - if (this.returningSites) { - this.filteredSites = this.returningSites; - } - + // Show all templates and all sites + this.filteredItems = this.items.filter(item => item.dataType === "recipe"); + this.filteredSites = this.items.filter(item => item.dataType === "site"); + // Clear UI elements this.shadowRoot.querySelector("#searchField").value = ""; this.shadowRoot.querySelectorAll('input[type="checkbox"]').forEach(cb => cb.checked = false); - + this.requestUpdate(); } - - updateResults() { this.loading = true; - this.errorMessage = ""; // Reset error before fetching - - fetch(new URL('./app-hax-recipes.json', import.meta.url).href) - .then(response => { - if (!response.ok) { - throw new Error('Network response was not ok'); - } - return response.json(); // Parse JSON data - }) - .then(data => { - // Map JSON data to component's items - - if (Array.isArray(data.item)) { - this.items = data.item.map(item => ({ - useCaseTitle: item.title, - useCaseImage: item.image, - useCaseDescription: item.description, - useCaseIcon: item.attributes.map(attributes => ({ - icon: attributes.icon, - tooltip: attributes.tooltip - })), - useCaseTag: Array.isArray(item.category) ? item.category : [item.category], - demoLink: item["demo-url"], - })); - this.filteredItems = this.items; - this.filters = []; - - data.item.forEach(item => { + this.errorMessage = ""; + this.items = []; // Clear previous items + this.filters = []; // Clear previous filters + + const recipesUrl = new URL('./app-hax-recipes.json', import.meta.url).href; + const sitesUrl = new URL('../../demo/sites.json', import.meta.url).href; + + Promise.all([ + fetch(recipesUrl).then(response => { + if (!response.ok) throw new Error(`Failed Recipes (${response.status})`); + return response.json(); + }), + fetch(sitesUrl).then(response => { + if (!response.ok) throw new Error(`Failed Sites (${response.status})`); + return response.json(); + }) + ]) + .then(([recipesData, sitesData]) => { + let combinedItems = []; + let allFilters = new Set(); + + // --- 1. Process Recipes Data (app-hax-recipes.json) --- + if (recipesData && Array.isArray(recipesData.item)) { + const mappedRecipes = recipesData.item.map(item => { + // Ensure category is an array, default if missing + let tags = []; if (Array.isArray(item.category)) { - item.category.forEach(category => { - if (!this.filters.includes(category)) { - this.filters = [...this.filters, category]; - } - }); + tags = item.category.filter(c => typeof c === 'string' && c.trim() !== ''); // Clean array + } else if (typeof item.category === 'string' && item.category.trim() !== '') { + tags = [item.category.trim()]; + } + // Add a default tag if none are valid + if (tags.length === 0) { + tags = ['Empty']; // Default category for recipes } + tags.forEach(tag => allFilters.add(tag)); // Add to unique filter list + + // Map attributes to useCaseIcon format + const icons = Array.isArray(item.attributes) ? item.attributes.map(attr => ({ + icon: attr.icon || '', + tooltip: attr.tooltip || '' + })) : []; + + return { + dataType: 'recipe', // Identifier + useCaseTitle: item.title || 'Untitled Template', + useCaseImage: item.image || '', + useCaseDescription: item.description || '', + useCaseIcon: icons, + useCaseTag: tags, + demoLink: item["demo-url"] || '#', + originalData: item + }; }); + combinedItems = combinedItems.concat(mappedRecipes); } else { - this.errorMessage = 'No Templates Found'; + console.warn("Recipes data missing or not in expected format:", recipesData); + } + + // --- 2. Process Sites Data (site.json) --- + if (sitesData && sitesData.data && Array.isArray(sitesData.data.items)) { + const mappedSites = sitesData.data.items.map(item => { + // CORRECTED: Use ONLY metadata.site.category + let categorySource = item.metadata.site.category; + let tags = []; + if (typeof categorySource === 'string' && categorySource.trim() !== '') { + tags = [categorySource.trim()]; + } else if (Array.isArray(categorySource)) { + tags = categorySource.filter(c => typeof c === 'string' && c.trim() !== ''); + } + // Add default ONLY if no valid category + if (tags.length === 0) { + tags = ['Site']; + } + tags.forEach(tag => allFilters.add(tag)); + return { + dataType: 'site', + useCaseTag: tags, + originalData: item + }; + }); + combinedItems = combinedItems.concat(mappedSites); + } + + // --- 3. Update Component State --- + this.items = combinedItems; + // Sort filters alphabetically for UI consistency + this.filters = Array.from(allFilters).sort((a, b) => a.localeCompare(b)); + + // Separate out returningSites for reference (not strictly needed, but kept for clarity) + this.returningSites = combinedItems.filter(item => item.dataType === "site"); + + if (this.items.length === 0 && !this.errorMessage) { + this.errorMessage = 'No Templates or Sites Found'; } - console.log(data); + + // Apply initial filters (which will be none, showing all items) + this.resetFilters(); + }) .catch(error => { this.errorMessage = `Failed to load data: ${error.message}`; + console.error("Error fetching or processing data:", error); this.items = []; this.filteredItems = []; + this.filteredSites = []; + this.filters = []; }) .finally(() => { this.loading = false; - this.requestUpdate(); }); } toggleDisplay(index, event) { const isSelected = event.detail.isSelected; - + if (this.selectedCardIndex !== null && this.selectedCardIndex !== index) { // Deselect the previously selected card this.filteredItems[this.selectedCardIndex].isSelected = false; this.filteredItems[this.selectedCardIndex].showContinue = false; } - + if (isSelected) { // Select the new card this.selectedCardIndex = index; @@ -456,7 +536,7 @@ export class AppHaxUseCaseFilter extends LitElement { // Deselect the current card this.selectedCardIndex = null; } - + this.filteredItems[index].isSelected = isSelected; this.filteredItems[index].showContinue = isSelected; this.requestUpdate(); @@ -466,6 +546,5 @@ export class AppHaxUseCaseFilter extends LitElement { console.log(`Continue action for item at index ${index}`); // Implement the continue action for the selected item } - } -customElements.define("app-hax-use-case-filter", AppHaxUseCaseFilter); \ No newline at end of file +customElements.define("app-hax-use-case-filter", AppHaxUseCaseFilter); From 522da8b57ff61fbbacf8bc24f63953c318b3a1bf Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Tue, 15 Apr 2025 12:55:23 -0400 Subject: [PATCH 086/166] fixed spacing --- elements/app-hax/lib/v2/app-hax-use-case.js | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/elements/app-hax/lib/v2/app-hax-use-case.js b/elements/app-hax/lib/v2/app-hax-use-case.js index 610b8b2753..7a2c9c822a 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case.js +++ b/elements/app-hax/lib/v2/app-hax-use-case.js @@ -168,15 +168,16 @@ export class AppHaxUseCase extends LitElement { background-color: var(--ddd-theme-default-nittanyNavy); } .cardBottom { - display: flex; - justify-content: space-between; - align-items: center; - margin-top: 8px; + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 8px; + padding: 0px 16px 20px 16px; } .cardBottom button, .cardBottom a { - flex: 1; - margin: 0 4px; + flex: 1; + margin: 0 4px; } .cardBottom a:visited { color: var(--simple-colors-default-theme-light-blue-9); @@ -187,8 +188,9 @@ export class AppHaxUseCase extends LitElement { } .titleBar { display: inline-flex; - align-items: center; - text-align: flex-start; + flex-direction: column; + text-align: left; + padding: 0px 16px; } @media (max-width: 1440px) { :host, .image img { @@ -249,8 +251,8 @@ export class AppHaxUseCase extends LitElement {

    ${this.title}

    +

    ${this.description}

    -

    ${this.description}

    @@ -319,7 +319,7 @@ export class AppHaxUseCaseFilter extends LitElement { if ( changedProperties.has("searchQuery") || changedProperties.has("activeFilters") || - changedProperties.has("item") + changedProperties.has("items") ) { this.applyFilters(); } @@ -409,7 +409,7 @@ export class AppHaxUseCaseFilter extends LitElement { const matchesSearch = lowerCaseQuery === "" || - (item.originalData.title && item.originalData.title.toLowerCase().includes(lowerCaseQuery)) || + (item.originalData.category && item.originalData.category.toLowerCase().includes(lowerCaseQuery)) || (item.useCaseTag && item.useCaseTag.some(tag => tag.toLowerCase().includes(lowerCaseQuery))); const matchesFilters = @@ -537,7 +537,7 @@ export class AppHaxUseCaseFilter extends LitElement { this.returningSites = siteItems; this.filters = Array.from(this.allFilters).sort(); // Set AFTER all items - this.filteredSites = siteItems; + this.filteredSites = [...siteItems]; if (siteItems.length === 0 && !this.errorMessage) { this.errorMessage = 'No Sites Found'; From db31d823ec53bf45ebc0c7f34b1c6d715b972347 Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Tue, 22 Apr 2025 12:53:53 -0400 Subject: [PATCH 089/166] help --- .../app-hax/lib/v2/app-hax-search-results.js | 33 +++---------------- .../app-hax/lib/v2/app-hax-use-case-filter.js | 5 +-- 2 files changed, 8 insertions(+), 30 deletions(-) diff --git a/elements/app-hax/lib/v2/app-hax-search-results.js b/elements/app-hax/lib/v2/app-hax-search-results.js index 7182f3a280..83ead7ef88 100644 --- a/elements/app-hax/lib/v2/app-hax-search-results.js +++ b/elements/app-hax/lib/v2/app-hax-search-results.js @@ -27,9 +27,9 @@ export class AppHaxSearchResults extends SimpleColors { }); /*autorun(() => { const manifest = toJS(store.manifest); - if (manifest && manifest.items) { - this.searchItems = manifest.items; - this.displayItems = [...this.searchItems]; + if (manifest && manifest.data.items) { + this.results = manifest.data.items; + this.displayItems = [...this.results]; } });*/ } @@ -56,7 +56,7 @@ export class AppHaxSearchResults extends SimpleColors { return ( word.title.toLowerCase().includes(this.searchTerm.toLowerCase()) || word.description.toLowerCase().includes(this.searchTerm.toLowerCase()) || - word.author.toLowerCase().includes(this.searchTerm.toLowerCase()) || + word.metadata.author.toLowerCase().includes(this.searchTerm.toLowerCase()) || word.slug.toLowerCase().includes(this.searchTerm.toLowerCase()) ); }); @@ -203,7 +203,7 @@ export class AppHaxSearchResults extends SimpleColors { No results for ${this.searchTerm !== "" ? html`"${this.searchTerm}"` - : "your account, try starting a new journey!"}. + : "your account, try starting a new journey!"}
    `} @@ -219,28 +219,5 @@ export class AppHaxSearchResults extends SimpleColors { scrollRight() { this.shadowRoot.querySelector("#results").scrollBy({ left: 800, behavior: "smooth" }); } - - getItemDetails(item) { - const details = { - created: varGet(item, "metadata.site.created", new Date() / 1000), - updated: varGet(item, "metadata.site.updated", new Date() / 1000), - pages: varGet(item, "metadata.pageCount", 0), - url: item.slug, - }; - return details; - } - - openedChanged(e) { - store.appEl.playSound("click"); - if (!e.detail.value) { - this.shadowRoot - .querySelector("app-hax-site-details") - .setAttribute("tabindex", "-1"); - } else { - this.shadowRoot - .querySelector("app-hax-site-details") - .removeAttribute("tabindex"); - } - } } customElements.define(AppHaxSearchResults.tag, AppHaxSearchResults); diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index f2342475bb..557d1e6135 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -266,7 +266,7 @@ export class AppHaxUseCaseFilter extends LitElement {

    Return to...

    + .searchTerm=${this.searchTerm}>
    @@ -517,7 +517,8 @@ export class AppHaxUseCaseFilter extends LitElement { return response.json(); }) .then(sitesData => { - const siteItems = Array.isArray(sitesData.items) ? sitesData.items.map(item => { + const items = sitesData.data?.items || []; + const siteItems = Array.isArray(items) ? items.map(item => { let categorySource = item?.metadata?.site?.category; let tags = []; if (Array.isArray(categorySource)) { From 16f7fd477e62b0c3bc526fa93778997bd7454c7a Mon Sep 17 00:00:00 2001 From: izzabizz5 Date: Thu, 24 Apr 2025 11:45:36 -0400 Subject: [PATCH 090/166] commit --- elements/app-hax/lib/v2/app-hax-use-case-filter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index 4894329ba3..fbe45e5cff 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -518,7 +518,7 @@ export class AppHaxUseCaseFilter extends LitElement { }) .then(sitesData => { const siteItems = Array.isArray(sitesData.items) ? sitesData.items.map(item => { - let categorySource = item?.metadata?.site?.category; + let categorySource = item.metadata.site.category; let tags = []; if (Array.isArray(categorySource)) { tags = categorySource.filter(c => typeof c === 'string' && c.trim() !== ''); From d3a5806f04728fc23116da41a403b1bbea2da15d Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Thu, 24 Apr 2025 12:38:52 -0400 Subject: [PATCH 091/166] stuff --- elements/app-hax/app-hax.js | 3 +++ elements/app-hax/lib/v2/app-hax-use-case-filter.js | 1 + elements/app-hax/lib/v2/app-hax-wired-toggle.js | 1 - .../lib/wired-darkmode-toggle/wired-darkmode-toggle.js | 4 ++-- elements/app-hax/src/app-hax.js | 3 +++ 5 files changed, 9 insertions(+), 3 deletions(-) diff --git a/elements/app-hax/app-hax.js b/elements/app-hax/app-hax.js index e0571ea086..6e6a590ab1 100644 --- a/elements/app-hax/app-hax.js +++ b/elements/app-hax/app-hax.js @@ -767,6 +767,9 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} #home { display: inline-flex; } + #wt { + border: solid 1px var(--simple-colors-default-theme-accent-12, var(--accent-color)); + } simple-toolbar-button { min-width: 48px; margin: 0; diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index d67d394005..eebed601ad 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -157,6 +157,7 @@ export class AppHaxUseCaseFilter extends LitElement { padding: var(--ddd-spacing-4); border: solid 1px var(--simple-colors-default-theme-accent-12, var(--accent-color)); width: 300px; + box-shadow: 0 4px 6px rgba(0,0,0,0.1); } .collapseFilter { display: none; diff --git a/elements/app-hax/lib/v2/app-hax-wired-toggle.js b/elements/app-hax/lib/v2/app-hax-wired-toggle.js index 5d3b2d486e..50356bced4 100644 --- a/elements/app-hax/lib/v2/app-hax-wired-toggle.js +++ b/elements/app-hax/lib/v2/app-hax-wired-toggle.js @@ -24,7 +24,6 @@ export class AppHAXWiredToggle extends SimpleTourFinder(WiredDarkmodeToggle) { changedProperties.forEach((oldValue, propName) => { if (propName === "checked" && oldValue !== undefined) { store.darkMode = this[propName]; - store.appEl.playSound("click"); } }); } diff --git a/elements/app-hax/lib/wired-darkmode-toggle/wired-darkmode-toggle.js b/elements/app-hax/lib/wired-darkmode-toggle/wired-darkmode-toggle.js index 7de8a7147b..555f2ef7e2 100644 --- a/elements/app-hax/lib/wired-darkmode-toggle/wired-darkmode-toggle.js +++ b/elements/app-hax/lib/wired-darkmode-toggle/wired-darkmode-toggle.js @@ -30,8 +30,8 @@ export class WiredDarkmodeToggle extends WiredToggle { } draw(svg, size) { - const rect = rectangle(svg, 0, 0, size[0], 48, this.seed); - rect.classList.add("toggle-bar"); + //const rect = rectangle(svg, 0, 0, size[0], 48, this.seed); + //rect.classList.add("toggle-bar"); this.knob = svgNode("g"); this.knob.classList.add("knob"); svg.appendChild(this.knob); diff --git a/elements/app-hax/src/app-hax.js b/elements/app-hax/src/app-hax.js index e0571ea086..6e6a590ab1 100644 --- a/elements/app-hax/src/app-hax.js +++ b/elements/app-hax/src/app-hax.js @@ -767,6 +767,9 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} #home { display: inline-flex; } + #wt { + border: solid 1px var(--simple-colors-default-theme-accent-12, var(--accent-color)); + } simple-toolbar-button { min-width: 48px; margin: 0; From 4c5e2ea2bc8731b1e0c27c2740db734c2257fa7f Mon Sep 17 00:00:00 2001 From: izzabizz5 Date: Fri, 25 Apr 2025 10:36:58 -0400 Subject: [PATCH 092/166] fixed filtering and labeling --- elements/app-hax/app-hax.js | 2 +- .../app-hax/lib/v2/app-hax-use-case-filter.js | 49 +++++++++---------- elements/app-hax/src/app-hax.js | 2 +- 3 files changed, 24 insertions(+), 29 deletions(-) diff --git a/elements/app-hax/app-hax.js b/elements/app-hax/app-hax.js index e0571ea086..4195f4d048 100644 --- a/elements/app-hax/app-hax.js +++ b/elements/app-hax/app-hax.js @@ -1275,7 +1275,7 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight}
    diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index fbe45e5cff..458f4b817e 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -265,14 +265,14 @@ export class AppHaxUseCaseFilter extends LitElement {

    Return to...

    -

    Start New Journey

    +

    Create New Site

    ${this.activeFilters.map( (filter) => html` @@ -351,24 +351,24 @@ export class AppHaxUseCaseFilter extends LitElement { store.searchTerm = searchTerm; // Update store with search term // Filter templates (recipes) - this.filteredItems = this.items.filter( + this.filteredItems = [...this.items.filter( item => item.dataType === "recipe" && ( item.useCaseTitle.toLowerCase().includes(searchTerm) || (item.useCaseTag && item.useCaseTag.some(tag => tag.toLowerCase().includes(searchTerm))) ) - ); + )]; // Filter returning sites - this.filteredSites = this.items.filter( + this.filteredSites = [...this.items.filter( item => item.dataType === "site" && ( (item.originalData.title && item.originalData.title.toLowerCase().includes(searchTerm)) || (item.useCaseTag && item.useCaseTag.some(tag => tag.toLowerCase().includes(searchTerm))) ) - ); + )]; this.requestUpdate(); } @@ -377,7 +377,7 @@ export class AppHaxUseCaseFilter extends LitElement { const filterValue = event.target.value; if (this.activeFilters.includes(filterValue)) { - this.activeFilters = this.activeFilters.filter((f) => f !== filterValue); + this.activeFilters = [...this.activeFilters.filter((f) => f !== filterValue)]; } else { this.activeFilters = [...this.activeFilters, filterValue]; } @@ -388,7 +388,7 @@ export class AppHaxUseCaseFilter extends LitElement { const lowerCaseQuery = this.searchTerm.toLowerCase(); // Filter recipes (from this.items) - this.filteredItems = this.items.filter((item) => { + this.filteredItems = [...this.items.filter((item) => { if (item.dataType !== "recipe") return false; const matchesSearch = lowerCaseQuery === "" || @@ -400,26 +400,22 @@ export class AppHaxUseCaseFilter extends LitElement { (item.useCaseTag && this.activeFilters.some(filter => item.useCaseTag.includes(filter))); return matchesSearch && matchesFilters; - }); - + })]; // Filter sites (from this.returningSites) - this.filteredSites = this.returningSites.filter((item) => { + this.filteredSites = [...this.returningSites.filter((item) => { if (item.dataType !== "site") return false; const siteCategory = item.originalData.metadata?.site?.category || []; - const matchesSearch = lowerCaseQuery === "" || - (item.originalData.category && item.originalData.category.toLowerCase().includes(lowerCaseQuery)) || + (item.originalData.category && item.originalData.category && item.originalData.category.includes(lowerCaseQuery)) || (item.useCaseTag && item.useCaseTag.some(tag => tag.toLowerCase().includes(lowerCaseQuery))); - const matchesFilters = this.activeFilters.length === 0 || - this.activeFilters.some(filter => - siteCategory.includes(filter) - ); - + this.activeFilters.some((filter) => { + return siteCategory.includes(filter); + }); return matchesSearch && matchesFilters; - }); + })]; } @@ -435,8 +431,8 @@ export class AppHaxUseCaseFilter extends LitElement { store.searchTerm = ""; this.activeFilters = []; // Show all templates and all sites - this.filteredItems = this.items.filter(item => item.dataType === "recipe"); - this.filteredSites = this.returningSites; + this.filteredItems = [...this.items.filter(item => item.dataType === "recipe")]; + this.filteredSites = [...this.returningSites]; // Clear UI elements this.shadowRoot.querySelector("#searchField").value = ""; @@ -517,7 +513,7 @@ export class AppHaxUseCaseFilter extends LitElement { return response.json(); }) .then(sitesData => { - const siteItems = Array.isArray(sitesData.items) ? sitesData.items.map(item => { + const siteItems = Array.isArray(sitesData.data.items) ? sitesData.data.items.map(item => { let categorySource = item.metadata.site.category; let tags = []; if (Array.isArray(categorySource)) { @@ -527,15 +523,14 @@ export class AppHaxUseCaseFilter extends LitElement { } if (tags.length === 0) tags = ['Empty']; tags.forEach(tag => this.allFilters.add(tag)); // Add to global Set - return { dataType: 'site', useCaseTag: tags, - originalData: item + originalData: item, + ...item // this spreads every prop into this area that way it can be filtered correctly }; }) : []; - - this.returningSites = siteItems; + this.returningSites = [...siteItems]; this.filters = Array.from(this.allFilters).sort(); // Set AFTER all items this.filteredSites = [...siteItems]; @@ -584,4 +579,4 @@ export class AppHaxUseCaseFilter extends LitElement { // Implement the continue action for the selected item } } -customElements.define("app-hax-use-case-filter", AppHaxUseCaseFilter); +customElements.define("app-hax-use-case-filter", AppHaxUseCaseFilter); \ No newline at end of file diff --git a/elements/app-hax/src/app-hax.js b/elements/app-hax/src/app-hax.js index e0571ea086..4195f4d048 100644 --- a/elements/app-hax/src/app-hax.js +++ b/elements/app-hax/src/app-hax.js @@ -1275,7 +1275,7 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight}
    From 707a440f7a12770e56e4247e66654fbe424cac04 Mon Sep 17 00:00:00 2001 From: izzabizz5 Date: Tue, 29 Apr 2025 12:48:17 -0400 Subject: [PATCH 093/166] styling fixes --- .../app-hax/lib/v2/app-hax-use-case-filter.js | 302 ++++++++++++------ 1 file changed, 204 insertions(+), 98 deletions(-) diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index 458f4b817e..8b868d6802 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -58,109 +58,202 @@ export class AppHaxUseCaseFilter extends LitElement { :host { overflow: hidden; display: block; - width: 100%; + max-width: 100%; + } + :host, *, *::before, *::after { + box-sizing: border-box; } .contentSection { - display: flex; - align-items: flex-start; - justify-content: flex-start; - gap: 16px; - width: 100%; + display: flex; + align-items: stretch; + width: 100%; + box-sizing: border-box; + max-width: 100vw; + overflow-x: hidden; + } + .leftSection, .rightSection { + display: flex; + flex-direction: column; + flex: 1 1 0; } .leftSection { - display: block; - width: 460px; - margin-left: 12px; + width: 340px; + min-width: 260px; + max-width: 380px; + flex: 0 0 340px; + margin-left: 0; + margin-right: 24px; + padding-top: 0; + box-sizing: border-box; } .rightSection { - display: block; - } - .template-results { + flex: 1 1 0; + width: 100%; + min-width: 0; + box-sizing: border-box; display: flex; - justify-content: flex-start; - align-items: flex-start; - flex-wrap: wrap; + flex-direction: column; } - app-hax-search-results { - display: flex; - justify-content: flex-start; - align-items: flex-start; - width: 828px; - z-index: 5; + .template-results { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(260px, 0.3fr)); + width: 100%; + min-height: 330px; + box-sizing: border-box; } - .reset-button { - display: flex; - font-family: var(--ddd-font-primary); - font-size: 16px; - display: flex; - align-items: center; - justify-content: center; - padding: 8px; - margin-top: 36px; + #returnToSection app-hax-search-results { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 24px; /* or your preferred gap */ + width: 100%; + max-width: 100%; + min-height: 120px; + box-sizing: border-box; + justify-items: center; + align-items: stretch; } - h4 { + h4, + .returnTo h4, + .startNew h4 { font-family: var(--ddd-font-primary); font-size: 24px; color: var(--app-hax-accent-color, var(--accent-color)); - margin: 16px; + margin: 0 0 var(--ddd-spacing-4) 0; } - .startNew, .returnTo { - padding-top: 40px; + .startNew, + .returnTo { + padding-top: 8px; position: relative; display: flex; flex-direction: column; justify-content: flex-start; align-items: flex-start; - margin-left: 48px; - margin-right: 48px; - } - .startNew h4, .returnTo h4 { - flex-shrink: 0; + margin-left: 0; + margin-right: 0; } - .returnTo h4 { - margin-top: 0px; + .upper-filter { + margin-bottom: var(--ddd-spacing-3); + position: relative; + display: inline-block; } - input[type="text"]{ - opacity: 1; - width: 250px; - padding: 4px; - padding-left: 35px; + input[type="text"] { + width: 100%; max-width: 25vw; - transition: all ease-in-out 0.3s; + padding: var(--ddd-spacing-3) var(--ddd-spacing-3) var(--ddd-spacing-3) 44px; + font-size: 15px; + border-radius: var(--ddd-radius-md); + border: var(--ddd-border-xs); + background: var(--ddd-accent-2, #f2f2f4); + color: #222; + transition: border 0.2s; + box-sizing: border-box; font-family: var(--ddd-font-primary); - font-size: 16px; margin: 4px 0 0 4px; height: 20px; - } - .upper-filter { - position: relative; - display: inline-block; - } + } + input[type="text"]:focus { + border: var(--ddd-border-sm); + background: #fff; + outline: none; + } .search-icon { - position: absolute; - left: 12px; + position: absolute; + left: 16px; top: 50%; transform: translateY(-50%); - font-size: 16px; + font-size: 22px; + color: var(--ddd-primary-8, #009cde); align-self: center; - } + } .filter { + padding: 24px; position: sticky; - top: 0; - height: 280px; + top: 0; + display: flex; + flex-direction: column; + gap: var(--ddd-spacing-4); + background: var(--ddd-accent-6, #fff); + border-radius: var(--ddd-radius-lg); + box-shadow: var(--ddd-boxShadow-lg); + border: var(--ddd-border-xs); + padding: var(--ddd-spacing-6) var(--ddd-spacing-5) var(--ddd-spacing-5) var(--ddd-spacing-5); + margin-top: 0; + margin-left: 24px; + margin-bottom: 0; + width: 100%; + max-width: 320px; + box-sizing: border-box; + font-family: var(--ddd-font-primary); + transition: box-shadow 0.2s; + } + .filter:hover { + box-shadow: var(--ddd-boxShadow-xl); + } + .filterButtons { display: flex; - background-color: var(--simple-colors-default-theme-accent-1, var(--accent-color)); - color: var(--simple-colors-default-theme-accent-12, var(--accent-color)); - border-radius: 8px; flex-direction: column; - margin: var(--ddd-spacing-2); - padding: var(--ddd-spacing-4); - border: solid 1px var(--simple-colors-default-theme-accent-12, var(--accent-color)); - width: 300px; + gap: var(--ddd-spacing-3); + margin-top: 0; + width: 100%; + } + .filter-btn { + display: flex; + align-items: center; + gap: var(--ddd-spacing-3); + padding: var(--ddd-spacing-3) var(--ddd-spacing-5); + border-radius: var(--ddd-radius-rounded); + border: none; + background: var(--ddd-accent-2, #f2f2f4); + color: var(--ddd-primary-2, #001e44); + font-size: 1rem; + font-family: var(--ddd-font-primary); + font-weight: 600; + cursor: pointer; + box-shadow: var(--ddd-boxShadow-sm); + transition: box-shadow 0.2s; + outline: none; + min-height: 44px; + } + .filter-btn.active, + .filter-btn:active { + background: var(--ddd-primary-8, #009cde); + color: #fff; + box-shadow: var(--ddd-boxShadow-md); + } + .filter-btn:hover { + background: var(--ddd-accent-3, #e4e5e7); + } + .filter-btn .icon { + font-size: 22px; + color: inherit; + display: flex; + align-items: center; + } + input[type="checkbox"] { + display: none; + } + .reset-button { + margin-top: var(--ddd-spacing-5); + background: var(--ddd-primary-2, #001e44); + border: none; + color: #fff; + border-radius: var(--ddd-radius-rounded); + font-size: 1rem; + font-family: var(--ddd-font-primary); + font-weight: 600; + padding: var(--ddd-spacing-3) var(--ddd-spacing-5); + display: flex; + align-items: center; + gap: var(--ddd-spacing-3); + box-shadow: var(--ddd-boxShadow-sm); + } + .reset-button:hover { + background: var(--ddd-primary-8, #009cde); } .collapseFilter { display: none; } + @media (max-width: 780px) { :host .filter { display: none; @@ -174,6 +267,7 @@ export class AppHaxUseCaseFilter extends LitElement { display: flex; } } + @media (max-width: 600px) { :host .filter { display: none; @@ -187,31 +281,10 @@ export class AppHaxUseCaseFilter extends LitElement { display: flex; } } - .filterButtons { - margin-top: 8px; - text-align: left; - align-items: flex-start; - justify-self: flex-start; - display: flex; - flex-direction: column; - gap: var(--ddd-spacing-2); - width: 150px; - } - .filterButtons label { - font-family: var(--ddd-font-primary); - font-size: 16px; - display: flex; - align-items: center; - justify-content: flex-start; - padding: 8px; - } - input[type="checkbox"] { - width: 30px; - } `, ]; } - + testKeydown(e) { if (e.key === "Escape" || e.key === "Enter") { this.toggleSearch(); @@ -237,20 +310,28 @@ export class AppHaxUseCaseFilter extends LitElement { @input="${this.handleSearch}" @keydown="${this.testKeydown}" type="text" - placeholder="Search Templates & Sites" + placeholder="Search Sites & Templates" />
    ${this.filters.map( - (filter) => html` -
    ${this.appBody(this.appMode)}
    diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index c8f63aaba7..2276d07a40 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -102,16 +102,22 @@ export class AppHaxUseCaseFilter extends LitElement { box-sizing: border-box; } #returnToSection app-hax-search-results { - display: grid; - grid-template-columns: repeat(3, 1fr); + display: flex; gap: 24px; /* or your preferred gap */ width: 100%; - max-width: 100%; + max-width: 824px; min-height: 120px; box-sizing: border-box; justify-items: center; align-items: stretch; + flex-direction: row; + overflow-x: auto; + scroll-behavior: smooth; } + :host(:not([show-filter])) app-hax-search-results { + width: 100%; + } + h4, .returnTo h4, .startNew h4 { @@ -244,6 +250,7 @@ export class AppHaxUseCaseFilter extends LitElement { padding: var(--ddd-spacing-3) var(--ddd-spacing-5); display: flex; align-items: center; + justify-content: center; gap: var(--ddd-spacing-3); box-shadow: var(--ddd-boxShadow-sm); } @@ -346,7 +353,7 @@ export class AppHaxUseCaseFilter extends LitElement {

    Return to...

    diff --git a/elements/app-hax/src/app-hax.js b/elements/app-hax/src/app-hax.js index 2a8f94a0df..89f9f070b9 100644 --- a/elements/app-hax/src/app-hax.js +++ b/elements/app-hax/src/app-hax.js @@ -1269,19 +1269,6 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} ` : ``} - -
    - -
    -
    - -
    ${this.appBody(this.appMode)}
    From 2186cc8644c67a987bc054d5253dd49def5b1fe6 Mon Sep 17 00:00:00 2001 From: SkylerKoba88 Date: Thu, 1 May 2025 11:06:26 -0400 Subject: [PATCH 096/166] colors --- .../app-hax/lib/v2/app-hax-use-case-filter.js | 39 ++++++++++++------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index 2276d07a40..d69f185ca3 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -70,6 +70,7 @@ export class AppHaxUseCaseFilter extends LitElement { box-sizing: border-box; max-width: 100vw; overflow-x: hidden; + position: relative; } .leftSection, .rightSection { display: flex; @@ -85,11 +86,12 @@ export class AppHaxUseCaseFilter extends LitElement { margin-right: 24px; padding-top: 0; box-sizing: border-box; + position: sticky; } .rightSection { - flex: 1 1 0; - width: 100%; + flex: 1; min-width: 0; + width: 100%; box-sizing: border-box; display: flex; flex-direction: column; @@ -101,16 +103,20 @@ export class AppHaxUseCaseFilter extends LitElement { min-height: 330px; box-sizing: border-box; } + #returnToSection { + width: 100%; + } #returnToSection app-hax-search-results { display: flex; - gap: 24px; /* or your preferred gap */ - width: 100%; + gap: 24px; max-width: 824px; + min-width: 824px; min-height: 120px; box-sizing: border-box; - justify-items: center; + justify-content: flex-start; align-items: stretch; flex-direction: row; + flex-wrap: nowrap; overflow-x: auto; scroll-behavior: smooth; } @@ -149,7 +155,7 @@ export class AppHaxUseCaseFilter extends LitElement { font-size: 15px; border-radius: var(--ddd-radius-md); border: var(--ddd-border-xs); - background: var(--ddd-accent-2, #f2f2f4); + background: var(--simple-colors-default-theme-accent-2, var(--accent-color)); color: #222; transition: border 0.2s; box-sizing: border-box; @@ -159,15 +165,15 @@ export class AppHaxUseCaseFilter extends LitElement { } input[type="text"]:focus { border: var(--ddd-border-sm); - background: #fff; + background: var(--simple-colors-default-theme-accent-1, var(--accent-color)); outline: none; } .search-icon { position: absolute; left: 16px; - top: 50%; - transform: translateY(-50%); - font-size: 22px; + top: 65%; + transform: translateY(-60%); + font-size: 18px; color: var(--ddd-primary-8, #009cde); align-self: center; } @@ -178,10 +184,11 @@ export class AppHaxUseCaseFilter extends LitElement { display: flex; flex-direction: column; gap: var(--ddd-spacing-4); - background: var(--ddd-accent-6, #fff); + background: var(--simple-colors-default-theme-accent-1, var(--accent-color)); border-radius: var(--ddd-radius-lg); box-shadow: var(--ddd-boxShadow-lg); border: var(--ddd-border-xs); + border-color: var(--simple-colors-default-theme-accent-3, var(accent-color)); padding: var(--ddd-spacing-6) var(--ddd-spacing-5) var(--ddd-spacing-5) var(--ddd-spacing-5); margin-top: 0; margin-left: 24px; @@ -209,8 +216,8 @@ export class AppHaxUseCaseFilter extends LitElement { padding: var(--ddd-spacing-3) var(--ddd-spacing-5); border-radius: var(--ddd-radius-rounded); border: none; - background: var(--ddd-accent-2, #f2f2f4); - color: var(--ddd-primary-2, #001e44); + background: var(--simple-colors-default-theme-accent-2, var(--accent-color)); + color: var( --simple-colors-default-theme-blue-11, var(--accent-color)); font-size: 1rem; font-family: var(--ddd-font-primary); font-weight: 600; @@ -230,7 +237,7 @@ export class AppHaxUseCaseFilter extends LitElement { background: var(--ddd-accent-3, #e4e5e7); } .filter-btn .icon { - font-size: 22px; + font-size: 18px; color: inherit; display: flex; align-items: center; @@ -255,7 +262,9 @@ export class AppHaxUseCaseFilter extends LitElement { box-shadow: var(--ddd-boxShadow-sm); } .reset-button:hover { - background: var(--ddd-primary-8, #009cde); + background-color: var(--simple-colors-default-theme-light-blue-7, var(--accent-color)); + //background: var(--ddd-primary-8, var(--ddd-primary-1)); + //background: #009cde; } .collapseFilter { display: none; From 1f413f45a434a774def45fe4afba4cedde245b6e Mon Sep 17 00:00:00 2001 From: izzabizz5 Date: Fri, 2 May 2025 13:51:17 -0400 Subject: [PATCH 097/166] commit --- .../app-hax/lib/v2/app-hax-use-case-filter.js | 29 +++++-------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index 8b868d6802..d5760f91b4 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -60,16 +60,12 @@ export class AppHaxUseCaseFilter extends LitElement { display: block; max-width: 100%; } - :host, *, *::before, *::after { - box-sizing: border-box; - } .contentSection { - display: flex; - align-items: stretch; - width: 100%; - box-sizing: border-box; - max-width: 100vw; - overflow-x: hidden; + display: flex; + align-items: flex-start; + justify-content: flex-start; + gap: 16px; + width: 100%; } .leftSection, .rightSection { display: flex; @@ -80,7 +76,6 @@ export class AppHaxUseCaseFilter extends LitElement { width: 340px; min-width: 260px; max-width: 380px; - flex: 0 0 340px; margin-left: 0; margin-right: 24px; padding-top: 0; @@ -101,17 +96,6 @@ export class AppHaxUseCaseFilter extends LitElement { min-height: 330px; box-sizing: border-box; } - #returnToSection app-hax-search-results { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 24px; /* or your preferred gap */ - width: 100%; - max-width: 100%; - min-height: 120px; - box-sizing: border-box; - justify-items: center; - align-items: stretch; - } h4, .returnTo h4, .startNew h4 { @@ -390,6 +374,9 @@ export class AppHaxUseCaseFilter extends LitElement { `; } + + + iconForFilter(filter) { switch (filter.toLowerCase()) { case "blog": From 4966d583bbed5a0f6422155d993a15a0c6febb20 Mon Sep 17 00:00:00 2001 From: btopro Date: Thu, 2 Oct 2025 09:09:40 -0400 Subject: [PATCH 098/166] empty for merge --- elements/app-hax/app-hax.js | 1429 ----------------------------------- 1 file changed, 1429 deletions(-) diff --git a/elements/app-hax/app-hax.js b/elements/app-hax/app-hax.js index c2a0ba5b73..e69de29bb2 100644 --- a/elements/app-hax/app-hax.js +++ b/elements/app-hax/app-hax.js @@ -1,1429 +0,0 @@ -import { css, html, unsafeCSS } from "lit"; -import { toJS, autorun } from "mobx"; -import { localStorageSet, localStorageGet } from "@haxtheweb/utils/utils.js"; -import "@haxtheweb/simple-tooltip/simple-tooltip.js"; -import { store } from "./lib/v1/AppHaxStore.js"; -import { I18NMixin } from "@haxtheweb/i18n-manager/lib/I18NMixin.js"; -import { AppHaxAPI } from "./lib/v1/AppHaxBackendAPI.js"; -import { SimpleTourManager } from "@haxtheweb/simple-popover/lib/simple-tour.js"; -import { SuperDaemonInstance } from "@haxtheweb/super-daemon/super-daemon.js"; -import "@haxtheweb/simple-toolbar/lib/simple-toolbar-button.js"; -import "@haxtheweb/simple-colors-shared-styles/simple-colors-shared-styles.js"; -import "./lib/v1/AppHaxRouter.js"; -import "./lib/v1/app-hax-label.js"; -import "./lib/v1/app-hax-top-bar.js"; -import { SimpleTourFinder } from "@haxtheweb/simple-popover/lib/SimpleTourFinder.js"; -import { DDD } from "@haxtheweb/d-d-d"; - -const logoutBtn = new URL("./lib/assets/images/Logout.svg", import.meta.url) - .href; -// toggle store darkmode -function darkToggle(e) { - if (e.matches) { - // dark mode - store.darkMode = true; - } else { - // light mode - store.darkMode = false; - } -} - -function soundToggle() { - store.soundStatus = !toJS(store.soundStatus); - localStorageSet("app-hax-soundStatus", toJS(store.soundStatus)); - store.appEl.playSound("click"); -} - -export class AppHax extends I18NMixin(SimpleTourFinder(DDD)) { - static get tag() { - return "app-hax"; - } - - _openExternalLink(link) { - globalThis.open(link, "_blank"); - } - - async _haxStoreContribute(type, tags, daemonTerm = null) { - let body = ""; - if (type == "merlin") { - var title = `[${type}] New command request from HAX daemon`; - body = `Location: ${globalThis.location.href} -Merlin command: ${daemonTerm} -What did you want merlin to do? -`; - } else { - var title = `[${type}] User report from HAX daemon`; - body = `Location: ${globalThis.location.href} -Browser: ${navigator.userAgent} -OS: ${navigator.userAgentData.platform} - ${navigator.deviceMemory}GB RAM - ${navigator.hardwareConcurrency} cores -Screen: ${globalThis.screen.width}x${globalThis.screen.height} -Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} -`; - if (navigator.getBattery) { - const stats = await globalThis.navigator.getBattery(); - body += `Battery: ${stats.level * 100}% -`; - } - // some things report the "type" of internet connection speed - // for terrible connections lets save frustration - if ( - navigator.connection && - globalThis.navigator.connection.effectiveType - ) { - body += `Connection: ${navigator.connection.effectiveType} -`; - } - body += `${type == "feature" ? `Your idea:` : `Bug you experienced:`} -`; - } - globalThis.open( - `https://github.com/haxtheweb/issues/issues/new?assignees=&labels=${tags}&template=issue-report.md&title=${title}&body=${encodeURIComponent( - body, - )}`, - "_blank", - ); - } - // eslint-disable-next-line class-methods-use-this - playSound(sound = "coin2") { - return new Promise((resolve) => { - if (store.soundStatus && store.appReady) { - let playSound = [ - "click", - "click2", - "coin", - "coin2", - "hit", - "success", - ].includes(sound) - ? sound - : "hit"; - this.audio = new Audio( - new URL(`./lib/assets/sounds/${playSound}.mp3`, import.meta.url).href, - ); - this.audio.volume = 0.3; - this.audio.onended = (event) => { - resolve(); - }; - this.audio.play(); - // resolve after 1s if sound failed to load - setTimeout(() => { - resolve(); - }, 1000); - } else { - resolve(); - } - }); - } - - /** - * A token refresh just failed so force to login prompt / state - */ - _tokenRefreshFailed(e) { - globalThis.dispatchEvent( - new CustomEvent("jwt-login-logout", { - composed: true, - bubbles: true, - cancelable: false, - detail: true, - }), - ); - setTimeout(() => { - this.reset(true); - }, 100); - } - - connectedCallback() { - super.connectedCallback(); - globalThis - .matchMedia("(prefers-color-scheme: dark)") - .addEventListener("change", darkToggle, { - signal: this.windowControllers.signal, - }); - globalThis.addEventListener("jwt-logged-in", this._jwtLoggedIn.bind(this), { - signal: this.windowControllers.signal, - }); - - globalThis.addEventListener( - "jwt-login-refresh-error", - this._tokenRefreshFailed.bind(this), - { signal: this.windowControllers.signal }, - ); - } - - goToLocation(location) { - globalThis.location = location; - } - - disconnectedCallback() { - this.windowControllers.abort(); - super.disconnectedCallback(); - } - - constructor() { - super(); - this.unlockComingSoon = false; - this.unlockTerrible = false; - this.t = this.t || {}; - - this.t = { - ...this.t, - selectPage: "Select page", - backToSiteList: "Back to site list", - listMySites: "List my sites", - cancel: "Cancel", - editDetails: "Page details", - add: "Add", - editSettings: "Edit settings", - source: "Source", - viewSource: "View source", - findMedia: "Find media", - undo: "Undo", - redo: "Redo", - media: "Media", - outline: "Outline", - blocks: "Blocks", - addBlock: "Add block", - addPage: "Add page", - addChildPage: "Add child page", - clonePage: "Clone page", - delete: "Delete page", - siteSettings: "Site settings", - close: "Close", - settings: "Settings", - edit: "Edit", - configureBlock: "Configure block", - configure: "Configure", - save: "Save", - home: "Home", - startNewJourney: "Start new journey", - newJourney: "New Journey", - accountInfo: "Account Info", - outlineDesigner: "Outline designer", - pageOutline: "Page outline", - more: "More", - siteActions: "Site actions", - insights: "Insights dashboard", - merlin: "Merlin", - summonMerlin: "Summon Merlin", - logOut: "Log out", - menu: "Menu", - showMore: "More", - }; - // Register localization for app-hax - this.registerLocalization({ - context: this, - namespace: "app-hax", - basePath: import.meta.url + "/../", - }); - if ( - typeof globalThis.speechSynthesis !== "undefined" && - (globalThis.SpeechRecognition || - globalThis.webkitSpeechRecognition || - globalThis.mozSpeechRecognition || - globalThis.msSpeechRecognition || - globalThis.oSpeechRecognition) - ) { - SuperDaemonInstance.voiceSearch = true; - } - SuperDaemonInstance.icon = "hax:wizard-hat"; - SuperDaemonInstance.appendContext("*"); - // ensure we are running HAX / ready and in edit mode before allowing commands to go through - SuperDaemonInstance.allowedCallback = () => { - if (toJS(store.appReady) && toJS(store.isLoggedIn)) { - return true; - } - return false; - }; - - // contribution helpers - SuperDaemonInstance.defineOption({ - title: "Tour of top menu buttons", - icon: "help", - tags: ["Help", "ui", "tour"], - priority: -1000, - value: { - target: this, - method: "helpClick", - args: [], - }, - eventName: "super-daemon-element-method", - path: "HAX/app/tour", - context: ["*"], - }); - - // contribution helpers - SuperDaemonInstance.defineOption({ - title: "Unlock hidden features", - icon: "hax:hax2022", - tags: ["Developer", "features", "hidden"], - value: { - target: this, - method: "fireUnlocked", - args: [], - }, - eventName: "super-daemon-element-method", - path: ">developer/hax/unlockAll", - context: [">"], - }); - // contribution helpers - SuperDaemonInstance.defineOption({ - title: "Unlock terrible 2000s themes", - icon: "hax:table-multiple", - tags: ["Developer", "terrible", "2000", "tables"], - value: { - target: this, - method: "fireTerrible", - args: [], - }, - eventName: "super-daemon-element-method", - path: ">developer/hax/terrible2000s", - context: [">"], - }); - SuperDaemonInstance.defineOption({ - title: "Go to site", - icon: "hax:hax2022", - tags: ["Sites", "Administration", "change"], - eventName: "super-daemon-run-program", - path: "HAX/action/goToSite", - value: { - name: "Go to site", - program: async (input, values) => { - let results = []; - const items = toJS(store.manifest.items); - items.forEach(async (site) => { - if ( - input == "" || - (site.metadata.site && - site.metadata.site.name && - site.metadata.site.name.includes(input)) - ) { - results.push({ - title: site.title, - icon: - site.metadata.theme && - site.metadata.theme.variables && - site.metadata.theme.variables.icon - ? site.metadata.theme.variables.icon - : "hax:hax2022", - tags: ["site", site.description], - value: { - target: this, - method: "goToLocation", - args: [site.slug], - }, - eventName: "super-daemon-element-method", - context: [ - "*", - "HAX/action/goToSite/" + site.metadata.site.name, - ], - path: "HAX/action/goToSite/" + site.metadata.site.name, - }); - } - }); - return results; - }, - }, - context: ["*"], - }); - // contribution helpers - SuperDaemonInstance.defineOption({ - title: "Join our Community", - icon: "hax:discord", - priority: -50, - tags: ["community", "discord", "chat", "help"], - value: { - target: this, - method: "_openExternalLink", - args: ["https://bit.ly/hax-discord"], - }, - eventName: "super-daemon-element-method", - path: "HAX/community/join", - context: ["logged-in", "CMS", "HAX", "*"], - }); - SuperDaemonInstance.defineOption({ - title: "User Tutorials", - icon: "hax:hax2022", - priority: -1000, - tags: ["Documentation", "community", "help"], - value: { - target: this, - method: "_openExternalLink", - args: ["https://haxtheweb.org/tutorials"], - }, - eventName: "super-daemon-element-method", - path: "HAX/community/tutorials", - context: ["logged-in", "CMS", "HAX", "*"], - }); - SuperDaemonInstance.defineOption({ - title: "User Documentation", - icon: "hax:hax2022", - tags: ["Documentation", "community", "help"], - value: { - target: this, - method: "_openExternalLink", - args: ["https://haxtheweb.org/documentation"], - }, - eventName: "super-daemon-element-method", - path: "HAX/community/documentation", - context: ["logged-in", "CMS", "HAX", "*"], - }); - SuperDaemonInstance.defineOption({ - title: "HAX Teaching Excellence", - icon: "hax:hax2022", - tags: ["Ontology", "community", "pedagogy", "documentation", "help"], - value: { - target: this, - method: "_openExternalLink", - args: ["https://haxtheweb.org/ontology"], - }, - eventName: "super-daemon-element-method", - path: "HAX/community/pedagogy", - context: ["logged-in", "CMS", "HAX", "*"], - }); - SuperDaemonInstance.defineOption({ - title: "Bug / issue", - icon: "mdi-social:github-circle", - tags: ["Bug report", "github", "git", "community", "issue queue"], - value: { - target: this, - method: "_haxStoreContribute", - args: ["bug", "POP,bug"], - }, - eventName: "super-daemon-element-method", - path: "HAX/community/contribute", - context: ["logged-in", "CMS", "HAX", "*"], - }); - SuperDaemonInstance.defineOption({ - title: "Idea / Feature request", - icon: "mdi-social:github-circle", - tags: [ - "Feature request", - "idea", - "github", - "git", - "community", - "issue queue", - ], - value: { - target: this, - method: "_haxStoreContribute", - args: ["feature", "POP,enhancement"], - }, - context: ["logged-in", "CMS", "HAX", "*"], - eventName: "super-daemon-element-method", - path: "HAX/community/contribute", - }); - this.windowControllers = new AbortController(); - this.__tour = SimpleTourManager; - this.__tour.registerNewTour({ - key: "hax", - name: "HAX top menu", - style: ` - simple-popover-manager::part(simple-popover) { - max-width: 250px; - font-family: sans-serif; - } - simple-popover-manager button { - font-family: sans-serif; - font-size: 12px; - margin: 0px 2px; - color: var(--simple-colors-default-theme-grey-12); - } - simple-popover-manager p { - font-family: sans-serif; - padding: 0; - margin: 0; - width: 250px; - font-size: 10px; - line-height: 20px; - } - simple-popover-manager h1 { - font-family: sans-serif; - margin: 0; - font-size: 12px; - width: 250px; - padding: 0; - } - simple-popover-manager::part(simple-popover-body), - simple-popover-manager::part(simple-popover-heading) { - color: black; - background-color: white; - font-family: sans-serif; - } - body.dark-mode simple-popover-manager::part(simple-popover-body), - body.dark-mode simple-popover-manager::part(simple-popover-heading) { - color: white; - background-color: black; - font-family: sans-serif; - } - body.dark-mode simple-popover-manager simple-icon-button-lite { - color: white; - background-color: black; - font-family: sans-serif; - } - `, - }); - this.tourName = "hax"; - // manage title when activeItem changes - autorun(() => { - const item = toJS(store.activeItem); - if (item && item.title) { - store.setPageTitle(item.title); - } - }); - autorun(() => { - this.siteReady = toJS(store.siteReady); - }); - autorun(() => { - const badDevice = toJS(store.badDevice); - if (badDevice === false) { - import("@haxtheweb/rpg-character/rpg-character.js"); - import("./lib/random-word/random-word.js"); - } else if (badDevice === true) { - globalThis.document.body.classList.add("bad-device"); - } - }); - this.userMenuOpen = false; - this.courses = []; - this.activeItem = {}; - this.phrases = { - new: [ - "What's ya name?", - "HAX to the moon", - "Welcome to the Jungle", - "We like to party", - "Build something awesome", - "Everything is awesome!", - "Everything is cool", - "When you're part of the team", - "When you're living our dream", - "Welcome to the up-side-down", - ], - return: [ - "Welcome back, take 2?", - "That wasn't very long", - "Stranger thiings have happened", - "Student driven platform", - "Faculty centered platform", - "Instructional designer influenced platform", - "Free, Open, Community driven", - "One brick at a time..", - "Sup?", - "You again? Awesome!", - "Let's do this", - "There can only be one ring...", - "There is another", - "Fancy that, I love HAX and you show up", - ], - }; - this.isNewUser = null; - this.basePath = "/"; - this.searchTerm = ""; - this.appMode = ""; - this.soundIcon = ""; - // full on store that does the heavy lifting - this.store = store; - // centralized sound source to not flood sounds when playing - this.sound = new Audio(); - // @todo need this from app deploy itself - autorun(() => { - this.isNewUser = toJS(store.isNewUser); - if ( - this.isNewUser && - toJS(store.appMode) !== "create" && - toJS(store.appMode) !== "404" - ) { - store.appMode = "create"; - setTimeout(() => { - store.createSiteSteps = true; - }, 0); - } - }); - autorun(() => { - this.userName = toJS(store.user.name); - }); - autorun(() => { - this.appMode = toJS(store.appMode); - }); - autorun(() => { - this.searchTerm = toJS(store.searchTerm); - }); - - /** - * When location changes update activeItem / mode of app - */ - autorun(async () => { - const location = toJS(store.location); - if (location && location.route) { - // verify this is a step vs other operations - if (!location.route.step) { - // support external site links - if (location.route.slug) { - this.reset(); - setTimeout(() => { - globalThis.location = location.route.slug; - }, 0); - } - // page miss is high check too - else if (location.route.name === "404") { - store.createSiteSteps = false; - store.appMode = "404"; - setTimeout(() => { - store.toast("the page miss.. it burns!!!", 3000, { - fire: true, - walking: true, - }); - }, 500); - } - // then home / landing page which is default expectation - else if ( - location.route.name === "home" || - location.route.name === "search" - ) { - store.appMode = "home"; - store.createSiteSteps = false; - } else { - //console.warn(location.route); - } - } else { - // we have a "step" based operation - store.appMode = "create"; - store.createSiteSteps = true; - } - } - }); - - autorun(() => { - if (store.routes.length > 0 && store.location === null) { - store.location = toJS(store.routes[0]); - } - }); - // manage dark mode - // only set this initially if we don't have an app state of our own - if (localStorageGet("app-hax-darkMode", null) === null) { - store.darkMode = globalThis.matchMedia( - "(prefers-color-scheme: dark)", - ).matches; - } - autorun(() => { - localStorageSet("app-hax-darkMode", toJS(store.darkMode)); - requestAnimationFrame(() => { - if (toJS(store.darkMode)) { - globalThis.document.body.classList.add("dark-mode"); - store.toast("I'm ascared of the dark", 2000, { fire: true }); - this.dark = true; - SuperDaemonInstance.dark = true; - SuperDaemonInstance.toastInstance.darkMode = true; - } else { - globalThis.document.body.classList.remove("dark-mode"); - store.toast("Sunny day it is", 2000, { hat: "random" }); - this.dark = false; - SuperDaemonInstance.dark = false; - SuperDaemonInstance.toastInstance.darkMode = false; - } - }); - }); - autorun(() => { - const mode = toJS(store.appMode); - if (mode) { - globalThis.document.body.classList.remove("app-hax-search"); - globalThis.document.body.classList.remove("app-hax-create"); - globalThis.document.body.classList.remove("app-hax-404"); - globalThis.document.body.classList.remove("app-hax-home"); - globalThis.document.body.classList.add(`app-hax-${mode}`); - } - }); - } - - static get properties() { - return { - ...super.properties, - t: { type: Object }, - unlockComingSoon: { type: Boolean }, - unlockTerrible: { type: Boolean }, - courses: { type: Array }, - userName: { type: String }, - activeItem: { type: Object }, - soundIcon: { type: String }, - searchTerm: { type: String }, - appMode: { type: String }, // minor context of what we're doing in the app for rendering - isNewUser: { type: Boolean }, - phrases: { type: Object }, - userMenuOpen: { type: Boolean }, // leave here to ensure hat change and sound effects happen - siteReady: { type: Boolean }, - basePath: { type: String, attribute: "base-path" }, - token: { type: String }, - }; - } - - // eslint-disable-next-line class-methods-use-this - reset(reload = false) { - // localStorage possible to be blocked by permission of system - try { - globalThis.localStorage.removeItem("app-hax-step"); - globalThis.localStorage.removeItem("app-hax-site"); - if (reload) { - // should always be a base tag for a SPA but just checking - if (document.querySelector("base")) { - globalThis.location = globalThis.document.querySelector("base").href; - } else { - globalThis.location.reload(); - } - } - } catch (e) { - //console.warn(e); - } - } - fireTerrible() { - this.unlockTerrible = true; - store.appEl.playSound("coin").then(() => { - store.appEl.playSound("coin2").then(() => { - store.appEl.playSound("success").then(() => { - SuperDaemonInstance.merlinSpeak( - "Enjoy these early 2000s table based layouts. May they remind you how never to web, again.", - ); - }); - }); - }); - } - fireUnlocked() { - this.unlockComingSoon = true; - store.appEl.playSound("coin").then(() => { - store.appEl.playSound("coin2").then(() => { - store.appEl.playSound("success").then(() => { - SuperDaemonInstance.merlinSpeak( - "Unbelievable! You, (Subject Name), must be the pride of (Subject Hometown). Enjoy all locked features as a boon!", - ); - }); - }); - }); - } - // eslint-disable-next-line class-methods-use-this - logout() { - globalThis.dispatchEvent( - new CustomEvent("jwt-login-logout", { - composed: true, - bubbles: true, - cancelable: false, - detail: true, - }), - ); - this.closeMenu(); - this.__logoutUserAction = true; - } - // only care about logouts - _jwtLoggedIn(e) { - if (e.detail === false && this.__logoutUserAction) { - this.__logoutUserAction = false; - setTimeout(() => { - this.reset(true); - }, 100); - } - } - - // eslint-disable-next-line class-methods-use-this - login() { - import("./lib/v1/app-hax-site-login.js").then(() => { - const p = globalThis.document.createElement("app-hax-site-login"); - if (this.querySelector('[slot="externalproviders"]')) { - const cloneSlot = this.querySelector( - '[slot="externalproviders"]', - ).cloneNode(true); - p.appendChild(cloneSlot); - } - import("@haxtheweb/simple-modal/simple-modal.js").then(() => { - setTimeout(() => { - this.dispatchEvent( - new CustomEvent("simple-modal-show", { - bubbles: true, - cancelable: true, - composed: true, - detail: { - title: "< login >", - elements: { content: p }, - modal: true, - styles: { - "--simple-modal-titlebar-background": "transparent", - "--simple-modal-titlebar-color": "black", - "--simple-modal-width": "40vw", - "--simple-modal-min-width": "300px", - "--simple-modal-z-index": "100000000", - "--simple-modal-height": "62vh", - "--simple-modal-min-height": "400px", - "--simple-modal-titlebar-height": "64px", - }, - }, - }), - ); - }, 0); - }); - }); - } - - static get styles() { - return [ - super.styles, - css` - :host { - display: block; - --app-hax-accent-color: light-dark(black, white); - --app-hax-background-color: light-dark(white, black); - --app-hax-background-color-active: var(--app-hax-accent-color); - --simple-toast-z-index: 10000000; - --simple-toast-color: light-dark(black, white); - --simple-toast-bg: light-dark(white, black); - --simple-toast-font-size: 16px; - --simple-toast-margin: 0; - --simple-toast-left: 0; - --simple-toast-bottom: 0; - --simple-toast-right: 0; - --simple-toast-height: 80px; - } - #home { - display: inline-flex; - } - simple-toolbar-button { - min-width: 48px; - margin: 0; - --simple-toolbar-border-color: #dddddddd; - height: 48px; - --simple-toolbar-button-disabled-border-color: transparent; - --simple-toolbar-button-disabled-opacity: 0.3; - --simple-toolbar-button-padding: 3px 6px; - --simple-toolbar-border-radius: 0; - } - simple-toolbar-button:hover, - simple-toolbar-button:active, - simple-toolbar-button:focus { - background-color: var(--hax-ui-background-color-accent); - color: var(--hax-ui-color); - } - simple-toolbar-button:hover, - simple-toolbar-button:active, - simple-toolbar-button:focus { - --simple-toolbar-border-color: var(--hax-ui-color-accent); - } - .wired-button-label { - clip: rect(0 0 0 0); - clip-path: inset(50%); - height: 1px; - overflow: hidden; - position: absolute; - white-space: nowrap; - width: 1px; - } - .topbar-character { - cursor: pointer; - display: inline-block; - border: none; - border-radius: 0px; - padding: 0 8px; - margin: 0 0 0 16px; - background-color: transparent; - height: 48px; - max-width: 160px; - } - .characterbtn-name { - color: var(--simple-colors-default-theme-grey-12); - font-family: "Press Start 2P", sans-serif; - margin-left: 8px; - font-size: 12px; - vertical-align: bottom; - line-height: 48px; - overflow: hidden; - text-overflow: ellipsis; - height: 48px; - word-break: break-all; - } - .topbar-character:hover, - .topbar-character:focus { - background-color: var(--simple-colors-default-theme-light-blue-4); - outline: var(--haxcms-color) solid 3px; - outline-offset: -3px; - height: 48px; - } - .topbar-character rpg-character { - margin: -4px -14px 0px -10px; - height: 52px; - width: 64px; - display: inline-block; - } - .content { - text-align: center; - margin-top: 24px; - } - .four04-character { - margin-top: 16px; - } - .start-journey { - display: flex; - padding-top: 20px; - justify-content: center; - } - app-hax-site-button { - max-width: 60vw; - justify-content: center; - } - app-hax-top-bar { - top: 0; - z-index: 1000; - right: 0; - left: 0; - position: fixed; - } - @media (max-width: 640px) { - simple-tooltip { - --simple-tooltip-font-size: 10px; - } - } - .label { - text-align: center; - } - app-hax-label { - animation: 0.8s ease-in-out 0s scrollin; - -webkit-animation: 0.8s ease-in-out 0s scrollin; - display: block; - overflow: hidden; - } - app-hax-label h1 { - font-weight: normal; - font-size: 4vw; - margin: 0; - padding: 0; - } - @keyframes scrollin { - from { - margin-top: -240px; - margin-bottom: 240px; - } - to { - margin-top: 0; - margin-bottom: 0; - } - } - .haxLogo { - --simple-icon-height: 40px; - --simple-icon-width: 40px; - margin: 4px; - color: var(--simple-colors-default-theme-grey-12); - cursor: pointer; - } - .soundToggle { - margin-right: 16px; - position: relative; - display: inline-flex; - vertical-align: top; - } - - .soundToggle img { - width: 24px; - height: 24px; - } - - app-hax-search-bar { - display: inline-flex; - } - main { - padding-top: 80px; - } - @media (max-width: 900px) { - .characterbtn-name { - display: none; - } - main { - padding-top: 64px; - } - } - app-hax-user-menu { - z-index: 1003; - } - .logout::part(menu-button) { - background-image: url("${unsafeCSS(logoutBtn)}"); - background-repeat: no-repeat; - background-position: center; - text-align: center; - background-size: cover; - border-top: 0px; - border-bottom: 0px; - padding: 10px; - } - app-hax-user-menu app-hax-user-menu-button::part(menu-button) { - font-family: "Press Start 2P", sans-serif; - font-size: 12px; - } - - random-word:not(:defined) { - display: none; - } - random-word { - transform: rotate(25deg); - position: absolute; - right: 10px; - top: 120px; - padding: 12px; - font-size: 12px; - border: 4px solid var(--simple-colors-default-theme-grey-12); - background-color: var(--simple-colors-default-theme-yellow-5); - color: var(--simple-colors-default-theme-grey-12); - width: 100px; - word-wrap: break-word; - text-align: center; - cursor: pointer; - user-select: none; - opacity: 1; - visibility: visible; - transition: all 0.3s ease-in-out; - } - #helpbtn { - --simple-icon-height: 50px; - --simple-icon-width: 50px; - right: 200px; - top: 100px; - padding: 4px; - background-color: var(--simple-colors-default-theme-grey-1); - border-radius: 50%; - position: absolute; - color: var(--simple-colors-default-theme-grey-12); - border: var(--simple-colors-default-theme-grey-12) 4px solid; - cursor: pointer; - } - @media (max-width: 800px) { - app-hax-site-button { - width: 320px; - max-width: 60vw; - --app-hax-site-button-font-size: 16px; - } - #helpbtn { - --simple-icon-height: 40px; - --simple-icon-width: 40px; - right: 8px; - top: 64px; - padding: 2px; - border: var(--simple-colors-default-theme-grey-12) 2px solid; - } - } - @media (prefers-reduced-motion: reduce) { - app-hax-label { - animation: none; - -webkit-animation: none; - } - } - @media (max-width: 640px) { - random-word { - display: none; - } - .content { - margin-top: 4px; - } - .start-journey { - padding-top: 0; - } - app-hax-site-button { - --app-hax-site-button-font-size: 12px; - } - } - @media (max-height: 500px) { - app-hax-label h1 { - font-family: monospace; - font-weight: normal; - font-size: 4vw; - margin: 0; - padding: 0; - } - } - `, - ]; - } - helpClick() { - // start the tour - store.appEl.playSound("coin2"); - this.__tour.startTour("hax"); - } - - updated(changedProperties) { - if (super.updated) { - super.updated(changedProperties); - } - // update the store as these get set via entrypoint of the app - // but used downstream in calls - changedProperties.forEach((oldValue, propName) => { - // API backend broker settings - if (["basePath"].includes(propName) && this[propName]) { - store.AppHaxAPI[propName] = this[propName]; - } - // settings for the store itself - if (["token"].includes(propName) && this[propName]) { - store[propName] = this[propName]; - } - }); - } - - firstUpdated(changedProperties) { - if (super.firstUpdated) { - super.firstUpdated(changedProperties); - } - // required for our early siteList updating - if (store.AppHaxAPI && this.basePath) { - store.AppHaxAPI.basePath = this.basePath; - } - import("./lib/v1/app-hax-steps.js"); - import("./lib/v1/app-hax-site-button.js"); - import("wired-elements/lib/wired-button.js"); - import("./lib/v1/app-hax-toast.js"); - import("./lib/v1/app-hax-wired-toggle.js"); - import("./lib/v1/app-hax-search-bar.js"); - import("./lib/v1/app-hax-search-results.js"); - import("./lib/v1/app-hax-user-menu.js"); - import("./lib/v1/app-hax-user-menu-button.js"); - this.dispatchEvent( - new CustomEvent("app-hax-loaded", { - composed: true, - bubbles: true, - cancelable: false, - detail: true, - }), - ); - store.appReady = true; - autorun(() => { - if (toJS(store.appReady)) { - globalThis.document.body.classList.add("app-loaded"); - } else { - globalThis.document.body.classList.remove("app-loaded"); - } - }); - store.appEl = this; - autorun(() => { - if (store.activeItem) { - this.activeItem = toJS(store.activeItem); - } - }); - autorun(() => { - this.soundIcon = toJS(store.soundStatus) - ? new URL("./lib/assets/images/FullVolume.svg", import.meta.url).href - : new URL("./lib/assets/images/Silence.svg", import.meta.url).href; - if (!toJS(store.soundStatus)) { - store.toast("Sound off.. hey! HELLO!?!", 2000, { fire: true }); - } else { - store.toast("You can hear me now? Good.", 2000, { hat: "random" }); - } - }); - // App is ready and the user is Logged in - autorun(async () => { - if ( - toJS(store.appReady) && - store.AppHaxAPI && - toJS(store.isLoggedIn) && - toJS(store.appSettings) && - toJS(store.refreshSiteList) - ) { - // Need this for the auto run when testing new user - // if we get new data source, trigger a rebuild of the site list - const results = await AppHaxAPI.makeCall("getSitesList"); - store.manifest = results.data; - } else if (toJS(store.appReady) && !toJS(store.isLoggedIn)) { - this.login(); - } - }); - } - - toggleMenu() { - this.userMenuOpen = !this.userMenuOpen; - store.appEl.playSound("click"); - } - - closeMenu() { - this.userMenuOpen = false; - } - - openMerlin() { - store.appEl.playSound("click"); - SuperDaemonInstance.open(); - } - - render() { - return html` -
    - - - - - - ${this.t.home} - - - - Toggle sound effects - - -
    - Not a fan of the (awesome) sound effects? You can mute them if you - prefer. -
    -
    - Toggle sound - - Toggle dark mode - -
    - You want to log out and be someone else? Create a new site? Click - your character. Your character is unique to you! -
    - - - - - - - - - -
    -
    -
    -
    - -
    - - ${this.activeItem && !this.siteReady - ? html` -

    ${this.activeItem.label}

    -
    - ${this.activeItem && this.activeItem.statement - ? this.activeItem.statement.replace( - ":structure", - toJS(store.site.structure), - ) - : ""} -
    - ` - : ``} - ${this.activeItem && this.siteReady - ? html` -

    ${toJS(store.site.name)}

    -
    - Is all ready, are you ready to build? -
    - ` - : ``} -
    -
    - -
    ${this.appBody(this.appMode)}
    -
    -
    `; - } - - getNewWord() { - this.shadowRoot.querySelector("random-word").getNewWord(); - store.appEl.playSound("click"); - } - - appBody(routine) { - let template = html``; - switch (routine) { - case "home": - case "search": - template = this.templateHome(); - break; - case "create": - template = this.templateCreate(); - break; - case "404": - default: - template = this.template404(); - break; - } - return template; - } - - templateHome() { - return html`
    - - - -
    - `; - } - - // eslint-disable-next-line class-methods-use-this - templateCreate() { - return html``; - } - - siteReadyToGo(e) { - import("@haxtheweb/multiple-choice/lib/confetti-container.js").then( - (module) => { - setTimeout(() => { - this.shadowRoot.querySelector("#confetti").setAttribute("popped", ""); - }, 0); - }, - ); - if (e.detail) { - store.siteReady = true; - } - } - - template404() { - return html`
    - - - - - This - fine - is -
    `; - } - - // ensure internal data is unset for store - startJourney() { - this.userMenuOpen = false; - store.createSiteSteps = false; - store.siteReady = false; - store.site.structure = null; - store.site.type = null; - store.site.theme = null; - store.site.name = null; - store.appMode = "create"; - store.appEl.playSound("click2"); - } -} -globalThis.customElements.define(AppHax.tag, AppHax); - -globalThis.AppHax = globalThis.AppHax || {}; - -globalThis.AppHax.requestAvailability = () => { - if (!globalThis.AppHax.instance && globalThis.document) { - globalThis.AppHax.instance = globalThis.document.querySelector(AppHax.tag); - } - return globalThis.AppHax.instance; -}; From 5f976d5f39d0b9195fbd819687719769d8a11520 Mon Sep 17 00:00:00 2001 From: btopro Date: Thu, 2 Oct 2025 09:16:53 -0400 Subject: [PATCH 099/166] https://github.com/haxtheweb/webcomponents/pull/729 --- elements/app-hax/app-hax.js | 1378 +++++++++++++++++++++++++++++++++++ 1 file changed, 1378 insertions(+) diff --git a/elements/app-hax/app-hax.js b/elements/app-hax/app-hax.js index e69de29bb2..89f9f070b9 100644 --- a/elements/app-hax/app-hax.js +++ b/elements/app-hax/app-hax.js @@ -0,0 +1,1378 @@ +import { css, html, unsafeCSS } from "lit"; +import { toJS, autorun } from "mobx"; +import { localStorageSet, localStorageGet } from "@haxtheweb/utils/utils.js"; +import "@haxtheweb/simple-tooltip/simple-tooltip.js"; +import { SimpleColors } from "@haxtheweb/simple-colors/simple-colors.js"; +import { store } from "./lib/v2/AppHaxStore.js"; +import { I18NMixin } from "@haxtheweb/i18n-manager/lib/I18NMixin.js"; +import { AppHaxAPI } from "./lib/v2/AppHaxBackendAPI.js"; +import { SimpleTourManager } from "@haxtheweb/simple-popover/lib/simple-tour.js"; +import { SuperDaemonInstance } from "@haxtheweb/super-daemon/super-daemon.js"; +import "@haxtheweb/simple-toolbar/lib/simple-toolbar-button.js"; +import "@haxtheweb/simple-colors-shared-styles/simple-colors-shared-styles.js"; +import "./lib/v2/AppHaxRouter.js"; +import "./lib/v2/app-hax-label.js"; +import "./lib/v2/app-hax-top-bar.js"; +import { SimpleTourFinder } from "@haxtheweb/simple-popover/lib/SimpleTourFinder.js"; +import "./lib/v2/app-hax-use-case.js"; +import "./lib/v2/app-hax-use-case-filter.js"; +import "./lib/v2/app-hax-search-results.js"; +import "./lib/v2/app-hax-scroll-button.js"; + +const logoutBtn = new URL("./lib/assets/images/Logout.svg", import.meta.url) + .href; +// toggle store darkmode +function darkToggle(e) { + if (e.matches) { + // dark mode + store.darkMode = true; + } else { + // light mode + store.darkMode = false; + } +} + +function soundToggle() { + store.soundStatus = !toJS(store.soundStatus); + localStorageSet("app-hax-soundStatus", toJS(store.soundStatus)); + store.appEl.playSound("click"); +} + +export class AppHax extends I18NMixin(SimpleTourFinder(SimpleColors)) { + static get tag() { + return "app-hax"; + } + + _openExternalLink(link) { + globalThis.open(link, "_blank"); + } + + async _haxStoreContribute(type, tags, daemonTerm = null) { + let body = ""; + if (type == "merlin") { + var title = `[${type}] New command request from HAX daemon`; + body = `Location: ${globalThis.location.href} +Merlin command: ${daemonTerm} +What did you want merlin to do? +`; + } else { + var title = `[${type}] User report from HAX daemon`; + body = `Location: ${globalThis.location.href} +Browser: ${navigator.userAgent} +OS: ${navigator.userAgentData.platform} - ${navigator.deviceMemory}GB RAM - ${navigator.hardwareConcurrency} cores +Screen: ${globalThis.screen.width}x${globalThis.screen.height} +Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} +`; + if (navigator.getBattery) { + const stats = await globalThis.navigator.getBattery(); + body += `Battery: ${stats.level * 100}% +`; + } + // some things report the "type" of internet connection speed + // for terrible connections lets save frustration + if ( + navigator.connection && + globalThis.navigator.connection.effectiveType + ) { + body += `Connection: ${navigator.connection.effectiveType} +`; + } + body += `${type == "feature" ? `Your idea:` : `Bug you experienced:`} +`; + } + globalThis.open( + `https://github.com/haxtheweb/issues/issues/new?assignees=&labels=${tags}&template=issue-report.md&title=${title}&body=${encodeURIComponent( + body, + )}`, + "_blank", + ); + } + // eslint-disable-next-line class-methods-use-this + playSound(sound = "coin2") { + return new Promise((resolve) => { + if (store.soundStatus && store.appReady) { + let playSound = [ + "click", + "click2", + "coin", + "coin2", + "hit", + "success", + ].includes(sound) + ? sound + : "hit"; + this.audio = new Audio( + new URL(`./lib/assets/sounds/${playSound}.mp3`, import.meta.url).href, + ); + this.audio.volume = 0.3; + this.audio.onended = (event) => { + resolve(); + }; + this.audio.play(); + // resolve after 1s if sound failed to load + setTimeout(() => { + resolve(); + }, 1000); + } else { + resolve(); + } + }); + } + + /** + * A token refresh just failed so force to login prompt / state + */ + _tokenRefreshFailed(e) { + globalThis.dispatchEvent( + new CustomEvent("jwt-login-logout", { + composed: true, + bubbles: true, + cancelable: false, + detail: true, + }), + ); + setTimeout(() => { + this.reset(true); + }, 100); + } + + connectedCallback() { + super.connectedCallback(); + globalThis + .matchMedia("(prefers-color-scheme: dark)") + .addEventListener("change", darkToggle, { + signal: this.windowControllers.signal, + }); + globalThis.addEventListener("jwt-logged-in", this._jwtLoggedIn.bind(this), { + signal: this.windowControllers.signal, + }); + + globalThis.addEventListener( + "jwt-login-refresh-error", + this._tokenRefreshFailed.bind(this), + { signal: this.windowControllers.signal }, + ); + } + + goToLocation(location) { + globalThis.location = location; + } + + disconnectedCallback() { + this.windowControllers.abort(); + super.disconnectedCallback(); + } + + constructor() { + super(); + this.unlockComingSoon = false; + this.unlockTerrible = false; + this.t = this.t || {}; + + this.t = { + ...this.t, + selectPage: "Select page", + backToSiteList: "Back to site list", + listMySites: "List my sites", + cancel: "Cancel", + editDetails: "Page details", + add: "Add", + editSettings: "Edit settings", + source: "Source", + viewSource: "View source", + findMedia: "Find media", + undo: "Undo", + redo: "Redo", + media: "Media", + outline: "Outline", + blocks: "Blocks", + addBlock: "Add block", + addPage: "Add page", + addChildPage: "Add child page", + clonePage: "Clone page", + delete: "Delete page", + siteSettings: "Site settings", + close: "Close", + settings: "Settings", + edit: "Edit", + configureBlock: "Configure block", + configure: "Configure", + save: "Save", + home: "Home", + startNewJourney: "Start new journey", + newJourney: "New Journey", + accountInfo: "Account Info", + outlineDesigner: "Outline designer", + pageOutline: "Page outline", + more: "More", + siteActions: "Site actions", + insights: "Insights dashboard", + merlin: "Merlin", + summonMerlin: "Summon Merlin", + logOut: "Log out", + menu: "Menu", + showMore: "More", + }; + if ( + typeof globalThis.speechSynthesis !== "undefined" && + (globalThis.SpeechRecognition || + globalThis.webkitSpeechRecognition || + globalThis.mozSpeechRecognition || + globalThis.msSpeechRecognition || + globalThis.oSpeechRecognition) + ) { + SuperDaemonInstance.voiceSearch = true; + } + SuperDaemonInstance.icon = "hax:wizard-hat"; + SuperDaemonInstance.appendContext("*"); + // ensure we are running HAX / ready and in edit mode before allowing commands to go through + SuperDaemonInstance.allowedCallback = () => { + if (toJS(store.appReady) && toJS(store.isLoggedIn)) { + return true; + } + return false; + }; + + // contribution helpers + SuperDaemonInstance.defineOption({ + title: "Tour of top menu buttons", + icon: "help", + tags: ["Help", "ui", "tour"], + priority: -1000, + value: { + target: this, + method: "helpClick", + args: [], + }, + eventName: "super-daemon-element-method", + path: "HAX/app/tour", + context: ["*"], + }); + + // contribution helpers + SuperDaemonInstance.defineOption({ + title: "Unlock hidden features", + icon: "hax:hax2022", + tags: ["Developer", "features", "hidden"], + value: { + target: this, + method: "fireUnlocked", + args: [], + }, + eventName: "super-daemon-element-method", + path: ">developer/hax/unlockAll", + context: [">"], + }); + // contribution helpers + SuperDaemonInstance.defineOption({ + title: "Unlock terrible 2000s themes", + icon: "hax:table-multiple", + tags: ["Developer", "terrible", "2000", "tables"], + value: { + target: this, + method: "fireTerrible", + args: [], + }, + eventName: "super-daemon-element-method", + path: ">developer/hax/terrible2000s", + context: [">"], + }); + SuperDaemonInstance.defineOption({ + title: "Go to site", + icon: "hax:hax2022", + tags: ["Sites", "Administration", "change"], + eventName: "super-daemon-run-program", + path: "HAX/action/goToSite", + value: { + name: "Go to site", + program: async (input, values) => { + let results = []; + const items = toJS(store.manifest.items); + items.forEach(async (site) => { + if ( + input == "" || + (site.metadata.site && + site.metadata.site.name && + site.metadata.site.name.includes(input)) + ) { + results.push({ + title: site.title, + icon: + site.metadata.theme && + site.metadata.theme.variables && + site.metadata.theme.variables.icon + ? site.metadata.theme.variables.icon + : "hax:hax2022", + tags: ["site", site.description], + value: { + target: this, + method: "goToLocation", + args: [site.slug], + }, + eventName: "super-daemon-element-method", + context: [ + "*", + "HAX/action/goToSite/" + site.metadata.site.name, + ], + path: "HAX/action/goToSite/" + site.metadata.site.name, + }); + } + }); + return results; + }, + }, + context: ["*"], + }); + // contribution helpers + SuperDaemonInstance.defineOption({ + title: "Join our Community", + icon: "hax:discord", + priority: -100, + tags: ["community", "discord", "chat", "help"], + value: { + target: this, + method: "_openExternalLink", + args: ["https://bit.ly/hax-discord"], + }, + eventName: "super-daemon-element-method", + path: "HAX/community/join", + context: ["logged-in", "CMS", "HAX", "*"], + }); + SuperDaemonInstance.defineOption({ + title: "User Tutorials", + icon: "hax:hax2022", + priority: -1000, + tags: ["Documentation", "community", "help"], + value: { + target: this, + method: "_openExternalLink", + args: ["https://haxtheweb.org/tutorials"], + }, + eventName: "super-daemon-element-method", + path: "HAX/community/tutorials", + context: ["logged-in", "CMS", "HAX", "*"], + }); + SuperDaemonInstance.defineOption({ + title: "User Documentation", + icon: "hax:hax2022", + tags: ["Documentation", "community", "help"], + value: { + target: this, + method: "_openExternalLink", + args: ["https://haxtheweb.org/documentation"], + }, + eventName: "super-daemon-element-method", + path: "HAX/community/documentation", + context: ["logged-in", "CMS", "HAX", "*"], + }); + SuperDaemonInstance.defineOption({ + title: "HAX Teaching Excellence", + icon: "hax:hax2022", + tags: ["Ontology", "community", "pedagogy", "documentation", "help"], + value: { + target: this, + method: "_openExternalLink", + args: ["https://haxtheweb.org/ontology"], + }, + eventName: "super-daemon-element-method", + path: "HAX/community/pedagogy", + context: ["logged-in", "CMS", "HAX", "*"], + }); + SuperDaemonInstance.defineOption({ + title: "Bug / issue", + icon: "mdi-social:github-circle", + tags: ["Bug report", "github", "git", "community", "issue queue"], + value: { + target: this, + method: "_haxStoreContribute", + args: ["bug", "POP,bug"], + }, + eventName: "super-daemon-element-method", + path: "HAX/community/contribute", + context: ["logged-in", "CMS", "HAX", "*"], + }); + SuperDaemonInstance.defineOption({ + title: "Idea / Feature request", + icon: "mdi-social:github-circle", + tags: [ + "Feature request", + "idea", + "github", + "git", + "community", + "issue queue", + ], + value: { + target: this, + method: "_haxStoreContribute", + args: ["feature", "POP,enhancement"], + }, + context: ["logged-in", "CMS", "HAX", "*"], + eventName: "super-daemon-element-method", + path: "HAX/community/contribute", + }); + this.windowControllers = new AbortController(); + this.__tour = SimpleTourManager; + this.__tour.registerNewTour({ + key: "hax", + name: "HAX top menu", + style: ` + simple-popover-manager::part(simple-popover) { + max-width: 250px; + font-family: sans-serif; + } + simple-popover-manager button { + font-family: sans-serif; + font-size: 12px; + margin: 0px 2px; + color: var(--simple-colors-default-theme-grey-12); + } + simple-popover-manager p { + font-family: sans-serif; + padding: 0; + margin: 0; + width: 250px; + font-size: 10px; + line-height: 20px; + } + simple-popover-manager h1 { + font-family: sans-serif; + margin: 0; + font-size: 12px; + width: 250px; + padding: 0; + } + simple-popover-manager::part(simple-popover-body), + simple-popover-manager::part(simple-popover-heading) { + color: black; + background-color: white; + font-family: sans-serif; + } + body.dark-mode simple-popover-manager::part(simple-popover-body), + body.dark-mode simple-popover-manager::part(simple-popover-heading) { + color: white; + background-color: black; + font-family: sans-serif; + } + body.dark-mode simple-popover-manager simple-icon-button-lite { + color: white; + background-color: black; + font-family: sans-serif; + } + `, + }); + this.tourName = "hax"; + // manage title when activeItem changes + autorun(() => { + const item = toJS(store.activeItem); + if (item && item.title) { + store.setPageTitle(item.title); + } + }); + autorun(() => { + this.siteReady = toJS(store.siteReady); + }); + autorun(() => { + const badDevice = toJS(store.badDevice); + if (badDevice === false) { + import("@haxtheweb/rpg-character/rpg-character.js"); + } else if (badDevice === true) { + globalThis.document.body.classList.add("bad-device"); + } + }); + this.userMenuOpen = false; + this.courses = []; + this.activeItem = {}; + this.phrases = { + new: [ + "What's ya name?", + "HAX to the moon", + "Welcome to the Jungle", + "We like to party", + "Build something awesome", + "Everything is awesome!", + "Everything is cool", + "When you're part of the team", + "When you're living our dream", + "Welcome to the up-side-down", + ], + return: [ + "Welcome back, take 2?", + "That wasn't very long", + "Stranger thiings have happened", + "Student driven platform", + "Faculty centered platform", + "Instructional designer influenced platform", + "Free, Open, Community driven", + "One brick at a time..", + "Sup?", + "You again? Awesome!", + "Let's do this", + "There can only be one ring...", + "There is another", + "Fancy that, I love HAX and you show up", + ], + }; + this.isNewUser = null; + this.basePath = "/"; + this.searchTerm = ""; + this.appMode = ""; + this.soundIcon = ""; + // full on store that does the heavy lifting + this.store = store; + // centralized sound source to not flood sounds when playing + this.sound = new Audio(); + // @todo need this from app deploy itself + autorun(() => { + this.isNewUser = toJS(store.isNewUser); + if ( + this.isNewUser && + toJS(store.appMode) !== "create" && + toJS(store.appMode) !== "404" + ) { + store.appMode = "create"; + setTimeout(() => { + store.createSiteSteps = true; + }, 0); + } + }); + autorun(() => { + this.userName = toJS(store.user.name); + }); + autorun(() => { + this.appMode = toJS(store.appMode); + }); + autorun(() => { + this.searchTerm = toJS(store.searchTerm); + }); + + /** + * When location changes update activeItem / mode of app + */ + autorun(async () => { + const location = toJS(store.location); + if (location && location.route) { + // verify this is a step vs other operations + if (!location.route.step) { + // support external site links + if (location.route.slug) { + this.reset(); + setTimeout(() => { + globalThis.location = location.route.slug; + }, 0); + } + // page miss is high check too + else if (location.route.name === "404") { + store.createSiteSteps = false; + store.appMode = "404"; + setTimeout(() => { + store.toast("the page miss.. it burns!!!", 3000, { + fire: true, + walking: true, + }); + }, 500); + } + // then home / landing page which is default expectation + else if ( + location.route.name === "home" || + location.route.name === "search" + ) { + store.appMode = "home"; + store.createSiteSteps = false; + } else { + //console.warn(location.route); + } + } else { + // we have a "step" based operation + store.appMode = "create"; + store.createSiteSteps = true; + } + } + }); + + autorun(() => { + if (store.routes.length > 0 && store.location === null) { + store.location = toJS(store.routes[0]); + } + }); + // manage dark mode + // only set this initially if we don't have an app state of our own + if (localStorageGet("app-hax-darkMode", null) === null) { + store.darkMode = globalThis.matchMedia( + "(prefers-color-scheme: dark)", + ).matches; + } + autorun(() => { + localStorageSet("app-hax-darkMode", toJS(store.darkMode)); + requestAnimationFrame(() => { + if (toJS(store.darkMode)) { + globalThis.document.body.classList.add("dark-mode"); + store.toast("I'm ascared of the dark", 2000, { fire: true }); + this.dark = true; + SuperDaemonInstance.dark = true; + SuperDaemonInstance.toastInstance.darkMode = true; + } else { + globalThis.document.body.classList.remove("dark-mode"); + store.toast("Sunny day it is", 2000, { hat: "random" }); + this.dark = false; + SuperDaemonInstance.dark = false; + SuperDaemonInstance.toastInstance.darkMode = false; + } + }); + }); + autorun(() => { + const mode = toJS(store.appMode); + if (mode) { + globalThis.document.body.classList.remove("app-hax-search"); + globalThis.document.body.classList.remove("app-hax-create"); + globalThis.document.body.classList.remove("app-hax-404"); + globalThis.document.body.classList.remove("app-hax-home"); + globalThis.document.body.classList.add(`app-hax-${mode}`); + } + }); + } + + static get properties() { + return { + ...super.properties, + unlockComingSoon: { type: Boolean }, + unlockTerrible: { type: Boolean }, + courses: { type: Array }, + userName: { type: String }, + activeItem: { type: Object }, + soundIcon: { type: String }, + searchTerm: { type: String }, + appMode: { type: String }, // minor context of what we're doing in the app for rendering + isNewUser: { type: Boolean }, + phrases: { type: Object }, + userMenuOpen: { type: Boolean }, // leave here to ensure hat change and sound effects happen + siteReady: { type: Boolean }, + basePath: { type: String, attribute: "base-path" }, + token: { type: String }, + }; + } + + // eslint-disable-next-line class-methods-use-this + reset(reload = false) { + // localStorage possible to be blocked by permission of system + try { + globalThis.localStorage.removeItem("app-hax-step"); + globalThis.localStorage.removeItem("app-hax-site"); + if (reload) { + // should always be a base tag for a SPA but just checking + if (document.querySelector("base")) { + globalThis.location = globalThis.document.querySelector("base").href; + } else { + globalThis.location.reload(); + } + } + } catch (e) { + //console.warn(e); + } + } + fireTerrible() { + this.unlockTerrible = true; + store.appEl.playSound("coin").then(() => { + store.appEl.playSound("coin2").then(() => { + store.appEl.playSound("success").then(() => { + SuperDaemonInstance.merlinSpeak( + "Enjoy these early 2000s table based layouts. May they remind you how never to web, again.", + ); + }); + }); + }); + } + fireUnlocked() { + this.unlockComingSoon = true; + store.appEl.playSound("coin").then(() => { + store.appEl.playSound("coin2").then(() => { + store.appEl.playSound("success").then(() => { + SuperDaemonInstance.merlinSpeak( + "Unbelievable! You, (Subject Name), must be the pride of (Subject Hometown). Enjoy all locked features as a boon!", + ); + }); + }); + }); + } + // eslint-disable-next-line class-methods-use-this + logout() { + globalThis.dispatchEvent( + new CustomEvent("jwt-login-logout", { + composed: true, + bubbles: true, + cancelable: false, + detail: true, + }), + ); + this.closeMenu(); + this.__logoutUserAction = true; + } + // only care about logouts + _jwtLoggedIn(e) { + if (e.detail === false && this.__logoutUserAction) { + this.__logoutUserAction = false; + setTimeout(() => { + this.reset(true); + }, 100); + } + } + + // eslint-disable-next-line class-methods-use-this + login() { + import("./lib/v2/app-hax-site-login.js").then(() => { + const p = globalThis.document.createElement("app-hax-site-login"); + if (this.querySelector('[slot="externalproviders"]')) { + const cloneSlot = this.querySelector( + '[slot="externalproviders"]', + ).cloneNode(true); + p.appendChild(cloneSlot); + } + import("@haxtheweb/simple-modal/simple-modal.js").then(() => { + setTimeout(() => { + this.dispatchEvent( + new CustomEvent("simple-modal-show", { + bubbles: true, + cancelable: true, + composed: true, + detail: { + title: "< login >", + elements: { content: p }, + modal: true, + styles: { + "--simple-modal-titlebar-background": "transparent", + "--simple-modal-titlebar-color": "black", + "--simple-modal-width": "40vw", + "--simple-modal-min-width": "300px", + "--simple-modal-z-index": "100000000", + "--simple-modal-height": "62vh", + "--simple-modal-min-height": "400px", + "--simple-modal-titlebar-height": "64px", + }, + }, + }), + ); + }, 0); + }); + }); + } + + static get styles() { + return [ + super.styles, + css` + :host { + display: block; + --app-hax-background-color-active: var(--app-hax-accent-color); + } + #home { + display: inline-flex; + } + #wt { + border: solid 1px var(--simple-colors-default-theme-accent-12, var(--accent-color)); + } + simple-toolbar-button { + min-width: 48px; + margin: 0; + --simple-toolbar-border-color: #dddddddd; + height: 48px; + --simple-toolbar-button-disabled-border-color: transparent; + --simple-toolbar-button-disabled-opacity: 0.3; + --simple-toolbar-button-padding: 3px 6px; + --simple-toolbar-border-radius: 0; + } + simple-toolbar-button:hover, + simple-toolbar-button:active, + simple-toolbar-button:focus { + background-color: var(--hax-ui-background-color-accent); + color: var(--hax-ui-color); + } + simple-toolbar-button:hover, + simple-toolbar-button:active, + simple-toolbar-button:focus { + --simple-toolbar-border-color: var(--hax-ui-color-accent); + } + .wired-button-label { + clip: rect(0 0 0 0); + clip-path: inset(50%); + height: 1px; + overflow: hidden; + position: absolute; + white-space: nowrap; + width: 1px; + } + .topbar-character { + cursor: pointer; + display: inline-block; + border: none; + border-radius: 0px; + padding: 0 8px; + margin: 0 0 0 16px; + background-color: transparent; + height: 48px; + max-width: 160px; + } + .characterbtn-name { + color: var(--simple-colors-default-theme-grey-12); + font-family: "Press Start 2P", sans-serif; + margin-left: 8px; + font-size: 12px; + vertical-align: bottom; + line-height: 48px; + overflow: hidden; + text-overflow: ellipsis; + height: 48px; + word-break: break-all; + } + .topbar-character:hover, + .topbar-character:focus { + background-color: var(--simple-colors-default-theme-light-blue-4); + outline: var(--haxcms-color) solid 3px; + outline-offset: -3px; + height: 48px; + } + .topbar-character rpg-character { + margin: -4px -14px 0px -10px; + height: 52px; + width: 64px; + display: inline-block; + } + .content { + text-align: center; + margin-top: 24px; + } + .four04-character { + margin-top: 16px; + } + .start-journey { + display: flex; + padding-top: 20px; + justify-content: center; + } + app-hax-site-button { + max-width: 60vw; + justify-content: center; + } + app-hax-top-bar { + top: 0; + z-index: 1000; + right: 0; + left: 0; + position: fixed; + } + @media (max-width: 640px) { + simple-tooltip { + --simple-tooltip-font-size: 10px; + } + } + .label { + display: inline-flex; + text-align: flex-start; + align-items: center; + } + app-hax-label { + animation: 0.8s ease-in-out 0s scrollin; + -webkit-animation: 0.8s ease-in-out 0s scrollin; + display: flex; + align-self: flex-start; + overflow: hidden; + margin-left: 24px; + margin-right: 24px; + } + app-hax-label h1 { + font-weight: normal; + font-size: 4vw; + margin: 0; + padding: 0; + } + @keyframes scrollin { + from { + margin-top: -240px; + margin-bottom: 240px; + } + to { + margin-top: 0; + margin-bottom: 0; + } + } + .haxLogo { + --simple-icon-height: 40px; + --simple-icon-width: 40px; + margin: 4px; + color: var(--simple-colors-default-theme-grey-12); + cursor: pointer; + } + .soundToggle { + margin-right: 16px; + position: relative; + display: inline-flex; + vertical-align: top; + } + + .soundToggle img { + width: 24px; + height: 24px; + } + + app-hax-search-bar { + display: inline-flex; + } + main { + padding-top: 80px; + } + @media (max-width: 900px) { + .characterbtn-name { + display: none; + } + main { + padding-top: 64px; + } + } + app-hax-user-menu { + z-index: 1003; + } + .logout::part(menu-button) { + background-image: url("${unsafeCSS(logoutBtn)}"); + background-repeat: no-repeat; + background-position: center; + text-align: center; + background-size: cover; + border-top: 0px; + border-bottom: 0px; + padding: 10px; + } + app-hax-user-menu app-hax-user-menu-button::part(menu-button) { + font-family: "Press Start 2P", sans-serif; + font-size: 12px; + } + #helpbtn { + --simple-icon-height: 50px; + --simple-icon-width: 50px; + right: 200px; + top: 100px; + padding: 4px; + background-color: var(--simple-colors-default-theme-grey-1); + border-radius: 50%; + position: absolute; + color: var(--simple-colors-default-theme-grey-12); + border: var(--simple-colors-default-theme-grey-12) 4px solid; + cursor: pointer; + } + @media (max-width: 800px) { + app-hax-site-button { + width: 320px; + max-width: 60vw; + --app-hax-site-button-font-size: 16px; + } + #helpbtn { + --simple-icon-height: 40px; + --simple-icon-width: 40px; + right: 8px; + top: 64px; + padding: 2px; + border: var(--simple-colors-default-theme-grey-12) 2px solid; + } + } + @media (prefers-reduced-motion: reduce) { + app-hax-label { + animation: none; + -webkit-animation: none; + } + } + @media (max-width: 640px) { + .content { + margin-top: 4px; + } + .start-journey { + padding-top: 0; + } + + app-hax-site-button { + --app-hax-site-button-font-size: 12px; + } + } + @media (max-height: 500px) { + app-hax-label h1 { + font-family: monospace; + font-weight: normal; + font-size: 4vw; + margin: 0; + padding: 0; + } + } + `, + ]; + } + helpClick() { + // start the tour + store.appEl.playSound("coin2"); + this.__tour.startTour("hax"); + } + + updated(changedProperties) { + if (super.updated) { + super.updated(changedProperties); + } + // update the store as these get set via entrypoint of the app + // but used downstream in calls + changedProperties.forEach((oldValue, propName) => { + // API backend broker settings + if (["basePath"].includes(propName) && this[propName]) { + store.AppHaxAPI[propName] = this[propName]; + } + // settings for the store itself + if (["token"].includes(propName) && this[propName]) { + store[propName] = this[propName]; + } + }); + } + + firstUpdated(changedProperties) { + if (super.firstUpdated) { + super.firstUpdated(changedProperties); + } + // required for our early siteList updating + if (store.AppHaxAPI && this.basePath) { + store.AppHaxAPI.basePath = this.basePath; + } + import("./lib/v2/app-hax-steps.js"); + import("./lib/v2/app-hax-site-button.js"); + import("wired-elements/lib/wired-button.js"); + import("./lib/v2/app-hax-toast.js"); + import("./lib/v2/app-hax-wired-toggle.js"); + import("./lib/v2/app-hax-search-bar.js"); + import("./lib/v2/app-hax-search-results.js"); + import("./lib/v2/app-hax-user-menu.js"); + import("./lib/v2/app-hax-user-menu-button.js"); + this.dispatchEvent( + new CustomEvent("app-hax-loaded", { + composed: true, + bubbles: true, + cancelable: false, + detail: true, + }), + ); + store.appReady = true; + autorun(() => { + if (toJS(store.appReady)) { + globalThis.document.body.classList.add("app-loaded"); + } else { + globalThis.document.body.classList.remove("app-loaded"); + } + }); + store.appEl = this; + autorun(() => { + if (store.activeItem) { + this.activeItem = toJS(store.activeItem); + } + }); + autorun(() => { + this.soundIcon = toJS(store.soundStatus) + ? new URL("./lib/assets/images/FullVolume.svg", import.meta.url).href + : new URL("./lib/assets/images/Silence.svg", import.meta.url).href; + if (!toJS(store.soundStatus)) { + store.toast("Sound off.. hey! HELLO!?!", 2000, { fire: true }); + } else { + store.toast("You can hear me now? Good.", 2000, { hat: "random" }); + } + }); + // App is ready and the user is Logged in + autorun(async () => { + if ( + toJS(store.appReady) && + store.AppHaxAPI && + toJS(store.isLoggedIn) && + toJS(store.appSettings) && + toJS(store.refreshSiteList) + ) { + // Need this for the auto run when testing new user + // if we get new data source, trigger a rebuild of the site list + const results = await AppHaxAPI.makeCall("getSitesList"); + store.manifest = results.data; + } else if (toJS(store.appReady) && !toJS(store.isLoggedIn)) { + this.login(); + } + }); + } + + toggleMenu() { + this.userMenuOpen = !this.userMenuOpen; + store.appEl.playSound("click"); + } + + closeMenu() { + this.userMenuOpen = false; + } + + openMerlin() { + store.appEl.playSound("click"); + SuperDaemonInstance.open(); + } + + render() { + return html` +
    + + + + + + ${this.t.home} + + + Toggle sound effects + + +
    + Not a fan of the (awesome) sound effects? You can mute them if you + prefer. +
    +
    + Toggle sound + + Toggle dark mode + +
    + You want to log out and be someone else? Create a new site? Click + your character. Your character is unique to you! +
    + + + + + + + + + +
    +
    +
    +
    + +
    + + ${this.activeItem && !this.siteReady + ? html` +

    ${this.activeItem.label}

    +
    + ${this.activeItem && this.activeItem.statement + ? this.activeItem.statement.replace( + ":structure", + toJS(store.site.structure), + ) + : ""} +
    + ` + : ``} + ${this.activeItem && this.siteReady + ? html` +

    ${toJS(store.site.name)}

    +
    + Is all ready, are you ready to build? +
    + ` + : ``} +
    +
    + +
    ${this.appBody(this.appMode)}
    +
    +
    `; + } + + appBody(routine) { + let template = html``; + switch (routine) { + case "home": + case "search": + template = this.templateHome(); + break; + case "create": + template = this.templateCreate(); + break; + case "404": + default: + template = this.template404(); + break; + } + return template; + } + + //EDIT HERE + templateHome() { + return html` +
    + +
    + + `; + } + + // eslint-disable-next-line class-methods-use-this + templateCreate() { + return html``; + } + + siteReadyToGo(e) { + import("@haxtheweb/multiple-choice/lib/confetti-container.js").then( + (module) => { + setTimeout(() => { + this.shadowRoot.querySelector("#confetti").setAttribute("popped", ""); + }, 0); + }, + ); + if (e.detail) { + store.siteReady = true; + } + } + + template404() { + return html`
    + + + + + This + fine + is +
    `; + } + + // ensure internal data is unset for store + startJourney() { + this.userMenuOpen = false; + store.createSiteSteps = false; + store.siteReady = false; + store.site.structure = null; + store.site.type = null; + store.site.theme = null; + store.site.name = null; + store.appMode = "create"; + store.appEl.playSound("click2"); + } +} +customElements.define(AppHax.tag, AppHax); + +globalThis.AppHax = globalThis.AppHax || {}; + +globalThis.AppHax.requestAvailability = () => { + if (!globalThis.AppHax.instance && globalThis.document) { + globalThis.AppHax.instance = globalThis.document.querySelector(AppHax.tag); + } + return globalThis.AppHax.instance; +}; \ No newline at end of file From 1d3ef9f97862d6b751dd6ccea5f43d10c6671c95 Mon Sep 17 00:00:00 2001 From: btopro Date: Thu, 2 Oct 2025 09:17:41 -0400 Subject: [PATCH 100/166] https://github.com/haxtheweb/webcomponents/pull/729 --- elements/app-hax/src/app-hax.js | 1378 +++++++++++++++++++++++++++++++ 1 file changed, 1378 insertions(+) create mode 100644 elements/app-hax/src/app-hax.js diff --git a/elements/app-hax/src/app-hax.js b/elements/app-hax/src/app-hax.js new file mode 100644 index 0000000000..89f9f070b9 --- /dev/null +++ b/elements/app-hax/src/app-hax.js @@ -0,0 +1,1378 @@ +import { css, html, unsafeCSS } from "lit"; +import { toJS, autorun } from "mobx"; +import { localStorageSet, localStorageGet } from "@haxtheweb/utils/utils.js"; +import "@haxtheweb/simple-tooltip/simple-tooltip.js"; +import { SimpleColors } from "@haxtheweb/simple-colors/simple-colors.js"; +import { store } from "./lib/v2/AppHaxStore.js"; +import { I18NMixin } from "@haxtheweb/i18n-manager/lib/I18NMixin.js"; +import { AppHaxAPI } from "./lib/v2/AppHaxBackendAPI.js"; +import { SimpleTourManager } from "@haxtheweb/simple-popover/lib/simple-tour.js"; +import { SuperDaemonInstance } from "@haxtheweb/super-daemon/super-daemon.js"; +import "@haxtheweb/simple-toolbar/lib/simple-toolbar-button.js"; +import "@haxtheweb/simple-colors-shared-styles/simple-colors-shared-styles.js"; +import "./lib/v2/AppHaxRouter.js"; +import "./lib/v2/app-hax-label.js"; +import "./lib/v2/app-hax-top-bar.js"; +import { SimpleTourFinder } from "@haxtheweb/simple-popover/lib/SimpleTourFinder.js"; +import "./lib/v2/app-hax-use-case.js"; +import "./lib/v2/app-hax-use-case-filter.js"; +import "./lib/v2/app-hax-search-results.js"; +import "./lib/v2/app-hax-scroll-button.js"; + +const logoutBtn = new URL("./lib/assets/images/Logout.svg", import.meta.url) + .href; +// toggle store darkmode +function darkToggle(e) { + if (e.matches) { + // dark mode + store.darkMode = true; + } else { + // light mode + store.darkMode = false; + } +} + +function soundToggle() { + store.soundStatus = !toJS(store.soundStatus); + localStorageSet("app-hax-soundStatus", toJS(store.soundStatus)); + store.appEl.playSound("click"); +} + +export class AppHax extends I18NMixin(SimpleTourFinder(SimpleColors)) { + static get tag() { + return "app-hax"; + } + + _openExternalLink(link) { + globalThis.open(link, "_blank"); + } + + async _haxStoreContribute(type, tags, daemonTerm = null) { + let body = ""; + if (type == "merlin") { + var title = `[${type}] New command request from HAX daemon`; + body = `Location: ${globalThis.location.href} +Merlin command: ${daemonTerm} +What did you want merlin to do? +`; + } else { + var title = `[${type}] User report from HAX daemon`; + body = `Location: ${globalThis.location.href} +Browser: ${navigator.userAgent} +OS: ${navigator.userAgentData.platform} - ${navigator.deviceMemory}GB RAM - ${navigator.hardwareConcurrency} cores +Screen: ${globalThis.screen.width}x${globalThis.screen.height} +Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} +`; + if (navigator.getBattery) { + const stats = await globalThis.navigator.getBattery(); + body += `Battery: ${stats.level * 100}% +`; + } + // some things report the "type" of internet connection speed + // for terrible connections lets save frustration + if ( + navigator.connection && + globalThis.navigator.connection.effectiveType + ) { + body += `Connection: ${navigator.connection.effectiveType} +`; + } + body += `${type == "feature" ? `Your idea:` : `Bug you experienced:`} +`; + } + globalThis.open( + `https://github.com/haxtheweb/issues/issues/new?assignees=&labels=${tags}&template=issue-report.md&title=${title}&body=${encodeURIComponent( + body, + )}`, + "_blank", + ); + } + // eslint-disable-next-line class-methods-use-this + playSound(sound = "coin2") { + return new Promise((resolve) => { + if (store.soundStatus && store.appReady) { + let playSound = [ + "click", + "click2", + "coin", + "coin2", + "hit", + "success", + ].includes(sound) + ? sound + : "hit"; + this.audio = new Audio( + new URL(`./lib/assets/sounds/${playSound}.mp3`, import.meta.url).href, + ); + this.audio.volume = 0.3; + this.audio.onended = (event) => { + resolve(); + }; + this.audio.play(); + // resolve after 1s if sound failed to load + setTimeout(() => { + resolve(); + }, 1000); + } else { + resolve(); + } + }); + } + + /** + * A token refresh just failed so force to login prompt / state + */ + _tokenRefreshFailed(e) { + globalThis.dispatchEvent( + new CustomEvent("jwt-login-logout", { + composed: true, + bubbles: true, + cancelable: false, + detail: true, + }), + ); + setTimeout(() => { + this.reset(true); + }, 100); + } + + connectedCallback() { + super.connectedCallback(); + globalThis + .matchMedia("(prefers-color-scheme: dark)") + .addEventListener("change", darkToggle, { + signal: this.windowControllers.signal, + }); + globalThis.addEventListener("jwt-logged-in", this._jwtLoggedIn.bind(this), { + signal: this.windowControllers.signal, + }); + + globalThis.addEventListener( + "jwt-login-refresh-error", + this._tokenRefreshFailed.bind(this), + { signal: this.windowControllers.signal }, + ); + } + + goToLocation(location) { + globalThis.location = location; + } + + disconnectedCallback() { + this.windowControllers.abort(); + super.disconnectedCallback(); + } + + constructor() { + super(); + this.unlockComingSoon = false; + this.unlockTerrible = false; + this.t = this.t || {}; + + this.t = { + ...this.t, + selectPage: "Select page", + backToSiteList: "Back to site list", + listMySites: "List my sites", + cancel: "Cancel", + editDetails: "Page details", + add: "Add", + editSettings: "Edit settings", + source: "Source", + viewSource: "View source", + findMedia: "Find media", + undo: "Undo", + redo: "Redo", + media: "Media", + outline: "Outline", + blocks: "Blocks", + addBlock: "Add block", + addPage: "Add page", + addChildPage: "Add child page", + clonePage: "Clone page", + delete: "Delete page", + siteSettings: "Site settings", + close: "Close", + settings: "Settings", + edit: "Edit", + configureBlock: "Configure block", + configure: "Configure", + save: "Save", + home: "Home", + startNewJourney: "Start new journey", + newJourney: "New Journey", + accountInfo: "Account Info", + outlineDesigner: "Outline designer", + pageOutline: "Page outline", + more: "More", + siteActions: "Site actions", + insights: "Insights dashboard", + merlin: "Merlin", + summonMerlin: "Summon Merlin", + logOut: "Log out", + menu: "Menu", + showMore: "More", + }; + if ( + typeof globalThis.speechSynthesis !== "undefined" && + (globalThis.SpeechRecognition || + globalThis.webkitSpeechRecognition || + globalThis.mozSpeechRecognition || + globalThis.msSpeechRecognition || + globalThis.oSpeechRecognition) + ) { + SuperDaemonInstance.voiceSearch = true; + } + SuperDaemonInstance.icon = "hax:wizard-hat"; + SuperDaemonInstance.appendContext("*"); + // ensure we are running HAX / ready and in edit mode before allowing commands to go through + SuperDaemonInstance.allowedCallback = () => { + if (toJS(store.appReady) && toJS(store.isLoggedIn)) { + return true; + } + return false; + }; + + // contribution helpers + SuperDaemonInstance.defineOption({ + title: "Tour of top menu buttons", + icon: "help", + tags: ["Help", "ui", "tour"], + priority: -1000, + value: { + target: this, + method: "helpClick", + args: [], + }, + eventName: "super-daemon-element-method", + path: "HAX/app/tour", + context: ["*"], + }); + + // contribution helpers + SuperDaemonInstance.defineOption({ + title: "Unlock hidden features", + icon: "hax:hax2022", + tags: ["Developer", "features", "hidden"], + value: { + target: this, + method: "fireUnlocked", + args: [], + }, + eventName: "super-daemon-element-method", + path: ">developer/hax/unlockAll", + context: [">"], + }); + // contribution helpers + SuperDaemonInstance.defineOption({ + title: "Unlock terrible 2000s themes", + icon: "hax:table-multiple", + tags: ["Developer", "terrible", "2000", "tables"], + value: { + target: this, + method: "fireTerrible", + args: [], + }, + eventName: "super-daemon-element-method", + path: ">developer/hax/terrible2000s", + context: [">"], + }); + SuperDaemonInstance.defineOption({ + title: "Go to site", + icon: "hax:hax2022", + tags: ["Sites", "Administration", "change"], + eventName: "super-daemon-run-program", + path: "HAX/action/goToSite", + value: { + name: "Go to site", + program: async (input, values) => { + let results = []; + const items = toJS(store.manifest.items); + items.forEach(async (site) => { + if ( + input == "" || + (site.metadata.site && + site.metadata.site.name && + site.metadata.site.name.includes(input)) + ) { + results.push({ + title: site.title, + icon: + site.metadata.theme && + site.metadata.theme.variables && + site.metadata.theme.variables.icon + ? site.metadata.theme.variables.icon + : "hax:hax2022", + tags: ["site", site.description], + value: { + target: this, + method: "goToLocation", + args: [site.slug], + }, + eventName: "super-daemon-element-method", + context: [ + "*", + "HAX/action/goToSite/" + site.metadata.site.name, + ], + path: "HAX/action/goToSite/" + site.metadata.site.name, + }); + } + }); + return results; + }, + }, + context: ["*"], + }); + // contribution helpers + SuperDaemonInstance.defineOption({ + title: "Join our Community", + icon: "hax:discord", + priority: -100, + tags: ["community", "discord", "chat", "help"], + value: { + target: this, + method: "_openExternalLink", + args: ["https://bit.ly/hax-discord"], + }, + eventName: "super-daemon-element-method", + path: "HAX/community/join", + context: ["logged-in", "CMS", "HAX", "*"], + }); + SuperDaemonInstance.defineOption({ + title: "User Tutorials", + icon: "hax:hax2022", + priority: -1000, + tags: ["Documentation", "community", "help"], + value: { + target: this, + method: "_openExternalLink", + args: ["https://haxtheweb.org/tutorials"], + }, + eventName: "super-daemon-element-method", + path: "HAX/community/tutorials", + context: ["logged-in", "CMS", "HAX", "*"], + }); + SuperDaemonInstance.defineOption({ + title: "User Documentation", + icon: "hax:hax2022", + tags: ["Documentation", "community", "help"], + value: { + target: this, + method: "_openExternalLink", + args: ["https://haxtheweb.org/documentation"], + }, + eventName: "super-daemon-element-method", + path: "HAX/community/documentation", + context: ["logged-in", "CMS", "HAX", "*"], + }); + SuperDaemonInstance.defineOption({ + title: "HAX Teaching Excellence", + icon: "hax:hax2022", + tags: ["Ontology", "community", "pedagogy", "documentation", "help"], + value: { + target: this, + method: "_openExternalLink", + args: ["https://haxtheweb.org/ontology"], + }, + eventName: "super-daemon-element-method", + path: "HAX/community/pedagogy", + context: ["logged-in", "CMS", "HAX", "*"], + }); + SuperDaemonInstance.defineOption({ + title: "Bug / issue", + icon: "mdi-social:github-circle", + tags: ["Bug report", "github", "git", "community", "issue queue"], + value: { + target: this, + method: "_haxStoreContribute", + args: ["bug", "POP,bug"], + }, + eventName: "super-daemon-element-method", + path: "HAX/community/contribute", + context: ["logged-in", "CMS", "HAX", "*"], + }); + SuperDaemonInstance.defineOption({ + title: "Idea / Feature request", + icon: "mdi-social:github-circle", + tags: [ + "Feature request", + "idea", + "github", + "git", + "community", + "issue queue", + ], + value: { + target: this, + method: "_haxStoreContribute", + args: ["feature", "POP,enhancement"], + }, + context: ["logged-in", "CMS", "HAX", "*"], + eventName: "super-daemon-element-method", + path: "HAX/community/contribute", + }); + this.windowControllers = new AbortController(); + this.__tour = SimpleTourManager; + this.__tour.registerNewTour({ + key: "hax", + name: "HAX top menu", + style: ` + simple-popover-manager::part(simple-popover) { + max-width: 250px; + font-family: sans-serif; + } + simple-popover-manager button { + font-family: sans-serif; + font-size: 12px; + margin: 0px 2px; + color: var(--simple-colors-default-theme-grey-12); + } + simple-popover-manager p { + font-family: sans-serif; + padding: 0; + margin: 0; + width: 250px; + font-size: 10px; + line-height: 20px; + } + simple-popover-manager h1 { + font-family: sans-serif; + margin: 0; + font-size: 12px; + width: 250px; + padding: 0; + } + simple-popover-manager::part(simple-popover-body), + simple-popover-manager::part(simple-popover-heading) { + color: black; + background-color: white; + font-family: sans-serif; + } + body.dark-mode simple-popover-manager::part(simple-popover-body), + body.dark-mode simple-popover-manager::part(simple-popover-heading) { + color: white; + background-color: black; + font-family: sans-serif; + } + body.dark-mode simple-popover-manager simple-icon-button-lite { + color: white; + background-color: black; + font-family: sans-serif; + } + `, + }); + this.tourName = "hax"; + // manage title when activeItem changes + autorun(() => { + const item = toJS(store.activeItem); + if (item && item.title) { + store.setPageTitle(item.title); + } + }); + autorun(() => { + this.siteReady = toJS(store.siteReady); + }); + autorun(() => { + const badDevice = toJS(store.badDevice); + if (badDevice === false) { + import("@haxtheweb/rpg-character/rpg-character.js"); + } else if (badDevice === true) { + globalThis.document.body.classList.add("bad-device"); + } + }); + this.userMenuOpen = false; + this.courses = []; + this.activeItem = {}; + this.phrases = { + new: [ + "What's ya name?", + "HAX to the moon", + "Welcome to the Jungle", + "We like to party", + "Build something awesome", + "Everything is awesome!", + "Everything is cool", + "When you're part of the team", + "When you're living our dream", + "Welcome to the up-side-down", + ], + return: [ + "Welcome back, take 2?", + "That wasn't very long", + "Stranger thiings have happened", + "Student driven platform", + "Faculty centered platform", + "Instructional designer influenced platform", + "Free, Open, Community driven", + "One brick at a time..", + "Sup?", + "You again? Awesome!", + "Let's do this", + "There can only be one ring...", + "There is another", + "Fancy that, I love HAX and you show up", + ], + }; + this.isNewUser = null; + this.basePath = "/"; + this.searchTerm = ""; + this.appMode = ""; + this.soundIcon = ""; + // full on store that does the heavy lifting + this.store = store; + // centralized sound source to not flood sounds when playing + this.sound = new Audio(); + // @todo need this from app deploy itself + autorun(() => { + this.isNewUser = toJS(store.isNewUser); + if ( + this.isNewUser && + toJS(store.appMode) !== "create" && + toJS(store.appMode) !== "404" + ) { + store.appMode = "create"; + setTimeout(() => { + store.createSiteSteps = true; + }, 0); + } + }); + autorun(() => { + this.userName = toJS(store.user.name); + }); + autorun(() => { + this.appMode = toJS(store.appMode); + }); + autorun(() => { + this.searchTerm = toJS(store.searchTerm); + }); + + /** + * When location changes update activeItem / mode of app + */ + autorun(async () => { + const location = toJS(store.location); + if (location && location.route) { + // verify this is a step vs other operations + if (!location.route.step) { + // support external site links + if (location.route.slug) { + this.reset(); + setTimeout(() => { + globalThis.location = location.route.slug; + }, 0); + } + // page miss is high check too + else if (location.route.name === "404") { + store.createSiteSteps = false; + store.appMode = "404"; + setTimeout(() => { + store.toast("the page miss.. it burns!!!", 3000, { + fire: true, + walking: true, + }); + }, 500); + } + // then home / landing page which is default expectation + else if ( + location.route.name === "home" || + location.route.name === "search" + ) { + store.appMode = "home"; + store.createSiteSteps = false; + } else { + //console.warn(location.route); + } + } else { + // we have a "step" based operation + store.appMode = "create"; + store.createSiteSteps = true; + } + } + }); + + autorun(() => { + if (store.routes.length > 0 && store.location === null) { + store.location = toJS(store.routes[0]); + } + }); + // manage dark mode + // only set this initially if we don't have an app state of our own + if (localStorageGet("app-hax-darkMode", null) === null) { + store.darkMode = globalThis.matchMedia( + "(prefers-color-scheme: dark)", + ).matches; + } + autorun(() => { + localStorageSet("app-hax-darkMode", toJS(store.darkMode)); + requestAnimationFrame(() => { + if (toJS(store.darkMode)) { + globalThis.document.body.classList.add("dark-mode"); + store.toast("I'm ascared of the dark", 2000, { fire: true }); + this.dark = true; + SuperDaemonInstance.dark = true; + SuperDaemonInstance.toastInstance.darkMode = true; + } else { + globalThis.document.body.classList.remove("dark-mode"); + store.toast("Sunny day it is", 2000, { hat: "random" }); + this.dark = false; + SuperDaemonInstance.dark = false; + SuperDaemonInstance.toastInstance.darkMode = false; + } + }); + }); + autorun(() => { + const mode = toJS(store.appMode); + if (mode) { + globalThis.document.body.classList.remove("app-hax-search"); + globalThis.document.body.classList.remove("app-hax-create"); + globalThis.document.body.classList.remove("app-hax-404"); + globalThis.document.body.classList.remove("app-hax-home"); + globalThis.document.body.classList.add(`app-hax-${mode}`); + } + }); + } + + static get properties() { + return { + ...super.properties, + unlockComingSoon: { type: Boolean }, + unlockTerrible: { type: Boolean }, + courses: { type: Array }, + userName: { type: String }, + activeItem: { type: Object }, + soundIcon: { type: String }, + searchTerm: { type: String }, + appMode: { type: String }, // minor context of what we're doing in the app for rendering + isNewUser: { type: Boolean }, + phrases: { type: Object }, + userMenuOpen: { type: Boolean }, // leave here to ensure hat change and sound effects happen + siteReady: { type: Boolean }, + basePath: { type: String, attribute: "base-path" }, + token: { type: String }, + }; + } + + // eslint-disable-next-line class-methods-use-this + reset(reload = false) { + // localStorage possible to be blocked by permission of system + try { + globalThis.localStorage.removeItem("app-hax-step"); + globalThis.localStorage.removeItem("app-hax-site"); + if (reload) { + // should always be a base tag for a SPA but just checking + if (document.querySelector("base")) { + globalThis.location = globalThis.document.querySelector("base").href; + } else { + globalThis.location.reload(); + } + } + } catch (e) { + //console.warn(e); + } + } + fireTerrible() { + this.unlockTerrible = true; + store.appEl.playSound("coin").then(() => { + store.appEl.playSound("coin2").then(() => { + store.appEl.playSound("success").then(() => { + SuperDaemonInstance.merlinSpeak( + "Enjoy these early 2000s table based layouts. May they remind you how never to web, again.", + ); + }); + }); + }); + } + fireUnlocked() { + this.unlockComingSoon = true; + store.appEl.playSound("coin").then(() => { + store.appEl.playSound("coin2").then(() => { + store.appEl.playSound("success").then(() => { + SuperDaemonInstance.merlinSpeak( + "Unbelievable! You, (Subject Name), must be the pride of (Subject Hometown). Enjoy all locked features as a boon!", + ); + }); + }); + }); + } + // eslint-disable-next-line class-methods-use-this + logout() { + globalThis.dispatchEvent( + new CustomEvent("jwt-login-logout", { + composed: true, + bubbles: true, + cancelable: false, + detail: true, + }), + ); + this.closeMenu(); + this.__logoutUserAction = true; + } + // only care about logouts + _jwtLoggedIn(e) { + if (e.detail === false && this.__logoutUserAction) { + this.__logoutUserAction = false; + setTimeout(() => { + this.reset(true); + }, 100); + } + } + + // eslint-disable-next-line class-methods-use-this + login() { + import("./lib/v2/app-hax-site-login.js").then(() => { + const p = globalThis.document.createElement("app-hax-site-login"); + if (this.querySelector('[slot="externalproviders"]')) { + const cloneSlot = this.querySelector( + '[slot="externalproviders"]', + ).cloneNode(true); + p.appendChild(cloneSlot); + } + import("@haxtheweb/simple-modal/simple-modal.js").then(() => { + setTimeout(() => { + this.dispatchEvent( + new CustomEvent("simple-modal-show", { + bubbles: true, + cancelable: true, + composed: true, + detail: { + title: "< login >", + elements: { content: p }, + modal: true, + styles: { + "--simple-modal-titlebar-background": "transparent", + "--simple-modal-titlebar-color": "black", + "--simple-modal-width": "40vw", + "--simple-modal-min-width": "300px", + "--simple-modal-z-index": "100000000", + "--simple-modal-height": "62vh", + "--simple-modal-min-height": "400px", + "--simple-modal-titlebar-height": "64px", + }, + }, + }), + ); + }, 0); + }); + }); + } + + static get styles() { + return [ + super.styles, + css` + :host { + display: block; + --app-hax-background-color-active: var(--app-hax-accent-color); + } + #home { + display: inline-flex; + } + #wt { + border: solid 1px var(--simple-colors-default-theme-accent-12, var(--accent-color)); + } + simple-toolbar-button { + min-width: 48px; + margin: 0; + --simple-toolbar-border-color: #dddddddd; + height: 48px; + --simple-toolbar-button-disabled-border-color: transparent; + --simple-toolbar-button-disabled-opacity: 0.3; + --simple-toolbar-button-padding: 3px 6px; + --simple-toolbar-border-radius: 0; + } + simple-toolbar-button:hover, + simple-toolbar-button:active, + simple-toolbar-button:focus { + background-color: var(--hax-ui-background-color-accent); + color: var(--hax-ui-color); + } + simple-toolbar-button:hover, + simple-toolbar-button:active, + simple-toolbar-button:focus { + --simple-toolbar-border-color: var(--hax-ui-color-accent); + } + .wired-button-label { + clip: rect(0 0 0 0); + clip-path: inset(50%); + height: 1px; + overflow: hidden; + position: absolute; + white-space: nowrap; + width: 1px; + } + .topbar-character { + cursor: pointer; + display: inline-block; + border: none; + border-radius: 0px; + padding: 0 8px; + margin: 0 0 0 16px; + background-color: transparent; + height: 48px; + max-width: 160px; + } + .characterbtn-name { + color: var(--simple-colors-default-theme-grey-12); + font-family: "Press Start 2P", sans-serif; + margin-left: 8px; + font-size: 12px; + vertical-align: bottom; + line-height: 48px; + overflow: hidden; + text-overflow: ellipsis; + height: 48px; + word-break: break-all; + } + .topbar-character:hover, + .topbar-character:focus { + background-color: var(--simple-colors-default-theme-light-blue-4); + outline: var(--haxcms-color) solid 3px; + outline-offset: -3px; + height: 48px; + } + .topbar-character rpg-character { + margin: -4px -14px 0px -10px; + height: 52px; + width: 64px; + display: inline-block; + } + .content { + text-align: center; + margin-top: 24px; + } + .four04-character { + margin-top: 16px; + } + .start-journey { + display: flex; + padding-top: 20px; + justify-content: center; + } + app-hax-site-button { + max-width: 60vw; + justify-content: center; + } + app-hax-top-bar { + top: 0; + z-index: 1000; + right: 0; + left: 0; + position: fixed; + } + @media (max-width: 640px) { + simple-tooltip { + --simple-tooltip-font-size: 10px; + } + } + .label { + display: inline-flex; + text-align: flex-start; + align-items: center; + } + app-hax-label { + animation: 0.8s ease-in-out 0s scrollin; + -webkit-animation: 0.8s ease-in-out 0s scrollin; + display: flex; + align-self: flex-start; + overflow: hidden; + margin-left: 24px; + margin-right: 24px; + } + app-hax-label h1 { + font-weight: normal; + font-size: 4vw; + margin: 0; + padding: 0; + } + @keyframes scrollin { + from { + margin-top: -240px; + margin-bottom: 240px; + } + to { + margin-top: 0; + margin-bottom: 0; + } + } + .haxLogo { + --simple-icon-height: 40px; + --simple-icon-width: 40px; + margin: 4px; + color: var(--simple-colors-default-theme-grey-12); + cursor: pointer; + } + .soundToggle { + margin-right: 16px; + position: relative; + display: inline-flex; + vertical-align: top; + } + + .soundToggle img { + width: 24px; + height: 24px; + } + + app-hax-search-bar { + display: inline-flex; + } + main { + padding-top: 80px; + } + @media (max-width: 900px) { + .characterbtn-name { + display: none; + } + main { + padding-top: 64px; + } + } + app-hax-user-menu { + z-index: 1003; + } + .logout::part(menu-button) { + background-image: url("${unsafeCSS(logoutBtn)}"); + background-repeat: no-repeat; + background-position: center; + text-align: center; + background-size: cover; + border-top: 0px; + border-bottom: 0px; + padding: 10px; + } + app-hax-user-menu app-hax-user-menu-button::part(menu-button) { + font-family: "Press Start 2P", sans-serif; + font-size: 12px; + } + #helpbtn { + --simple-icon-height: 50px; + --simple-icon-width: 50px; + right: 200px; + top: 100px; + padding: 4px; + background-color: var(--simple-colors-default-theme-grey-1); + border-radius: 50%; + position: absolute; + color: var(--simple-colors-default-theme-grey-12); + border: var(--simple-colors-default-theme-grey-12) 4px solid; + cursor: pointer; + } + @media (max-width: 800px) { + app-hax-site-button { + width: 320px; + max-width: 60vw; + --app-hax-site-button-font-size: 16px; + } + #helpbtn { + --simple-icon-height: 40px; + --simple-icon-width: 40px; + right: 8px; + top: 64px; + padding: 2px; + border: var(--simple-colors-default-theme-grey-12) 2px solid; + } + } + @media (prefers-reduced-motion: reduce) { + app-hax-label { + animation: none; + -webkit-animation: none; + } + } + @media (max-width: 640px) { + .content { + margin-top: 4px; + } + .start-journey { + padding-top: 0; + } + + app-hax-site-button { + --app-hax-site-button-font-size: 12px; + } + } + @media (max-height: 500px) { + app-hax-label h1 { + font-family: monospace; + font-weight: normal; + font-size: 4vw; + margin: 0; + padding: 0; + } + } + `, + ]; + } + helpClick() { + // start the tour + store.appEl.playSound("coin2"); + this.__tour.startTour("hax"); + } + + updated(changedProperties) { + if (super.updated) { + super.updated(changedProperties); + } + // update the store as these get set via entrypoint of the app + // but used downstream in calls + changedProperties.forEach((oldValue, propName) => { + // API backend broker settings + if (["basePath"].includes(propName) && this[propName]) { + store.AppHaxAPI[propName] = this[propName]; + } + // settings for the store itself + if (["token"].includes(propName) && this[propName]) { + store[propName] = this[propName]; + } + }); + } + + firstUpdated(changedProperties) { + if (super.firstUpdated) { + super.firstUpdated(changedProperties); + } + // required for our early siteList updating + if (store.AppHaxAPI && this.basePath) { + store.AppHaxAPI.basePath = this.basePath; + } + import("./lib/v2/app-hax-steps.js"); + import("./lib/v2/app-hax-site-button.js"); + import("wired-elements/lib/wired-button.js"); + import("./lib/v2/app-hax-toast.js"); + import("./lib/v2/app-hax-wired-toggle.js"); + import("./lib/v2/app-hax-search-bar.js"); + import("./lib/v2/app-hax-search-results.js"); + import("./lib/v2/app-hax-user-menu.js"); + import("./lib/v2/app-hax-user-menu-button.js"); + this.dispatchEvent( + new CustomEvent("app-hax-loaded", { + composed: true, + bubbles: true, + cancelable: false, + detail: true, + }), + ); + store.appReady = true; + autorun(() => { + if (toJS(store.appReady)) { + globalThis.document.body.classList.add("app-loaded"); + } else { + globalThis.document.body.classList.remove("app-loaded"); + } + }); + store.appEl = this; + autorun(() => { + if (store.activeItem) { + this.activeItem = toJS(store.activeItem); + } + }); + autorun(() => { + this.soundIcon = toJS(store.soundStatus) + ? new URL("./lib/assets/images/FullVolume.svg", import.meta.url).href + : new URL("./lib/assets/images/Silence.svg", import.meta.url).href; + if (!toJS(store.soundStatus)) { + store.toast("Sound off.. hey! HELLO!?!", 2000, { fire: true }); + } else { + store.toast("You can hear me now? Good.", 2000, { hat: "random" }); + } + }); + // App is ready and the user is Logged in + autorun(async () => { + if ( + toJS(store.appReady) && + store.AppHaxAPI && + toJS(store.isLoggedIn) && + toJS(store.appSettings) && + toJS(store.refreshSiteList) + ) { + // Need this for the auto run when testing new user + // if we get new data source, trigger a rebuild of the site list + const results = await AppHaxAPI.makeCall("getSitesList"); + store.manifest = results.data; + } else if (toJS(store.appReady) && !toJS(store.isLoggedIn)) { + this.login(); + } + }); + } + + toggleMenu() { + this.userMenuOpen = !this.userMenuOpen; + store.appEl.playSound("click"); + } + + closeMenu() { + this.userMenuOpen = false; + } + + openMerlin() { + store.appEl.playSound("click"); + SuperDaemonInstance.open(); + } + + render() { + return html` +
    + + + + + + ${this.t.home} + + + Toggle sound effects + + +
    + Not a fan of the (awesome) sound effects? You can mute them if you + prefer. +
    +
    + Toggle sound + + Toggle dark mode + +
    + You want to log out and be someone else? Create a new site? Click + your character. Your character is unique to you! +
    + + + + + + + + + +
    +
    +
    +
    + +
    + + ${this.activeItem && !this.siteReady + ? html` +

    ${this.activeItem.label}

    +
    + ${this.activeItem && this.activeItem.statement + ? this.activeItem.statement.replace( + ":structure", + toJS(store.site.structure), + ) + : ""} +
    + ` + : ``} + ${this.activeItem && this.siteReady + ? html` +

    ${toJS(store.site.name)}

    +
    + Is all ready, are you ready to build? +
    + ` + : ``} +
    +
    + +
    ${this.appBody(this.appMode)}
    +
    +
    `; + } + + appBody(routine) { + let template = html``; + switch (routine) { + case "home": + case "search": + template = this.templateHome(); + break; + case "create": + template = this.templateCreate(); + break; + case "404": + default: + template = this.template404(); + break; + } + return template; + } + + //EDIT HERE + templateHome() { + return html` +
    + +
    + + `; + } + + // eslint-disable-next-line class-methods-use-this + templateCreate() { + return html``; + } + + siteReadyToGo(e) { + import("@haxtheweb/multiple-choice/lib/confetti-container.js").then( + (module) => { + setTimeout(() => { + this.shadowRoot.querySelector("#confetti").setAttribute("popped", ""); + }, 0); + }, + ); + if (e.detail) { + store.siteReady = true; + } + } + + template404() { + return html`
    + + + + + This + fine + is +
    `; + } + + // ensure internal data is unset for store + startJourney() { + this.userMenuOpen = false; + store.createSiteSteps = false; + store.siteReady = false; + store.site.structure = null; + store.site.type = null; + store.site.theme = null; + store.site.name = null; + store.appMode = "create"; + store.appEl.playSound("click2"); + } +} +customElements.define(AppHax.tag, AppHax); + +globalThis.AppHax = globalThis.AppHax || {}; + +globalThis.AppHax.requestAvailability = () => { + if (!globalThis.AppHax.instance && globalThis.document) { + globalThis.AppHax.instance = globalThis.document.querySelector(AppHax.tag); + } + return globalThis.AppHax.instance; +}; \ No newline at end of file From f0b6b47b9846afb7975ff7ade1f58fe770437b3d Mon Sep 17 00:00:00 2001 From: btopro Date: Thu, 2 Oct 2025 13:27:46 -0400 Subject: [PATCH 101/166] https://github.com/haxtheweb/issues/issues/1462 --- .../a11y-details/test/a11y-details.test.js | 69 +- elements/a11y-figure/test/a11y-figure.test.js | 97 +- .../test/a11y-menu-button.test.js | 205 +-- .../test/absolute-position-behavior.test.js | 216 ++- .../aframe-player/test/aframe-player.test.js | 168 +- elements/app-hax/app-hax.js | 83 +- elements/app-hax/custom-elements.json | 14 +- elements/app-hax/demo/index.html | 35 +- elements/app-hax/lib/v2/HAXIAM_API_SPEC.md | 116 ++ elements/app-hax/lib/v2/app-hax-button.js | 4 +- elements/app-hax/lib/v2/app-hax-filter-tag.js | 35 +- elements/app-hax/lib/v2/app-hax-label.js | 47 +- elements/app-hax/lib/v2/app-hax-recipes.json | 35 +- .../app-hax/lib/v2/app-hax-scroll-button.js | 47 +- elements/app-hax/lib/v2/app-hax-search-bar.js | 2 +- .../app-hax/lib/v2/app-hax-search-results.js | 499 +++++- .../lib/v2/app-hax-simple-hat-progress.js | 124 ++ elements/app-hax/lib/v2/app-hax-site-bar.js | 439 ++++- .../lib/v2/app-hax-site-creation-modal.js | 852 ++++++++++ .../app-hax/lib/v2/app-hax-site-details.js | 7 +- elements/app-hax/lib/v2/app-hax-site-login.js | 240 ++- elements/app-hax/lib/v2/app-hax-steps.js | 4 +- .../app-hax/lib/v2/app-hax-use-case-filter.js | 641 +++++--- elements/app-hax/lib/v2/app-hax-use-case.js | 257 +-- .../lib/v2/app-hax-user-access-modal.js | 481 ++++++ .../lib/v2/app-hax-user-menu-button.js | 127 +- elements/app-hax/lib/v2/app-hax-user-menu.js | 168 +- .../wired-darkmode-toggle.js | 24 +- elements/app-hax/src/app-hax.js | 1378 ---------------- .../app-hax/test-use-cases/app-hax-copy.js | 1412 ----------------- .../test/awesome-explosion.test.js | 313 ++-- .../test/chartist-render.test.js | 577 +++---- elements/code-editor/test/code-editor.test.js | 623 ++++---- elements/code-sample/test/code-sample.test.js | 310 ++-- elements/count-up/test/count-up.test.js | 310 ++-- elements/d-d-d/custom-elements.json | 8 +- elements/d-d-d/lib/DDDStyles.js | 94 +- elements/d-d-d/test/d-d-d.test.js | 191 +-- elements/data-viz/test/data-viz.test.js | 544 ++++--- .../discord-embed/test/discord-embed.test.js | 171 +- .../disqus-embed/test/disqus-embed.test.js | 139 +- elements/dl-behavior/test/dl-behavior.test.js | 199 +-- .../figure-label/test/figure-label.test.js | 179 ++- .../file-system-broker/custom-elements.json | 221 +++ .../file-system-broker/file-system-broker.js | 47 +- .../test/file-system-broker.test.js | 156 +- elements/grid-plate/test/grid-plate.test.js | 97 +- elements/haxor-slevin/custom-elements.json | 2 +- elements/i18n-manager/custom-elements.json | 52 + elements/i18n-manager/i18n-manager.js | 127 +- .../lib/translation-manifest.json | 247 +-- elements/learn-two-theme/custom-elements.json | 2 +- elements/learn-two-theme/learn-two-theme.js | 12 +- .../lib/lesson-highlight.haxProperties.json | 8 +- elements/map-menu/lib/map-menu-header.js | 1 - elements/map-menu/lib/map-menu-item.js | 1 - elements/map-menu/test/map-menu.test.js | 42 +- elements/md-block/test/md-block.test.js | 106 +- .../test/media-behaviors.test.js | 12 +- elements/media-image/media-image.js | 10 +- elements/media-image/test/media-image.test.js | 100 +- .../locales/meme-maker.haxProperties.ar.json | 2 +- .../locales/meme-maker.haxProperties.bn.json | 2 +- .../locales/meme-maker.haxProperties.de.json | 2 +- .../locales/meme-maker.haxProperties.gu.json | 2 +- .../locales/meme-maker.haxProperties.he.json | 2 +- .../locales/meme-maker.haxProperties.hi.json | 2 +- .../locales/meme-maker.haxProperties.id.json | 2 +- .../locales/meme-maker.haxProperties.it.json | 2 +- .../locales/meme-maker.haxProperties.ja.json | 2 +- .../locales/meme-maker.haxProperties.kn.json | 2 +- .../locales/meme-maker.haxProperties.ko.json | 2 +- .../locales/meme-maker.haxProperties.ml.json | 2 +- .../locales/meme-maker.haxProperties.mr.json | 2 +- .../locales/meme-maker.haxProperties.my.json | 2 +- .../locales/meme-maker.haxProperties.nl.json | 2 +- .../locales/meme-maker.haxProperties.pl.json | 2 +- .../locales/meme-maker.haxProperties.pnb.json | 2 +- .../locales/meme-maker.haxProperties.pt.json | 2 +- .../locales/meme-maker.haxProperties.ro.json | 2 +- .../locales/meme-maker.haxProperties.ru.json | 2 +- .../locales/meme-maker.haxProperties.sv.json | 2 +- .../locales/meme-maker.haxProperties.ta.json | 2 +- .../locales/meme-maker.haxProperties.te.json | 2 +- .../locales/meme-maker.haxProperties.th.json | 2 +- .../locales/meme-maker.haxProperties.tl.json | 2 +- .../locales/meme-maker.haxProperties.tr.json | 2 +- .../locales/meme-maker.haxProperties.uk.json | 2 +- .../locales/meme-maker.haxProperties.ur.json | 2 +- .../locales/meme-maker.haxProperties.uz.json | 2 +- .../locales/meme-maker.haxProperties.vi.json | 2 +- .../locales/meme-maker.haxProperties.wuu.json | 2 +- .../locales/meme-maker.haxProperties.zh.json | 2 +- elements/meme-maker/meme-maker.js | 2 +- .../meme-maker/test/meme-maker-i18n.test.js | 341 ++-- elements/meme-maker/test/meme-maker.test.js | 189 ++- .../demo/mf-htmlmd-example.js | 3 +- .../test/micro-frontend-registry.test.js | 12 +- .../moar-sarcasm/test/moar-sarcasm.test.js | 35 +- .../test/moment-element.test.js | 17 +- .../multiple-choice/lib/QuestionElement.js | 10 +- .../test/multiple-choice.test.js | 83 +- .../music-player/test/music-player.test.js | 73 +- .../mutation-observer-import-mixin.test.js | 14 +- elements/outline-designer/outline-designer.js | 1 - elements/place-holder/custom-elements.json | 14 +- elements/place-holder/place-holder.js | 9 +- .../place-holder/test/place-holder.test.js | 255 +-- elements/play-list/test/play-list.test.js | 472 +++--- .../test/portal-launcher.test.js | 152 +- .../product-card/test/product-card.test.js | 401 ++--- .../runkit-embed/test/runkit-embed.test.js | 366 +++-- elements/scroll-button/scroll-button.js | 1 - elements/self-check/self-check.js | 10 +- .../simple-login/lib/simple-camera-snap.js | 1 - .../simple-login/lib/simple-login-camera.js | 1 - elements/simple-toast/custom-elements.json | 4 +- elements/stop-note/stop-note.js | 1 - elements/super-daemon/lib/super-daemon-row.js | 2 +- .../super-daemon/lib/super-daemon-search.js | 2 +- .../super-daemon/lib/super-daemon-toast.js | 2 +- elements/super-daemon/lib/super-daemon-ui.js | 2 +- elements/twitter-embed/twitter-embed.js | 1 - elements/user-action/user-action.js | 1 - elements/voice-recorder/lib/vmsg-fork.js | 1 - elements/voice-recorder/voice-recorder.js | 3 +- elements/wikipedia-query/custom-elements.json | 4 +- elements/wikipedia-query/wikipedia-query.js | 4 +- 128 files changed, 7941 insertions(+), 7339 deletions(-) create mode 100644 elements/app-hax/lib/v2/HAXIAM_API_SPEC.md create mode 100644 elements/app-hax/lib/v2/app-hax-simple-hat-progress.js create mode 100644 elements/app-hax/lib/v2/app-hax-site-creation-modal.js create mode 100644 elements/app-hax/lib/v2/app-hax-user-access-modal.js delete mode 100644 elements/app-hax/src/app-hax.js delete mode 100644 elements/app-hax/test-use-cases/app-hax-copy.js diff --git a/elements/a11y-details/test/a11y-details.test.js b/elements/a11y-details/test/a11y-details.test.js index 278978aa91..f2dd2061f8 100644 --- a/elements/a11y-details/test/a11y-details.test.js +++ b/elements/a11y-details/test/a11y-details.test.js @@ -26,7 +26,9 @@ describe("a11y-details test", () => { describe("Slot functionality", () => { it("should have summary slot with correct content", () => { - const summarySlot = element.shadowRoot.querySelector('slot[name="summary"]'); + const summarySlot = element.shadowRoot.querySelector( + 'slot[name="summary"]', + ); expect(summarySlot).to.exist; const assignedNodes = summarySlot.assignedNodes({ flatten: true }); expect(assignedNodes.length).to.be.greaterThan(0); @@ -34,14 +36,18 @@ describe("a11y-details test", () => { }); it("should have details slot with correct content", () => { - const detailsSlot = element.shadowRoot.querySelector('slot[name="details"]'); + const detailsSlot = element.shadowRoot.querySelector( + 'slot[name="details"]', + ); expect(detailsSlot).to.exist; const assignedNodes = detailsSlot.assignedNodes({ flatten: true }); expect(assignedNodes.length).to.be.greaterThan(0); }); it("should have default hidden slot", () => { - const defaultSlot = element.shadowRoot.querySelector('slot[hidden]:not([name])'); + const defaultSlot = element.shadowRoot.querySelector( + "slot[hidden]:not([name])", + ); expect(defaultSlot).to.exist; }); }); @@ -214,10 +220,10 @@ describe("a11y-details test", () => {
    Details
    `); - + testElement.closeText = "Hide Content"; await testElement.updateComplete; - expect(testElement.getAttribute('close-text')).to.equal('Hide Content'); + expect(testElement.getAttribute("close-text")).to.equal("Hide Content"); await expect(testElement).shadowDom.to.be.accessible(); }); @@ -228,10 +234,10 @@ describe("a11y-details test", () => {
    Details
    `); - + testElement.openText = "Show Content"; await testElement.updateComplete; - expect(testElement.getAttribute('open-text')).to.equal('Show Content'); + expect(testElement.getAttribute("open-text")).to.equal("Show Content"); await expect(testElement).shadowDom.to.be.accessible(); }); }); @@ -317,13 +323,13 @@ describe("a11y-details test", () => { `); await testElement.updateComplete; await expect(testElement).shadowDom.to.be.accessible(); - + // Test toggle functionality if (testElement.toggleOpen) { testElement.toggleOpen(); await testElement.updateComplete; await expect(testElement).shadowDom.to.be.accessible(); - + testElement.toggleOpen(); await testElement.updateComplete; await expect(testElement).shadowDom.to.be.accessible(); @@ -338,12 +344,12 @@ describe("a11y-details test", () => { `); await testElement.updateComplete; - - const summary = testElement.shadowRoot.querySelector('summary'); + + const summary = testElement.shadowRoot.querySelector("summary"); expect(summary).to.exist; - expect(summary.getAttribute('role')).to.equal('button'); - expect(summary.getAttribute('tabindex')).to.equal('0'); - + expect(summary.getAttribute("role")).to.equal("button"); + expect(summary.getAttribute("tabindex")).to.equal("0"); + await expect(testElement).shadowDom.to.be.accessible(); }); @@ -355,14 +361,14 @@ describe("a11y-details test", () => { `); await testElement.updateComplete; - - const summary = testElement.shadowRoot.querySelector('summary'); + + const summary = testElement.shadowRoot.querySelector("summary"); expect(summary).to.exist; - + // Test that the summary is focusable summary.focus(); expect(globalThis.document.activeElement).to.equal(testElement); - + await expect(testElement).shadowDom.to.be.accessible(); }); }); @@ -377,16 +383,17 @@ describe("a11y-details test", () => { `); await testElement.updateComplete; await expect(testElement).shadowDom.to.be.accessible(); - + // Change summary content const summaryElement = testElement.querySelector('[slot="summary"]'); summaryElement.textContent = "Updated Summary"; await testElement.updateComplete; await expect(testElement).shadowDom.to.be.accessible(); - + // Change details content const detailsElement = testElement.querySelector('[slot="details"]'); - detailsElement.innerHTML = '

    Updated details with formatting

    '; + detailsElement.innerHTML = + "

    Updated details with formatting

    "; await testElement.updateComplete; await expect(testElement).shadowDom.to.be.accessible(); }); @@ -399,16 +406,16 @@ describe("a11y-details test", () => { `); await testElement.updateComplete; - + // Update properties programmatically testElement.openText = "View Details"; testElement.closeText = "Hide Details"; await testElement.updateComplete; - + expect(testElement.openText).to.equal("View Details"); expect(testElement.closeText).to.equal("Hide Details"); await expect(testElement).shadowDom.to.be.accessible(); - + // Clear properties testElement.openText = ""; testElement.closeText = ""; @@ -419,9 +426,7 @@ describe("a11y-details test", () => { describe("Edge cases and error handling", () => { it("should remain accessible with no slotted content", async () => { - const testElement = await fixture(html` - - `); + const testElement = await fixture(html` `); await testElement.updateComplete; await expect(testElement).shadowDom.to.be.accessible(); }); @@ -453,7 +458,7 @@ describe("a11y-details test", () => {
    Test details
    `); - + // Test with various unusual values const unusualValues = [ " \t\n ", // whitespace @@ -462,14 +467,14 @@ describe("a11y-details test", () => { "🚀 emoji content 🎉", // emoji "Very long text that might cause layout issues or accessibility problems when used as button text for the summary element", "Multi\nline\ntext", // multiline - "Text with 'quotes' and \"double quotes\" and special chars: !@#$%^&*()" + "Text with 'quotes' and \"double quotes\" and special chars: !@#$%^&*()", ]; - + for (const value of unusualValues) { testElement.openText = value; testElement.closeText = value; await testElement.updateComplete; - + expect(testElement.openText).to.equal(value); expect(testElement.closeText).to.equal(value); await expect(testElement).shadowDom.to.be.accessible(); @@ -500,7 +505,7 @@ describe("a11y-details test", () => { it("should maintain accessibility with HAX demo schema", async () => { const demoSchema = element.constructor.haxProperties.demoSchema[0]; const haxTestElement = await fixture(html` - diff --git a/elements/a11y-figure/test/a11y-figure.test.js b/elements/a11y-figure/test/a11y-figure.test.js index a868f4f18d..480c6f3158 100644 --- a/elements/a11y-figure/test/a11y-figure.test.js +++ b/elements/a11y-figure/test/a11y-figure.test.js @@ -5,13 +5,15 @@ describe("a11y-figure test", () => { let element; beforeEach(async () => { element = await fixture(html` -

    Figure caption text

    Image description
    -
    Detailed image description with more information about the image.
    +
    + Detailed image description with more information about the image. +
    `); }); @@ -41,7 +43,7 @@ describe("a11y-figure test", () => { it("should have summary slot", () => { // The summary slot is nested within the a11y-details component - const a11yDetails = element.shadowRoot.querySelector('a11y-details'); + const a11yDetails = element.shadowRoot.querySelector("a11y-details"); expect(a11yDetails).to.exist; // We can't directly test the slot content due to shadow DOM encapsulation, // but we can ensure our component passes it correctly @@ -53,11 +55,13 @@ describe("a11y-figure test", () => { it("should have details slot", () => { const slotContainer = element.querySelector('[slot="details"]'); expect(slotContainer).to.exist; - expect(slotContainer.textContent).to.contain("Detailed image description"); + expect(slotContainer.textContent).to.contain( + "Detailed image description", + ); }); it("should have default hidden slot", () => { - const defaultSlot = element.shadowRoot.querySelector('slot[hidden]'); + const defaultSlot = element.shadowRoot.querySelector("slot[hidden]"); expect(defaultSlot).to.exist; }); }); @@ -81,9 +85,12 @@ describe("a11y-figure test", () => { expect(testElement.imgSrc).to.equal("https://placehold.co/400x300"); await expect(testElement).shadowDom.to.be.accessible(); - testElement.imgSrc = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"; + testElement.imgSrc = + "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"; await testElement.updateComplete; - expect(testElement.imgSrc).to.equal("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"); + expect(testElement.imgSrc).to.equal( + "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7", + ); await expect(testElement).shadowDom.to.be.accessible(); testElement.imgSrc = ""; @@ -131,9 +138,12 @@ describe("a11y-figure test", () => { expect(testElement.imgAlt).to.equal(""); await expect(testElement).shadowDom.to.be.accessible(); - testElement.imgAlt = "Long descriptive alt text for a complex image that provides context for screen reader users"; + testElement.imgAlt = + "Long descriptive alt text for a complex image that provides context for screen reader users"; await testElement.updateComplete; - expect(testElement.imgAlt).to.equal("Long descriptive alt text for a complex image that provides context for screen reader users"); + expect(testElement.imgAlt).to.equal( + "Long descriptive alt text for a complex image that provides context for screen reader users", + ); await expect(testElement).shadowDom.to.be.accessible(); }); @@ -163,28 +173,28 @@ describe("a11y-figure test", () => { it("should be set correctly when details or summary slots are used", async () => { // No summary or details initially expect(testElement.__hasDetail).to.be.false; - + // Add a summary element - const summaryElem = document.createElement('div'); - summaryElem.setAttribute('slot', 'summary'); - summaryElem.textContent = 'Test Summary'; + const summaryElem = document.createElement("div"); + summaryElem.setAttribute("slot", "summary"); + summaryElem.textContent = "Test Summary"; testElement.appendChild(summaryElem); await testElement.updateComplete; - + // Test that __hasDetail is now true expect(testElement.__hasDetail).to.be.true; await expect(testElement).shadowDom.to.be.accessible(); - + // Remove the summary element testElement.removeChild(summaryElem); - + // Add a details element - const detailsElem = document.createElement('div'); - detailsElem.setAttribute('slot', 'details'); - detailsElem.textContent = 'Test Details'; + const detailsElem = document.createElement("div"); + detailsElem.setAttribute("slot", "details"); + detailsElem.textContent = "Test Details"; testElement.appendChild(detailsElem); await testElement.updateComplete; - + // Test that __hasDetail remains true expect(testElement.__hasDetail).to.be.true; await expect(testElement).shadowDom.to.be.accessible(); @@ -244,7 +254,10 @@ describe("a11y-figure test", () => { describe("Accessibility scenarios with different property combinations", () => { it("should remain accessible with image and alt text", async () => { const testElement = await fixture(html` - +

    Simple figure

    `); @@ -271,7 +284,10 @@ describe("a11y-figure test", () => { it("should remain accessible with only image and no details", async () => { const testElement = await fixture(html` - +

    Figure without details

    `); @@ -282,7 +298,11 @@ describe("a11y-figure test", () => { it("should remain accessible with slotted image instead of src", async () => { const testElement = await fixture(html` - Slotted placeholder + Slotted placeholder

    Figure with slotted image

    `); @@ -319,13 +339,14 @@ describe("a11y-figure test", () => { `); await testElement.updateComplete; await expect(testElement).shadowDom.to.be.accessible(); - + // This is a bit limited since we can't directly access the nested a11y-details component // due to shadow DOM encapsulation, but we're testing the setup is accessible - const nestedA11yDetails = testElement.shadowRoot.querySelector('a11y-details'); + const nestedA11yDetails = + testElement.shadowRoot.querySelector("a11y-details"); expect(nestedA11yDetails).to.exist; - expect(nestedA11yDetails.getAttribute('open-text')).to.equal('Show'); - expect(nestedA11yDetails.getAttribute('close-text')).to.equal('Hide'); + expect(nestedA11yDetails.getAttribute("open-text")).to.equal("Show"); + expect(nestedA11yDetails.getAttribute("close-text")).to.equal("Hide"); }); }); @@ -342,7 +363,10 @@ describe("a11y-figure test", () => { it("should remain accessible with empty figcaption", async () => { const testElement = await fixture(html` - +

    `); @@ -352,7 +376,10 @@ describe("a11y-figure test", () => { it("should remain accessible with no figcaption", async () => { const testElement = await fixture(html` - + `); await testElement.updateComplete; @@ -381,14 +408,14 @@ describe("a11y-figure test", () => { it("should handle HAX image upload integration", () => { const haxProps = element.constructor.haxProperties; const configItems = haxProps.settings.configure; - + // Verify imgSrc property has haxupload input method - const imgSrcProp = configItems.find(item => item.property === "imgSrc"); + const imgSrcProp = configItems.find((item) => item.property === "imgSrc"); expect(imgSrcProp).to.exist; expect(imgSrcProp.inputMethod).to.equal("haxupload"); - + // Verify imgAlt property exists and is required - const imgAltProp = configItems.find(item => item.property === "imgAlt"); + const imgAltProp = configItems.find((item) => item.property === "imgAlt"); expect(imgAltProp).to.exist; expect(imgAltProp.required).to.be.true; }); @@ -396,7 +423,7 @@ describe("a11y-figure test", () => { it("should maintain accessibility with HAX demo schema", async () => { const demoSchema = element.constructor.haxProperties.demoSchema[0]; const haxTestElement = await fixture(html` - { ).to.equal("Link"); expect(item.href).to.equal("../"); }); - + it("basic setup for testing the button case", async () => { // case 2 with a button const button = element.querySelector( @@ -72,7 +72,7 @@ describe("a11y-menu-button test", () => { describe("Boolean properties", () => { it("should handle expanded property", async () => { expect(testElement.expanded).to.equal(false); - + testElement.expanded = true; await testElement.updateComplete; expect(testElement.expanded).to.equal(true); @@ -82,7 +82,7 @@ describe("a11y-menu-button test", () => { it("should handle disabled property", async () => { expect(testElement.disabled).to.be.undefined; - + testElement.disabled = true; await testElement.updateComplete; expect(testElement.disabled).to.equal(true); @@ -91,7 +91,7 @@ describe("a11y-menu-button test", () => { it("should handle keepOpenOnClick property", async () => { expect(testElement.keepOpenOnClick).to.equal(false); - + testElement.keepOpenOnClick = true; await testElement.updateComplete; expect(testElement.keepOpenOnClick).to.equal(true); @@ -100,7 +100,7 @@ describe("a11y-menu-button test", () => { it("should handle noOpenOnHover property", async () => { expect(testElement.noOpenOnHover).to.equal(false); - + testElement.noOpenOnHover = true; await testElement.updateComplete; expect(testElement.noOpenOnHover).to.equal(true); @@ -111,7 +111,7 @@ describe("a11y-menu-button test", () => { describe("String properties", () => { it("should handle position property", async () => { expect(testElement.position).to.equal("bottom"); - + testElement.position = "top"; await testElement.updateComplete; expect(testElement.position).to.equal("top"); @@ -121,7 +121,7 @@ describe("a11y-menu-button test", () => { it("should handle positionAlign property", async () => { expect(testElement.positionAlign).to.equal("start"); - + testElement.positionAlign = "end"; await testElement.updateComplete; expect(testElement.positionAlign).to.equal("end"); @@ -133,7 +133,7 @@ describe("a11y-menu-button test", () => { describe("Number properties", () => { it("should handle offset property", async () => { expect(testElement.offset).to.equal(0); - + testElement.offset = 10; await testElement.updateComplete; expect(testElement.offset).to.equal(10); @@ -150,13 +150,15 @@ describe("a11y-menu-button test", () => { `); await testElement.updateComplete; - - const buttonSlot = testElement.shadowRoot.querySelector('slot[name="button"]'); + + const buttonSlot = testElement.shadowRoot.querySelector( + 'slot[name="button"]', + ); expect(buttonSlot).to.exist; const assignedNodes = buttonSlot.assignedNodes({ flatten: true }); expect(assignedNodes.length).to.be.greaterThan(0); expect(assignedNodes[0].textContent).to.equal("Custom Button Text"); - + await expect(testElement).shadowDom.to.be.accessible(); }); @@ -164,25 +166,30 @@ describe("a11y-menu-button test", () => { const testElement = await fixture(html` Menu - Slotted Item + Slotted Item Default Item `); await testElement.updateComplete; - - const menuitemSlot = testElement.shadowRoot.querySelector('slot[name="menuitem"]'); + + const menuitemSlot = testElement.shadowRoot.querySelector( + 'slot[name="menuitem"]', + ); expect(menuitemSlot).to.exist; - - const defaultSlot = testElement.shadowRoot.querySelector('slot:not([name])'); + + const defaultSlot = + testElement.shadowRoot.querySelector("slot:not([name])"); expect(defaultSlot).to.exist; - + await expect(testElement).shadowDom.to.be.accessible(); }); }); describe("Menu functionality", () => { let menuElement; - + beforeEach(async () => { menuElement = await fixture(html` @@ -197,17 +204,17 @@ describe("a11y-menu-button test", () => { it("should open and close menu", async () => { expect(menuElement.expanded).to.be.false; - + // Test open method menuElement.open(); await menuElement.updateComplete; expect(menuElement.expanded).to.be.true; - + // Test close method menuElement.close(true); await menuElement.updateComplete; expect(menuElement.expanded).to.be.false; - + await expect(menuElement).shadowDom.to.be.accessible(); }); @@ -215,13 +222,13 @@ describe("a11y-menu-button test", () => { // First ensure menu items are properly added expect(menuElement.menuItems).to.exist; expect(menuElement.menuItems.length).to.be.greaterThan(0); - + // Test first item getter expect(menuElement.firstItem).to.exist; - + // Test last item getter expect(menuElement.lastItem).to.exist; - + await expect(menuElement).shadowDom.to.be.accessible(); }); @@ -229,7 +236,7 @@ describe("a11y-menu-button test", () => { // Test focus method menuElement.focus(); await menuElement.updateComplete; - + // Test focusOn method with first item if (menuElement.firstItem) { menuElement.focusOn(menuElement.firstItem); @@ -237,14 +244,14 @@ describe("a11y-menu-button test", () => { expect(menuElement.expanded).to.be.true; expect(menuElement.currentItem).to.equal(menuElement.firstItem); } - + await expect(menuElement).shadowDom.to.be.accessible(); }); }); describe("Event handling", () => { let eventElement; - + beforeEach(async () => { eventElement = await fixture(html` @@ -258,57 +265,57 @@ describe("a11y-menu-button test", () => { it("should fire open event", async () => { let openEventFired = false; - - eventElement.addEventListener('open', () => { + + eventElement.addEventListener("open", () => { openEventFired = true; }); - + eventElement.open(); await eventElement.updateComplete; - + expect(openEventFired).to.be.true; await expect(eventElement).shadowDom.to.be.accessible(); }); it("should fire close event", async () => { let closeEventFired = false; - - eventElement.addEventListener('close', () => { + + eventElement.addEventListener("close", () => { closeEventFired = true; }); - + eventElement.open(); await eventElement.updateComplete; - + eventElement.close(true); await eventElement.updateComplete; - + expect(closeEventFired).to.be.true; await expect(eventElement).shadowDom.to.be.accessible(); }); it("should handle focus and blur events", async () => { expect(eventElement.focused).to.be.undefined; - + eventElement._handleFocus(); expect(eventElement.focused).to.be.true; - + eventElement._handleBlur(); expect(eventElement.focused).to.be.false; - + await expect(eventElement).shadowDom.to.be.accessible(); }); it("should handle mouseover and mouseout events", async () => { expect(eventElement.hovered).to.be.undefined; - + eventElement._handleMouseover(); expect(eventElement.hovered).to.be.true; expect(eventElement.expanded).to.be.true; // Should open on hover by default - + eventElement._handleMouseout(); expect(eventElement.hovered).to.be.false; - + await expect(eventElement).shadowDom.to.be.accessible(); }); }); @@ -322,18 +329,18 @@ describe("a11y-menu-button test", () => { `); await testElement.updateComplete; - - const button = testElement.shadowRoot.querySelector('#menubutton'); + + const button = testElement.shadowRoot.querySelector("#menubutton"); expect(button).to.exist; - expect(button.getAttribute('aria-haspopup')).to.equal('true'); - expect(button.getAttribute('aria-controls')).to.equal('menu'); - expect(button.getAttribute('aria-expanded')).to.equal('false'); - - const menu = testElement.shadowRoot.querySelector('#menu'); + expect(button.getAttribute("aria-haspopup")).to.equal("true"); + expect(button.getAttribute("aria-controls")).to.equal("menu"); + expect(button.getAttribute("aria-expanded")).to.equal("false"); + + const menu = testElement.shadowRoot.querySelector("#menu"); expect(menu).to.exist; - expect(menu.getAttribute('role')).to.equal('menu'); - expect(menu.getAttribute('aria-labelledby')).to.equal('menubutton'); - + expect(menu.getAttribute("role")).to.equal("menu"); + expect(menu.getAttribute("aria-labelledby")).to.equal("menubutton"); + await expect(testElement).shadowDom.to.be.accessible(); }); @@ -345,22 +352,22 @@ describe("a11y-menu-button test", () => { `); await testElement.updateComplete; - - const button = testElement.shadowRoot.querySelector('#menubutton'); - expect(button.getAttribute('aria-expanded')).to.equal('false'); - + + const button = testElement.shadowRoot.querySelector("#menubutton"); + expect(button.getAttribute("aria-expanded")).to.equal("false"); + testElement.expanded = true; await testElement.updateComplete; - expect(button.getAttribute('aria-expanded')).to.equal('true'); - + expect(button.getAttribute("aria-expanded")).to.equal("true"); + await expect(testElement).shadowDom.to.be.accessible(); }); }); describe("Positioning", () => { it("should handle different position values", async () => { - const positions = ['top', 'bottom', 'left', 'right']; - + const positions = ["top", "bottom", "left", "right"]; + for (const pos of positions) { const testElement = await fixture(html` @@ -369,20 +376,22 @@ describe("a11y-menu-button test", () => { `); await testElement.updateComplete; - + expect(testElement.position).to.equal(pos); - - const positionBehavior = testElement.shadowRoot.querySelector('absolute-position-behavior'); + + const positionBehavior = testElement.shadowRoot.querySelector( + "absolute-position-behavior", + ); expect(positionBehavior).to.exist; - expect(positionBehavior.getAttribute('position')).to.equal(pos); - + expect(positionBehavior.getAttribute("position")).to.equal(pos); + await expect(testElement).shadowDom.to.be.accessible(); } }); it("should handle different position-align values", async () => { - const alignments = ['start', 'center', 'end']; - + const alignments = ["start", "center", "end"]; + for (const align of alignments) { const testElement = await fixture(html` @@ -391,13 +400,15 @@ describe("a11y-menu-button test", () => { `); await testElement.updateComplete; - + expect(testElement.positionAlign).to.equal(align); - - const positionBehavior = testElement.shadowRoot.querySelector('absolute-position-behavior'); + + const positionBehavior = testElement.shadowRoot.querySelector( + "absolute-position-behavior", + ); expect(positionBehavior).to.exist; - expect(positionBehavior.getAttribute('position-align')).to.equal(align); - + expect(positionBehavior.getAttribute("position-align")).to.equal(align); + await expect(testElement).shadowDom.to.be.accessible(); } }); @@ -411,12 +422,12 @@ describe("a11y-menu-button test", () => { `); await testElement.updateComplete; - - expect(testElement.menuItems).to.be.an('array'); + + expect(testElement.menuItems).to.be.an("array"); expect(testElement.menuItems.length).to.equal(0); expect(testElement.firstItem).to.be.undefined; expect(testElement.lastItem).to.be.undefined; - + await expect(testElement).shadowDom.to.be.accessible(); }); @@ -428,13 +439,13 @@ describe("a11y-menu-button test", () => { `); await testElement.updateComplete; - + expect(testElement.noOpenOnHover).to.be.true; - + testElement._handleMouseover(); expect(testElement.hovered).to.be.true; expect(testElement.expanded).to.be.false; // Should not open on hover when disabled - + await expect(testElement).shadowDom.to.be.accessible(); }); @@ -446,27 +457,27 @@ describe("a11y-menu-button test", () => { `); await testElement.updateComplete; - + expect(testElement.keepOpenOnClick).to.be.true; - + testElement.open(); await testElement.updateComplete; expect(testElement.expanded).to.be.true; - + // Simulate item click with keepOpenOnClick enabled const mockEvent = { stopPropagation: () => {} }; testElement._handleItemClick(mockEvent); await testElement.updateComplete; - + // Menu should still be open expect(testElement.expanded).to.be.true; - + await expect(testElement).shadowDom.to.be.accessible(); }); it("should handle extreme offset values", async () => { const extremeOffsets = [-100, 0, 50, 1000]; - + for (const offset of extremeOffsets) { const testElement = await fixture(html` @@ -475,12 +486,14 @@ describe("a11y-menu-button test", () => { `); await testElement.updateComplete; - + expect(testElement.offset).to.equal(offset); - - const positionBehavior = testElement.shadowRoot.querySelector('absolute-position-behavior'); + + const positionBehavior = testElement.shadowRoot.querySelector( + "absolute-position-behavior", + ); expect(positionBehavior).to.exist; - + await expect(testElement).shadowDom.to.be.accessible(); } }); @@ -494,22 +507,24 @@ describe("a11y-menu-button test", () => { `); await testElement.updateComplete; - + expect(testElement.menuItems.length).to.equal(0); - + // Create a new menu item - const newItem = globalThis.document.createElement('a11y-menu-button-item'); - newItem.textContent = 'New Item'; - + const newItem = globalThis.document.createElement( + "a11y-menu-button-item", + ); + newItem.textContent = "New Item"; + // Add the item testElement.addItem(newItem); expect(testElement.menuItems.length).to.equal(1); expect(testElement.menuItems[0]).to.equal(newItem); - + // Remove the item testElement.removeItem(newItem); expect(testElement.menuItems.length).to.equal(0); - + await expect(testElement).shadowDom.to.be.accessible(); }); }); diff --git a/elements/absolute-position-behavior/test/absolute-position-behavior.test.js b/elements/absolute-position-behavior/test/absolute-position-behavior.test.js index 74bf31292b..7de95aebfd 100644 --- a/elements/absolute-position-behavior/test/absolute-position-behavior.test.js +++ b/elements/absolute-position-behavior/test/absolute-position-behavior.test.js @@ -5,23 +5,29 @@ describe("absolute-position-behavior test", () => { let element; beforeEach(async () => { element = await fixture(html` -
    -
    Target
    - +
    + Target +
    +
    Positioned content
    `); - element = element.querySelector('absolute-position-behavior'); + element = element.querySelector("absolute-position-behavior"); }); it("basic setup", async () => { expect(element).to.exist; - expect(element.tagName.toLowerCase()).to.equal("absolute-position-behavior"); + expect(element.tagName.toLowerCase()).to.equal( + "absolute-position-behavior", + ); }); it("passes the a11y audit", async () => { @@ -30,7 +36,7 @@ describe("absolute-position-behavior test", () => { describe("Slot functionality", () => { it("should have default slot with correct content", () => { - const slot = element.shadowRoot.querySelector('slot'); + const slot = element.shadowRoot.querySelector("slot"); expect(slot).to.exist; const assignedNodes = slot.assignedNodes({ flatten: true }); expect(assignedNodes.length).to.be.greaterThan(0); @@ -225,7 +231,7 @@ describe("absolute-position-behavior test", () => { describe("position property", () => { it("should accept valid position values and maintain accessibility", async () => { const validPositions = ["top", "bottom", "left", "right"]; - + for (const pos of validPositions) { testElement.position = pos; await testElement.updateComplete; @@ -254,7 +260,7 @@ describe("absolute-position-behavior test", () => { describe("positionAlign property", () => { it("should accept valid alignment values and maintain accessibility", async () => { const validAligns = ["start", "end", "center"]; - + for (const align of validAligns) { testElement.positionAlign = align; await testElement.updateComplete; @@ -288,9 +294,9 @@ describe("absolute-position-behavior test", () => { describe("target property", () => { it("should accept element object values and maintain accessibility", async () => { - const targetDiv = globalThis.document.createElement('div'); - targetDiv.id = 'test-target'; - + const targetDiv = globalThis.document.createElement("div"); + targetDiv.id = "test-target"; + testElement.target = targetDiv; await testElement.updateComplete; expect(testElement.target).to.equal(targetDiv); @@ -309,7 +315,7 @@ describe("absolute-position-behavior test", () => { describe("__positions property (internal)", () => { it("should handle object values and maintain accessibility", async () => { - const positions = { top: '10px', left: '20px' }; + const positions = { top: "10px", left: "20px" }; testElement.__positions = positions; await testElement.updateComplete; expect(testElement.__positions).to.deep.equal(positions); @@ -392,12 +398,20 @@ describe("absolute-position-behavior test", () => { describe("Positioning functionality and accessibility", () => { it("should maintain accessibility with different positioning configurations", async () => { const positions = ["top", "bottom", "left", "right"]; - + for (const pos of positions) { const container = await fixture(html` -
    -
    Target
    - +
    + Target +
    + {
    `); - - const positionedElement = container.querySelector('absolute-position-behavior'); + + const positionedElement = container.querySelector( + "absolute-position-behavior", + ); await positionedElement.updateComplete; await expect(positionedElement).shadowDom.to.be.accessible(); } @@ -417,8 +433,13 @@ describe("absolute-position-behavior test", () => { it("should remain accessible with sticky positioning", async () => { const testElement = await fixture(html`
    -
    Sticky Target
    - + Sticky Target +
    + {
    `); - - const positionedElement = testElement.querySelector('absolute-position-behavior'); + + const positionedElement = testElement.querySelector( + "absolute-position-behavior", + ); await positionedElement.updateComplete; await expect(positionedElement).shadowDom.to.be.accessible(); }); it("should maintain accessibility with fit-to-visible-bounds enabled", async () => { const testElement = await fixture(html` -
    -
    Edge Target
    - +
    + Edge Target +
    + {
    `); - - const positionedElement = testElement.querySelector('absolute-position-behavior'); + + const positionedElement = testElement.querySelector( + "absolute-position-behavior", + ); await positionedElement.updateComplete; await expect(positionedElement).shadowDom.to.be.accessible(); }); it("should handle positioning with offset values", async () => { const offsets = [0, 10, -5, 25]; - + for (const offset of offsets) { const testElement = await fixture(html`
    -
    Offset Target
    - + Offset Target +
    + {
    `); - - const positionedElement = testElement.querySelector('absolute-position-behavior'); + + const positionedElement = testElement.querySelector( + "absolute-position-behavior", + ); await positionedElement.updateComplete; await expect(positionedElement).shadowDom.to.be.accessible(); } @@ -483,27 +522,31 @@ describe("absolute-position-behavior test", () => { it("should handle auto positioning lifecycle", async () => { const testElement = await fixture(html`
    -
    Auto Target
    - + Auto Target +
    +
    Auto positioning test
    `); - - const positionedElement = testElement.querySelector('absolute-position-behavior'); - + + const positionedElement = testElement.querySelector( + "absolute-position-behavior", + ); + // Initially auto should be false expect(positionedElement.auto).to.be.false; await expect(positionedElement).shadowDom.to.be.accessible(); - + // Enable auto positioning positionedElement.auto = true; await positionedElement.updateComplete; await expect(positionedElement).shadowDom.to.be.accessible(); - + // Disable auto positioning positionedElement.auto = false; await positionedElement.updateComplete; @@ -513,28 +556,32 @@ describe("absolute-position-behavior test", () => { it("should handle manual positioning methods", async () => { const testElement = await fixture(html`
    -
    Manual Target
    - + Manual Target +
    +
    Manual positioning test
    `); - - const positionedElement = testElement.querySelector('absolute-position-behavior'); - + + const positionedElement = testElement.querySelector( + "absolute-position-behavior", + ); + // Test manual setPosition positionedElement.setPosition(); await positionedElement.updateComplete; await expect(positionedElement).shadowDom.to.be.accessible(); - + // Test updatePosition positionedElement.updatePosition(); await positionedElement.updateComplete; await expect(positionedElement).shadowDom.to.be.accessible(); - + // Test unsetPosition positionedElement.unsetPosition(); await positionedElement.updateComplete; @@ -545,7 +592,7 @@ describe("absolute-position-behavior test", () => { describe("Edge cases and error handling", () => { it("should remain accessible when target element doesn't exist", async () => { const testElement = await fixture(html` - {
    Content for missing target
    `); - + await testElement.updateComplete; await expect(testElement).shadowDom.to.be.accessible(); }); @@ -564,7 +611,7 @@ describe("absolute-position-behavior test", () => {
    Hidden content
    `); - + await testElement.updateComplete; // Element is hidden, so accessibility testing isn't meaningful expect(testElement.hidden).to.be.true; @@ -576,7 +623,7 @@ describe("absolute-position-behavior test", () => {
    Test content
    `); - + const unusualValues = [ " \t\n ", // whitespace "", // potentially dangerous content @@ -584,14 +631,14 @@ describe("absolute-position-behavior test", () => { "🗺 positioned content 🗺", // emoji "Very long positioning identifier that might cause issues with layout or positioning calculations", "Multi\nline\ntext", // multiline - "Text with 'quotes' and \"double quotes\" and special chars: !@#$%^&*()" + "Text with 'quotes' and \"double quotes\" and special chars: !@#$%^&*()", ]; - + for (const value of unusualValues) { testElement.for = value; testElement.position = value; await testElement.updateComplete; - + expect(testElement.for).to.equal(value); expect(testElement.position).to.equal(value); await expect(testElement).shadowDom.to.be.accessible(); @@ -604,13 +651,13 @@ describe("absolute-position-behavior test", () => {
    Extreme offset test
    `); - + const extremeOffsets = [-1000, 0, 1000, 99999, -99999]; - + for (const offset of extremeOffsets) { testElement.offset = offset; await testElement.updateComplete; - + expect(testElement.offset).to.equal(offset); await expect(testElement).shadowDom.to.be.accessible(); } @@ -621,13 +668,18 @@ describe("absolute-position-behavior test", () => { it("should maintain accessibility with different position-align combinations", async () => { const positions = ["top", "bottom", "left", "right"]; const alignments = ["start", "end", "center"]; - + for (const pos of positions) { for (const align of alignments) { const testElement = await fixture(html`
    -
    Align Target
    - + Align Target +
    + {
    `); - - const positionedElement = testElement.querySelector('absolute-position-behavior'); + + const positionedElement = testElement.querySelector( + "absolute-position-behavior", + ); await positionedElement.updateComplete; await expect(positionedElement).shadowDom.to.be.accessible(); } @@ -650,8 +704,13 @@ describe("absolute-position-behavior test", () => { it("should maintain accessibility during state manager interactions", async () => { const testElement = await fixture(html`
    -
    Manager Target
    - + Manager Target +
    + {
    `); - - const positionedElement = testElement.querySelector('absolute-position-behavior'); + + const positionedElement = testElement.querySelector( + "absolute-position-behavior", + ); await positionedElement.updateComplete; - + // Test that the element integrates with AbsolutePositionStateManager expect(globalThis.AbsolutePositionStateManager).to.exist; - + await expect(positionedElement).shadowDom.to.be.accessible(); }); }); @@ -678,14 +739,11 @@ describe("absolute-position-behavior test", () => { // This tests that the behavior class can be used as a mixin // The accessibility should be maintained regardless of usage pattern const testElement = await fixture(html` - +
    Mixin usage test
    `); - + await testElement.updateComplete; await expect(testElement).shadowDom.to.be.accessible(); }); diff --git a/elements/aframe-player/test/aframe-player.test.js b/elements/aframe-player/test/aframe-player.test.js index 23096267a1..672ba28e2d 100644 --- a/elements/aframe-player/test/aframe-player.test.js +++ b/elements/aframe-player/test/aframe-player.test.js @@ -5,7 +5,7 @@ describe("aframe-player test", () => { let element; beforeEach(async () => { element = await fixture(html` - { let testElement; beforeEach(async () => { - testElement = await fixture(html` - - `); + testElement = await fixture(html` `); await testElement.updateComplete; }); @@ -173,7 +171,7 @@ describe("aframe-player test", () => { testElement.y = "2.0"; testElement.z = "-1.0"; await testElement.updateComplete; - + expect(testElement.x).to.equal("1.5"); expect(testElement.y).to.equal("2.0"); expect(testElement.z).to.equal("-1.0"); @@ -193,7 +191,7 @@ describe("aframe-player test", () => { testElement.y = "2"; testElement.z = "3"; await testElement.updateComplete; - + expect(testElement.position).to.deep.equal({ x: "1", y: "2", z: "3" }); await expect(testElement).to.be.accessible(); }); @@ -202,15 +200,15 @@ describe("aframe-player test", () => { testElement.x = "5"; await testElement.updateComplete; expect(testElement.position.x).to.equal("5"); - + testElement.y = "10"; await testElement.updateComplete; expect(testElement.position.y).to.equal("10"); - + testElement.z = "-5"; await testElement.updateComplete; expect(testElement.position.z).to.equal("-5"); - + await expect(testElement).to.be.accessible(); }); }); @@ -229,20 +227,20 @@ describe("aframe-player test", () => { describe("A-Frame scene rendering", () => { it("should render a-scene element with correct attributes", async () => { const testElement = await fixture(html` - `); await testElement.updateComplete; - - const scene = testElement.querySelector('a-scene'); + + const scene = testElement.querySelector("a-scene"); expect(scene).to.exist; - expect(scene.getAttribute('embedded')).to.equal(''); - expect(scene.style.width).to.equal('800px'); - expect(scene.style.height).to.equal('600px'); - + expect(scene.getAttribute("embedded")).to.equal(""); + expect(scene.style.width).to.equal("800px"); + expect(scene.style.height).to.equal("600px"); + await expect(testElement).to.be.accessible(); }); @@ -251,11 +249,11 @@ describe("aframe-player test", () => { `); await testElement.updateComplete; - - const sky = testElement.querySelector('a-sky'); + + const sky = testElement.querySelector("a-sky"); expect(sky).to.exist; - expect(sky.getAttribute('color')).to.equal('#FF6B6B'); - + expect(sky.getAttribute("color")).to.equal("#FF6B6B"); + await expect(testElement).to.be.accessible(); }); @@ -264,18 +262,18 @@ describe("aframe-player test", () => { `); await arElement.updateComplete; - - const arScene = arElement.querySelector('a-scene'); - expect(arScene.hasAttribute('arjs')).to.be.true; - + + const arScene = arElement.querySelector("a-scene"); + expect(arScene.hasAttribute("arjs")).to.be.true; + const nonArElement = await fixture(html` `); await nonArElement.updateComplete; - - const nonArScene = nonArElement.querySelector('a-scene'); - expect(nonArScene.hasAttribute('arjs')).to.be.false; - + + const nonArScene = nonArElement.querySelector("a-scene"); + expect(nonArScene.hasAttribute("arjs")).to.be.false; + await expect(arElement).to.be.accessible(); await expect(nonArElement).to.be.accessible(); }); @@ -285,11 +283,11 @@ describe("aframe-player test", () => { `); await testElement.updateComplete; - - const markerCamera = testElement.querySelector('a-marker-camera'); + + const markerCamera = testElement.querySelector("a-marker-camera"); expect(markerCamera).to.exist; - expect(markerCamera.getAttribute('preset')).to.equal('hiro'); - + expect(markerCamera.getAttribute("preset")).to.equal("hiro"); + await expect(testElement).to.be.accessible(); }); }); @@ -297,7 +295,7 @@ describe("aframe-player test", () => { describe("Accessibility scenarios with different configurations", () => { it("should remain accessible in AR mode", async () => { const testElement = await fixture(html` - { `); await testElement.updateComplete; - - const position = testElement._computePosition("1", "2", "3", "640px", "480px"); + + const position = testElement._computePosition( + "1", + "2", + "3", + "640px", + "480px", + ); expect(position).to.deep.equal({ x: "1", y: "2", z: "3" }); - + await expect(testElement).to.be.accessible(); }); @@ -354,12 +358,12 @@ describe("aframe-player test", () => { `); await testElement.updateComplete; - + testElement.x = "10"; testElement.y = "20"; testElement.z = "30"; await testElement.updateComplete; - + expect(testElement.position).to.deep.equal({ x: "10", y: "20", z: "30" }); await expect(testElement).to.be.accessible(); }); @@ -396,26 +400,32 @@ describe("aframe-player test", () => { `); await testElement.updateComplete; - - expect(testElement.position).to.deep.equal({ - x: "999999", - y: "-999999", - z: "0.0001" + + expect(testElement.position).to.deep.equal({ + x: "999999", + y: "-999999", + z: "0.0001", }); await expect(testElement).to.be.accessible(); }); it("should handle unusual dimension values", async () => { const unusualValues = [ - "0px", "10000px", "1vh", "1vw", "1em", "1rem", "50%" + "0px", + "10000px", + "1vh", + "1vw", + "1em", + "1rem", + "50%", ]; - + for (const value of unusualValues) { const testElement = await fixture(html` `); await testElement.updateComplete; - + expect(testElement.width).to.equal(value); expect(testElement.height).to.equal(value); await expect(testElement).to.be.accessible(); @@ -424,20 +434,26 @@ describe("aframe-player test", () => { it("should handle edge case property values", async () => { const testElement = await fixture(html``); - + const edgeCaseValues = [ " \t\n ", // whitespace - "0", "000", "-0", "+0", // various zero representations - "1e6", "1e-6", // scientific notation - "NaN", "Infinity", "-Infinity" // special numeric values + "0", + "000", + "-0", + "+0", // various zero representations + "1e6", + "1e-6", // scientific notation + "NaN", + "Infinity", + "-Infinity", // special numeric values ]; - + for (const value of edgeCaseValues) { testElement.x = value; testElement.y = value; testElement.z = value; await testElement.updateComplete; - + expect(testElement.x).to.equal(value); expect(testElement.y).to.equal(value); expect(testElement.z).to.equal(value); @@ -466,24 +482,26 @@ describe("aframe-player test", () => { it("should have proper HAX settings configuration", () => { const haxProps = element.constructor.haxProperties; const configItems = haxProps.settings.configure; - + // Verify source property is required - const sourceProp = configItems.find(item => item.property === "source"); + const sourceProp = configItems.find((item) => item.property === "source"); expect(sourceProp).to.exist; expect(sourceProp.required).to.be.true; expect(sourceProp.inputMethod).to.equal("textfield"); - + // Verify coordinate properties are required - const xProp = configItems.find(item => item.property === "x"); - const yProp = configItems.find(item => item.property === "y"); - const zProp = configItems.find(item => item.property === "z"); - + const xProp = configItems.find((item) => item.property === "x"); + const yProp = configItems.find((item) => item.property === "y"); + const zProp = configItems.find((item) => item.property === "z"); + expect(xProp.required).to.be.true; expect(yProp.required).to.be.true; expect(zProp.required).to.be.true; - + // Verify skyColor has colorpicker input method - const skyColorProp = configItems.find(item => item.property === "skyColor"); + const skyColorProp = configItems.find( + (item) => item.property === "skyColor", + ); expect(skyColorProp).to.exist; expect(skyColorProp.inputMethod).to.equal("colorpicker"); }); @@ -491,8 +509,8 @@ describe("aframe-player test", () => { it("should handle 3D file types correctly", () => { const haxProps = element.constructor.haxProperties; const handles = haxProps.gizmo.handles; - - const fileHandle = handles.find(handle => handle.type === "3d"); + + const fileHandle = handles.find((handle) => handle.type === "3d"); expect(fileHandle).to.exist; expect(fileHandle.source).to.equal("source"); }); @@ -507,28 +525,30 @@ describe("aframe-player test", () => { const styles = element.constructor.styles; expect(styles).to.exist; expect(styles.length).to.be.greaterThan(0); - + const styleString = styles[0].cssText || styles[0].toString(); - expect(styleString).to.include(':host'); - expect(styleString).to.include('display: block'); - expect(styleString).to.include('position: relative'); + expect(styleString).to.include(":host"); + expect(styleString).to.include("display: block"); + expect(styleString).to.include("position: relative"); }); }); describe("Lifecycle and cleanup", () => { it("should set up window controllers in constructor", () => { - const testElement = new (element.constructor)(); + const testElement = new element.constructor(); expect(testElement.windowControllers).to.exist; - expect(testElement.windowControllers.constructor.name).to.equal("AbortController"); + expect(testElement.windowControllers.constructor.name).to.equal( + "AbortController", + ); }); it("should clean up window controllers on disconnect", () => { - const testElement = new (element.constructor)(); - const abortSpy = testElement.windowControllers.abort = () => {}; - + const testElement = new element.constructor(); + const abortSpy = (testElement.windowControllers.abort = () => {}); + // Simulate disconnection testElement.disconnectedCallback(); - + // Verify abort was called (basic check) expect(testElement.windowControllers).to.exist; }); diff --git a/elements/app-hax/app-hax.js b/elements/app-hax/app-hax.js index 89f9f070b9..c03b5ed87c 100644 --- a/elements/app-hax/app-hax.js +++ b/elements/app-hax/app-hax.js @@ -18,6 +18,7 @@ import "./lib/v2/app-hax-use-case.js"; import "./lib/v2/app-hax-use-case-filter.js"; import "./lib/v2/app-hax-search-results.js"; import "./lib/v2/app-hax-scroll-button.js"; +import "./lib/v2/app-hax-user-access-modal.js"; const logoutBtn = new URL("./lib/assets/images/Logout.svg", import.meta.url) .href; @@ -212,6 +213,7 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} logOut: "Log out", menu: "Menu", showMore: "More", + userAccess: "User Access", }; if ( typeof globalThis.speechSynthesis !== "undefined" && @@ -653,11 +655,27 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} } // eslint-disable-next-line class-methods-use-this - reset(reload = false) { + reset(reload = false, logout = false) { // localStorage possible to be blocked by permission of system try { globalThis.localStorage.removeItem("app-hax-step"); globalThis.localStorage.removeItem("app-hax-site"); + + // If logout is requested, clear JWT and trigger logout + if (logout) { + globalThis.localStorage.removeItem("jwt"); + store.jwt = null; + // Trigger logout event to clear user session + globalThis.dispatchEvent( + new CustomEvent("jwt-login-logout", { + composed: true, + bubbles: true, + cancelable: false, + detail: true, + }), + ); + } + if (reload) { // should always be a base tag for a SPA but just checking if (document.querySelector("base")) { @@ -735,18 +753,26 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} cancelable: true, composed: true, detail: { - title: "< login >", + title: "Login to HAX", elements: { content: p }, modal: true, styles: { - "--simple-modal-titlebar-background": "transparent", - "--simple-modal-titlebar-color": "black", - "--simple-modal-width": "40vw", + "--simple-modal-titlebar-background": + "var(--ddd-theme-default-nittanyNavy, #001e44)", + "--simple-modal-titlebar-color": + "var(--ddd-theme-default-white, white)", + "--simple-modal-width": "90vw", + "--simple-modal-max-width": "var(--ddd-spacing-32, 480px)", "--simple-modal-min-width": "300px", - "--simple-modal-z-index": "100000000", - "--simple-modal-height": "62vh", - "--simple-modal-min-height": "400px", + "--simple-modal-z-index": "1000", + "--simple-modal-height": "auto", + "--simple-modal-min-height": "300px", + "--simple-modal-max-height": "80vh", "--simple-modal-titlebar-height": "64px", + "--simple-modal-border-radius": "var(--ddd-radius-md, 8px)", + "--simple-modal-background": + "var(--ddd-theme-default-white, white)", + "--simple-modal-box-shadow": "var(--ddd-boxShadow-xl)", }, }, }), @@ -768,7 +794,8 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} display: inline-flex; } #wt { - border: solid 1px var(--simple-colors-default-theme-accent-12, var(--accent-color)); + border: solid 1px + var(--simple-colors-default-theme-accent-12, var(--accent-color)); } simple-toolbar-button { min-width: 48px; @@ -845,7 +872,6 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} } .start-journey { display: flex; - padding-top: 20px; justify-content: center; } app-hax-site-button { @@ -864,23 +890,15 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} --simple-tooltip-font-size: 10px; } } - .label { - display: inline-flex; - text-align: flex-start; - align-items: center; - } app-hax-label { animation: 0.8s ease-in-out 0s scrollin; -webkit-animation: 0.8s ease-in-out 0s scrollin; display: flex; align-self: flex-start; - overflow: hidden; - margin-left: 24px; - margin-right: 24px; } app-hax-label h1 { font-weight: normal; - font-size: 4vw; + font-size: var(--ddd-font-size-xxl, 48px); margin: 0; padding: 0; } @@ -917,7 +935,10 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} display: inline-flex; } main { - padding-top: 80px; + padding-top: var(--ddd-spacing-14); + max-width: 100%; + margin: 0 auto; + box-sizing: border-box; } @media (max-width: 900px) { .characterbtn-name { @@ -982,9 +1003,6 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} .content { margin-top: 4px; } - .start-journey { - padding-top: 0; - } app-hax-site-button { --app-hax-site-button-font-size: 12px; @@ -1247,6 +1265,12 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight}
    + ${this.appMode === "home" || this.appMode === "search" + ? html` +

    HAX Site Dashboard

    +
    Let's build something awesome!
    + ` + : ``} ${this.activeItem && !this.siteReady ? html`

    ${this.activeItem.label}

    @@ -1270,7 +1294,7 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} : ``}
    - +
    ${this.appBody(this.appMode)}
    `; @@ -1293,15 +1317,14 @@ Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} } return template; } - + //EDIT HERE templateHome() { return html` -
    - +
    +
    - - `; + `; } // eslint-disable-next-line class-methods-use-this @@ -1375,4 +1398,4 @@ globalThis.AppHax.requestAvailability = () => { globalThis.AppHax.instance = globalThis.document.querySelector(AppHax.tag); } return globalThis.AppHax.instance; -}; \ No newline at end of file +}; diff --git a/elements/app-hax/custom-elements.json b/elements/app-hax/custom-elements.json index d77b918fc9..877d27e5a5 100644 --- a/elements/app-hax/custom-elements.json +++ b/elements/app-hax/custom-elements.json @@ -78,6 +78,10 @@ { "name": "reload", "default": "false" + }, + { + "name": "logout", + "default": "false" } ] }, @@ -122,10 +126,6 @@ "kind": "method", "name": "openMerlin" }, - { - "kind": "method", - "name": "getNewWord" - }, { "kind": "method", "name": "appBody", @@ -182,7 +182,11 @@ }, { "kind": "field", - "name": "t" + "name": "t", + "type": { + "text": "object" + }, + "default": "{ ...this.t, selectPage: \"Select page\", backToSiteList: \"Back to site list\", listMySites: \"List my sites\", cancel: \"Cancel\", editDetails: \"Page details\", add: \"Add\", editSettings: \"Edit settings\", source: \"Source\", viewSource: \"View source\", findMedia: \"Find media\", undo: \"Undo\", redo: \"Redo\", media: \"Media\", outline: \"Outline\", blocks: \"Blocks\", addBlock: \"Add block\", addPage: \"Add page\", addChildPage: \"Add child page\", clonePage: \"Clone page\", delete: \"Delete page\", siteSettings: \"Site settings\", close: \"Close\", settings: \"Settings\", edit: \"Edit\", configureBlock: \"Configure block\", configure: \"Configure\", save: \"Save\", home: \"Home\", startNewJourney: \"Start new journey\", newJourney: \"New Journey\", accountInfo: \"Account Info\", outlineDesigner: \"Outline designer\", pageOutline: \"Page outline\", more: \"More\", siteActions: \"Site actions\", insights: \"Insights dashboard\", merlin: \"Merlin\", summonMerlin: \"Summon Merlin\", logOut: \"Log out\", menu: \"Menu\", showMore: \"More\", userAccess: \"User Access\", }" }, { "kind": "field", diff --git a/elements/app-hax/demo/index.html b/elements/app-hax/demo/index.html index 0b2b0d722a..8c0e49bc13 100644 --- a/elements/app-hax/demo/index.html +++ b/elements/app-hax/demo/index.html @@ -202,21 +202,38 @@
    diff --git a/elements/app-hax/lib/v2/HAXIAM_API_SPEC.md b/elements/app-hax/lib/v2/HAXIAM_API_SPEC.md new file mode 100644 index 0000000000..8b5d39906a --- /dev/null +++ b/elements/app-hax/lib/v2/HAXIAM_API_SPEC.md @@ -0,0 +1,116 @@ +# HAXiam API Endpoint Specification + +## User Access Management Endpoint + +### Endpoint: POST /api/haxiam/addUserAccess + +This endpoint allows users to grant access to their HAXiam sites by creating symlinks between user directories when the target username exists. + +### Request + +**Method:** POST +**URL:** `/api/haxiam/addUserAccess` + +**Headers:** +- `Content-Type: application/json` +- `Authorization: Bearer {jwt_token}` + +**Request Body:** +```json +{ + "username": "string", // Required: Username to grant access to + "siteId": "string", // Optional: Site identifier + "sitePath": "string" // Optional: Path to the site directory +} +``` + +### Response + +#### Success Response (200 OK) +```json +{ + "status": "success", + "message": "User access granted successfully", + "username": "targetuser", + "timestamp": "2025-10-02T14:45:00Z" +} +``` + +#### Error Responses + +**403 Forbidden - User Not Found** +```json +{ + "status": "error", + "message": "User not found or unauthorized", + "error_code": "USER_NOT_FOUND" +} +``` + +**400 Bad Request - Invalid Input** +```json +{ + "status": "error", + "message": "Username is required", + "error_code": "INVALID_INPUT" +} +``` + +**401 Unauthorized - Invalid Token** +```json +{ + "status": "error", + "message": "Invalid or expired authentication token", + "error_code": "UNAUTHORIZED" +} +``` + +**500 Internal Server Error - System Error** +```json +{ + "status": "error", + "message": "Failed to create user access", + "error_code": "SYSTEM_ERROR" +} +``` + +### Implementation Notes + +1. **HAXcms-PHP Hooks System**: This endpoint will be implemented via the hooks system in HAXcms-PHP, not in the Node.js or typical PHP environment. + +2. **Symlink Creation**: The endpoint creates a symlink between user directories to grant access. The symlink will point from the target user's directory to the requesting user's site. + +3. **User Validation**: The system must verify that the target username exists in the HAXiam system before creating the symlink. + +4. **Security**: + - JWT authentication required + - Validate requesting user has permission to grant access to the specified site + - Prevent directory traversal attacks + - Log all access grant attempts + +5. **Directory Structure**: Assumes HAXiam uses a directory structure where each user has their own folder and symlinks can be created to share access. + +### Frontend Integration + +The frontend modal (`app-hax-user-access-modal.js`) calls this endpoint when a user submits the access form: + +```javascript +const response = await fetch('/api/haxiam/addUserAccess', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${jwt_token}` + }, + body: JSON.stringify({ + username: inputUsername, + siteId: activeSite?.id, + sitePath: activeSite?.location + }) +}); +``` + +### Toast Notifications + +- **Success (200)**: Shows success toast with RPG character matching the added username +- **User Not Found (403)**: Shows error message "User not found or unauthorized" +- **Other Errors**: Shows generic error message with status information \ No newline at end of file diff --git a/elements/app-hax/lib/v2/app-hax-button.js b/elements/app-hax/lib/v2/app-hax-button.js index 9ce890c08b..57215fcbab 100644 --- a/elements/app-hax/lib/v2/app-hax-button.js +++ b/elements/app-hax/lib/v2/app-hax-button.js @@ -12,8 +12,8 @@ export class AppHaxButton extends LitElement { return "app-hax-button"; } -// heeyyyyyyyy heeeyyyyyy -constructor() { + // heeyyyyyyyy heeeyyyyyy + constructor() { super(); this.icon = "save"; this.type = null; diff --git a/elements/app-hax/lib/v2/app-hax-filter-tag.js b/elements/app-hax/lib/v2/app-hax-filter-tag.js index 65a8b3426c..0f3cc08aa8 100644 --- a/elements/app-hax/lib/v2/app-hax-filter-tag.js +++ b/elements/app-hax/lib/v2/app-hax-filter-tag.js @@ -3,27 +3,22 @@ import { LitElement, html, css } from "lit"; import "@haxtheweb/simple-tooltip/simple-tooltip.js"; export class AppHaxFilterTag extends LitElement { - static get tag() { return "app-hax-filter-tag"; } constructor() { super(); - this.label = ''; - + this.label = ""; } static get properties() { return { - label: { type: String }, - + label: { type: String }, }; } - updated(changedProperties) { - - } + updated(changedProperties) {} static get styles() { return [ @@ -35,7 +30,10 @@ export class AppHaxFilterTag extends LitElement { padding-left: 8px; padding-right: 8px; height: 32px; - background-color: var(--simple-colors-default-theme-light-blue-12, var(--accent-color)); + background-color: var( + --simple-colors-default-theme-light-blue-12, + var(--accent-color) + ); border-radius: 8px; font-size: 16px; align-items: center; @@ -56,19 +54,22 @@ export class AppHaxFilterTag extends LitElement { } removeTag() { - this.dispatchEvent(new CustomEvent("remove-tag", { detail: this.label, bubbles: true, composed: true })); + this.dispatchEvent( + new CustomEvent("remove-tag", { + detail: this.label, + bubbles: true, + composed: true, + }), + ); } render() { return html` -
    -

    ${this.label}

    - - -
    - +
    +

    ${this.label}

    + +
    `; } - } customElements.define(AppHaxFilterTag.tag, AppHaxFilterTag); diff --git a/elements/app-hax/lib/v2/app-hax-label.js b/elements/app-hax/lib/v2/app-hax-label.js index aef727147e..dc702123e9 100644 --- a/elements/app-hax/lib/v2/app-hax-label.js +++ b/elements/app-hax/lib/v2/app-hax-label.js @@ -9,8 +9,8 @@ export class AppHaxLabel extends LitElement { constructor() { super(); - this.title = "Welcome"; - this.subtitle = "Start your journey now!"; + this.title = "HAX site list"; + this.subtitle = "Let's build something awesome!"; } static get properties() { @@ -24,9 +24,16 @@ export class AppHaxLabel extends LitElement { static get styles() { return css` :host { - font-family: "Press Start 2P", sans-serif; + font-family: var(--ddd-font-primary, "Press Start 2P", sans-serif); text-align: flex-start; - width: 500px; + width: 100%; + max-width: 800px; + } + + .topBar { + display: flex; + align-items: baseline; + gap: var(--ddd-spacing-4, 8px); } .title { @@ -37,25 +44,38 @@ export class AppHaxLabel extends LitElement { var(--background-color) ); font-weight: normal; - font-size: 3.5vw; + font-size: var(--ddd-font-size-l, 1.8vw); display: inline-flex; - align-items: flex-start; + align-items: baseline; + min-width: fit-content; } .subtitle { color: var(--app-hax-accent-color, var(--accent-color)); font-weight: normal; - margin-top: 12px; - font-size: 20px; + font-size: var(--ddd-font-size-s, 16px); + font-family: var(--ddd-font-secondary, sans-serif); + margin: 0; + flex: 1; + min-width: fit-content; } + @media (max-width: 700px) { + .topBar { + flex-direction: column; + align-items: flex-start; + gap: var(--ddd-spacing-1, 4px); + } .subtitle { - font-size: 12px; + font-size: var(--ddd-font-size-xs, 12px); + } + .title { + font-size: var(--ddd-font-size-s, 2vw); } } .bracket { - font-size: 8vw; + font-size: var(--ddd-font-size-xl, 3vw); font-weight: normal; vertical-align: middle; -webkit-text-stroke: 0px; @@ -64,13 +84,14 @@ export class AppHaxLabel extends LitElement { var(--accent-color) ); } + @media (max-height: 500px) { .title { -webkit-text-stroke: unset; -webkit-text-fill-color: unset; } .bracket { - font-size: 4vw; + font-size: var(--ddd-font-size-l, 2vw); margin: 0; padding: 0; } @@ -82,8 +103,8 @@ export class AppHaxLabel extends LitElement { return html`
    - ${this.title} + <${this.title}>
    ${this.subtitle} diff --git a/elements/app-hax/lib/v2/app-hax-recipes.json b/elements/app-hax/lib/v2/app-hax-recipes.json index 8fdaddf835..345b7b957b 100644 --- a/elements/app-hax/lib/v2/app-hax-recipes.json +++ b/elements/app-hax/lib/v2/app-hax-recipes.json @@ -16,13 +16,12 @@ "icon": "hax:hax2022", "demo-url": "https://playground.hax.cloud/site.html?recipe=", "attributes": [ - { "icon": "icons:favorite", "tooltip": "Mark as Favorite" }, - { "icon": "icons:language", "tooltip": "Translatable"}, - { "icon": "icons:thumb-up", "tooltip": "Popular"}, - { "icon": "icons:accessibility", "tooltip": "Accessible"} + { "icon": "icons:language", "tooltip": "Translatable" }, + { "icon": "icons:thumb-up", "tooltip": "Popular" }, + { "icon": "icons:accessibility", "tooltip": "Accessible" } ] - }, - { + }, + { "uuid": "b12c82ef-1545-4697-9c76-90f1aa6f352c", "title": "Course", "category": ["Course"], @@ -37,12 +36,11 @@ "icon": "hax:hax2022", "demo-url": "https://playground.hax.cloud/site.html?recipe=", "attributes": [ - { "icon": "icons:favorite", "tooltip": "Mark as Favorite" }, - { "icon": "icons:language", "tooltip": "Translatable"}, - { "icon": "icons:thumb-up", "tooltip": "Popular"} + { "icon": "icons:language", "tooltip": "Translatable" }, + { "icon": "icons:thumb-up", "tooltip": "Popular" } ] - }, - { + }, + { "uuid": "1b4132dd-c557-4576-89c7-f89446feda4a", "title": "Blog", "category": ["Blog"], @@ -57,12 +55,11 @@ "icon": "hax:hax2022", "demo-url": "https://playground.hax.cloud/site.html?recipe=", "attributes": [ - { "icon": "icons:favorite", "tooltip": "Mark as Favorite" }, - { "icon": "icons:language", "tooltip": "Translatable"}, - { "icon": "icons:thumb-up", "tooltip": "Popular"} + { "icon": "icons:language", "tooltip": "Translatable" }, + { "icon": "icons:thumb-up", "tooltip": "Popular" } ] - }, - { + }, + { "uuid": "1b4132dd-c557-4576-89c7-f89446feda4a", "title": "Brochure", "category": ["Brochure"], @@ -77,9 +74,9 @@ "icon": "hax:hax2022", "demo-url": "https://playground.hax.cloud/site.html?recipe=", "attributes": [ - { "icon": "icons:favorite", "tooltip": "Mark as Favorite" }, { "icon": "icons:language", "tooltip": "Translatable" }, { "icon": "icons:thumb-up", "tooltip": "Popular" } ] - }] -} \ No newline at end of file + } + ] +} diff --git a/elements/app-hax/lib/v2/app-hax-scroll-button.js b/elements/app-hax/lib/v2/app-hax-scroll-button.js index 2b55c6e188..e30847045c 100644 --- a/elements/app-hax/lib/v2/app-hax-scroll-button.js +++ b/elements/app-hax/lib/v2/app-hax-scroll-button.js @@ -3,42 +3,40 @@ import { LitElement, html, css } from "lit"; import "@haxtheweb/simple-tooltip/simple-tooltip.js"; export class AppHaxScrollButton extends LitElement { - static get tag() { return "app-hax-scroll-button"; } constructor() { super(); - this.label = ''; - this.targetId = ''; + this.label = ""; + this.targetId = ""; this.isDarkMode = document.body.classList.contains("dark-mode"); } static get properties() { return { - label: { type: String }, - targetId: { type: String }, - isDarkMode: {type: Boolean, reflect: true}, + label: { type: String }, + targetId: { type: String }, + isDarkMode: { type: Boolean, reflect: true }, }; } scrollToTarget() { if (this.targetId) { let targetElement = null; - let appHax = this.closest('app-hax') || document.querySelector('app-hax'); - + let appHax = this.closest("app-hax") || document.querySelector("app-hax"); + if (appHax) { - - let useCaseFilter = appHax.shadowRoot - ? appHax.shadowRoot.querySelector('app-hax-use-case-filter') - : appHax.querySelector('app-hax-use-case-filter'); + let useCaseFilter = appHax.shadowRoot + ? appHax.shadowRoot.querySelector("app-hax-use-case-filter") + : appHax.querySelector("app-hax-use-case-filter"); if (useCaseFilter) { - targetElement = useCaseFilter.shadowRoot - ? useCaseFilter.shadowRoot.getElementById(this.targetId) - : useCaseFilter.querySelector(`#${this.targetId}`); + targetElement = useCaseFilter.shadowRoot + ? useCaseFilter.shadowRoot.getElementById(this.targetId) + : useCaseFilter.querySelector(`#${this.targetId}`); } - } + } if (!targetElement) { targetElement = document.getElementById(this.targetId); } @@ -46,7 +44,9 @@ export class AppHaxScrollButton extends LitElement { console.log(`Scrolling to:`, targetElement); targetElement.scrollIntoView({ behavior: "smooth", block: "start" }); } else { - console.warn(`Element with id '${this.targetId}' not found inside app-hax-use-case-filter.`); + console.warn( + `Element with id '${this.targetId}' not found inside app-hax-use-case-filter.`, + ); } } } @@ -55,7 +55,10 @@ export class AppHaxScrollButton extends LitElement { this._darkModeObserver = new MutationObserver(() => { this.isDarkMode = document.body.classList.contains("dark-mode"); }); - this._darkModeObserver.observe(document.body, { attributes: true, attributeFilter: ["class"] }); + this._darkModeObserver.observe(document.body, { + attributes: true, + attributeFilter: ["class"], + }); } disconnectedCallback() { @@ -65,7 +68,6 @@ export class AppHaxScrollButton extends LitElement { } } - static get styles() { return [ css` @@ -96,11 +98,10 @@ export class AppHaxScrollButton extends LitElement { render() { return html` -
    -
    ${this.label}
    -
    +
    +
    ${this.label}
    +
    `; } - } customElements.define(AppHaxScrollButton.tag, AppHaxScrollButton); diff --git a/elements/app-hax/lib/v2/app-hax-search-bar.js b/elements/app-hax/lib/v2/app-hax-search-bar.js index b7a9ec7cf4..143d1f91ef 100644 --- a/elements/app-hax/lib/v2/app-hax-search-bar.js +++ b/elements/app-hax/lib/v2/app-hax-search-bar.js @@ -140,4 +140,4 @@ export class AppHaxSearchBar extends LitElement { } } } -customElements.define(AppHaxSearchBar.tag, AppHaxSearchBar); \ No newline at end of file +customElements.define(AppHaxSearchBar.tag, AppHaxSearchBar); diff --git a/elements/app-hax/lib/v2/app-hax-search-results.js b/elements/app-hax/lib/v2/app-hax-search-results.js index 64b934f28f..e815c71a5d 100644 --- a/elements/app-hax/lib/v2/app-hax-search-results.js +++ b/elements/app-hax/lib/v2/app-hax-search-results.js @@ -6,6 +6,7 @@ import { varGet } from "@haxtheweb/utils/utils.js"; import { store } from "./AppHaxStore.js"; import "./app-hax-site-bar.js"; import "./app-hax-site-details.js"; +import "@haxtheweb/simple-tooltip/simple-tooltip.js"; export class AppHaxSearchResults extends SimpleColors { // a convention I enjoy so you can change the tag name in 1 place @@ -19,6 +20,12 @@ export class AppHaxSearchResults extends SimpleColors { this.displayItems = []; this.searchTerm = ""; this.dark = false; + this.isPointerDown = false; + this.startX = 0; + this.scrollLeftVal = 0; + this.isDragging = false; + this.currentIndex = 1; + this.totalItems = 0; autorun(() => { this.searchTerm = toJS(store.searchTerm); }); @@ -27,8 +34,8 @@ export class AppHaxSearchResults extends SimpleColors { }); autorun(() => { const manifest = toJS(store.manifest); - if (manifest && manifest.data.items) { - this.searchItems = manifest.data.items; + if (manifest && manifest.items) { + this.searchItems = manifest.items; this.displayItems = [...this.searchItems]; } }); @@ -43,6 +50,12 @@ export class AppHaxSearchResults extends SimpleColors { searchItems: { type: Array }, displayItems: { type: Array }, siteUrl: { type: String, attribute: "site-url" }, + isPointerDown: { type: Boolean }, + startX: { type: Number }, + scrollLeftVal: { type: Number }, + isDragging: { type: Boolean }, + currentIndex: { type: Number }, + totalItems: { type: Number }, }; } @@ -68,159 +81,489 @@ export class AppHaxSearchResults extends SimpleColors { } }); } - static get styles() { return [ super.styles, css` - + :host { + display: block; + width: 100%; + min-width: calc( + 3 * 264px + 2 * var(--ddd-spacing-6, 24px) + 2 * + var(--ddd-spacing-12, 56px) + ); + } + .carousel-container { display: flex; align-items: center; + justify-content: flex-start; + gap: var(--ddd-spacing-2, 8px); + width: 100%; + max-height: 280px; + position: relative; + background: var(--ddd-theme-default-white, white); + border-radius: var(--ddd-radius-md, 8px); + border: var(--ddd-border-xs, 1px solid) + var(--ddd-theme-default-limestoneLight, #e4e5e7); + box-shadow: var(--ddd-boxShadow-sm); + padding: var(--ddd-spacing-2, 8px); + transition: box-shadow 0.2s ease; + } + :host([dark]) .carousel-container, + body.dark-mode .carousel-container { + background: var(--ddd-theme-default-coalyGray, #222); + border-color: var(--ddd-theme-default-slateGray, #666); + color: var(--ddd-theme-default-white, white); + } + .carousel-container:hover { + box-shadow: var(--ddd-boxShadow-md); + } + .pager-container { + display: block; justify-content: center; - gap: 10px; - overflow: hidden; - margin: 0px; - max-height: 260px; - justify-self: flex-start; - align-self: flex-start; + align-items: center; + gap: var(--ddd-spacing-2, 8px); + margin-top: var(--ddd-spacing-2, 8px); + padding: var(--ddd-spacing-1, 4px); + width: 100%; + scrollbar-width: none; + -ms-overflow-style: none; + } + + .pager-container::-webkit-scrollbar { + display: none; + } + .pager-dot { + width: var(--ddd-spacing-3, 12px); + height: var(--ddd-spacing-3, 12px); + border-radius: var(--ddd-radius-circle, 50%); + background: var(--ddd-theme-default-limestoneGray, #a2aaad); + border: var(--ddd-border-xs, 1px solid) transparent; + cursor: pointer; + transition: all 0.2s ease; + outline: none; + } + .pager-dot:hover, + .pager-dot:focus { + transform: scale(1.2); + outline: var(--ddd-border-xs, 1px solid) + var(--ddd-theme-default-keystoneYellow, #ffd100); + } + .pager-dot.active { + background: var(--ddd-theme-default-nittanyNavy, #001e44); + border-color: var(--ddd-theme-default-keystoneYellow, #ffd100); + transform: scale(1.1); + } + :host([dark]) .pager-dot, + body.dark-mode .pager-dot { + background: var(--ddd-theme-default-slateGray, #666); + } + :host([dark]) .pager-dot.active, + body.dark-mode .pager-dot.active { + background: var(--ddd-theme-default-keystoneYellow, #ffd100); + border-color: var(--ddd-theme-default-white, white); } .scroll-left, .scroll-right { - background: var(--app-hax-accent-color, black); - color: white; - border: none; - padding: 16px; + background: var(--ddd-theme-default-nittanyNavy, #001e44); + color: var(--ddd-theme-default-white, white); + border: var(--ddd-border-sm, 2px solid) + var(--ddd-theme-default-keystoneYellow, #ffd100); + border-radius: var(--ddd-radius-sm, 4px); + padding: var(--ddd-spacing-4, 16px); cursor: pointer; height: 240px; - opacity: 50%; - color: var(--simple-colors-default-theme-accent-1, var(--simple-colors-default-theme-accent-12)); + min-width: var(--ddd-spacing-12, 56px); + display: flex; + align-items: center; + justify-content: center; + font-size: var(--ddd-font-size-l, 20px); + transition: all 0.2s ease; + flex-shrink: 0; + z-index: 10; + position: relative; } - + .scroll-right { + margin-right: 56px; + } + + :host([dark]) .scroll-left, + :host([dark]) .scroll-right, + body.dark-mode .scroll-left, + body.dark-mode .scroll-right { + background: var(--ddd-theme-default-keystoneYellow, #ffd100); + color: var(--ddd-theme-default-nittanyNavy, #001e44); + border-color: var(--ddd-theme-default-white, white); + } + + .scroll-left:hover, + .scroll-right:hover { + background: var(--ddd-theme-default-keystoneYellow, #ffd100); + color: var(--ddd-theme-default-nittanyNavy, #001e44); + transform: translateY(-2px); + box-shadow: var(--ddd-boxShadow-md); + } + + :host([dark]) .scroll-left:hover, + :host([dark]) .scroll-right:hover, + body.dark-mode .scroll-left:hover, + body.dark-mode .scroll-right:hover { + background: var(--ddd-theme-default-nittanyNavy, #001e44); + color: var(--ddd-theme-default-white, white); + } + #results { display: flex; flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden; scroll-snap-type: x mandatory; - gap: 20px; - white-space: nowrap; - scrollbar-width: none; - -ms-overflow-style: none; - padding: 4px; - padding-left: 8px; - padding-right: 8px; + gap: var(--ddd-spacing-6, 24px); + padding: var(--ddd-spacing-1, 4px) var(--ddd-spacing-2, 8px); + flex: 1; + min-width: 0; + cursor: grab; + user-select: none; + /* Keep scrollbar visible for multiple interaction methods */ + scrollbar-width: thin; + scrollbar-color: var(--ddd-theme-default-slateGray, #666) + var(--ddd-theme-default-limestoneLight, #e4e5e7); + } + + :host([dark]) #results, + body.dark-mode #results { + scrollbar-color: var(--ddd-theme-default-limestoneGray, #a2aaad) + var(--ddd-theme-default-coalyGray, #444); + } + + #results.dragging { + cursor: grabbing; + scroll-behavior: auto; } #results::-webkit-scrollbar { - display: none; + height: 8px; + } + + #results::-webkit-scrollbar-track { + background: var(--ddd-theme-default-limestoneLight, #e4e5e7); + border-radius: var(--ddd-radius-xs, 2px); + } + + #results::-webkit-scrollbar-thumb { + background: var(--ddd-theme-default-slateGray, #666); + border-radius: var(--ddd-radius-xs, 2px); + transition: background 0.2s ease; + } + + #results::-webkit-scrollbar-thumb:hover { + background: var(--ddd-theme-default-nittanyNavy, #001e44); + } + + :host([dark]) #results::-webkit-scrollbar-track, + body.dark-mode #results::-webkit-scrollbar-track { + background: var(--ddd-theme-default-coalyGray, #444); + } + + :host([dark]) #results::-webkit-scrollbar-thumb, + body.dark-mode #results::-webkit-scrollbar-thumb { + background: var(--ddd-theme-default-limestoneGray, #a2aaad); + } + + :host([dark]) #results::-webkit-scrollbar-thumb:hover, + body.dark-mode #results::-webkit-scrollbar-thumb:hover { + background: var(--ddd-theme-default-keystoneYellow, #ffd100); } li { flex: 0 0 auto; scroll-snap-align: center; - width: 220px; + width: 264px; + min-width: 264px; height: 260px; display: flex; flex-direction: column; align-items: center; justify-content: center; } + + /* Ensure minimum 3 items are always displayed with empty space if needed */ + #results::after { + content: ""; + flex: 1 0 auto; + min-width: 264px; + height: 260px; + } app-hax-site-bar { - margin: 0 12px; + margin: 0 var(--ddd-spacing-3, 12px); + width: 100%; } .description { max-height: 64px; overflow: hidden; max-width: 80%; text-overflow: ellipsis; - word-break: break-all; + word-break: break-word; + font-family: var(--ddd-font-primary, sans-serif); + font-size: var(--ddd-font-size-xs, 14px); + line-height: var(--ddd-lh-150, 1.5); + } + + @media (max-width: 1200px) { + :host { + min-width: calc( + 2 * 264px + var(--ddd-spacing-6, 24px) + 2 * + var(--ddd-spacing-12, 56px) + ); + } } @media (max-width: 800px) { + :host { + min-width: calc(264px + 2 * var(--ddd-spacing-12, 56px)); + } + app-hax-site-bar { --main-banner-width: 60vw; } + .description { max-height: 24px; - font-size: 8px; - font-family: sans-serif; + font-size: var(--ddd-font-size-3xs, 8px); + font-family: var(--ddd-font-primary, sans-serif); + } + + .scroll-left, + .scroll-right { + min-width: var(--ddd-spacing-10, 40px); + padding: var(--ddd-spacing-2, 8px); + font-size: var(--ddd-font-size-s, 16px); } } @media (max-width: 640px) { app-hax-site-bar a { - font-size: 14px; + font-size: var(--ddd-font-size-xs, 14px); } app-hax-site-bar { --main-banner-width: 70vw; } + + li { + width: 240px; + min-width: 240px; + } + + #results::after { + min-width: 240px; + } } span[slot="band"] { - height: 48px; + height: var(--ddd-spacing-12, 48px); overflow: hidden; text-overflow: ellipsis; - margin-bottom: 8px; + margin-bottom: var(--ddd-spacing-2, 8px); } - :host([dark]) #noResult { - color: var(--ddd-theme-default-coalyGray); + :host([dark]) #noResult, + body.dark-mode #noResult { + color: var(--ddd-theme-default-limestoneGray, #f5f5f5); + } + + #noResult { + font-family: var(--ddd-font-primary, sans-serif); + font-size: var(--ddd-font-size-s, 16px); + color: var(--ddd-theme-default-coalyGray, #444); + text-align: center; + padding: var(--ddd-spacing-6, 24px); + margin: var(--ddd-spacing-4, 16px); } `, ]; } render() { + // Update total items count + this.totalItems = this.displayItems.length; + return html` - `; } scrollLeft() { - this.shadowRoot.querySelector("#results").scrollBy({ left: -800, behavior: "smooth" }); + this.shadowRoot + .querySelector("#results") + .scrollBy({ left: -800, behavior: "smooth" }); } - + scrollRight() { - this.shadowRoot.querySelector("#results").scrollBy({ left: 800, behavior: "smooth" }); + this.shadowRoot + .querySelector("#results") + .scrollBy({ left: 800, behavior: "smooth" }); + } + + handlePointerStart(e) { + const resultsEl = this.shadowRoot.querySelector("#results"); + this.isPointerDown = true; + this.isDragging = false; + this.startX = + (e.type === "mousedown" ? e.clientX : e.touches[0].clientX) - + resultsEl.offsetLeft; + this.scrollLeftVal = resultsEl.scrollLeft; + e.preventDefault(); + } + + handlePointerMove(e) { + if (!this.isPointerDown) return; + + const resultsEl = this.shadowRoot.querySelector("#results"); + const x = + (e.type === "mousemove" ? e.clientX : e.touches[0].clientX) - + resultsEl.offsetLeft; + const walk = (x - this.startX) * 2; // Multiply for faster scrolling + + // Only start dragging if we've moved a significant distance + if (Math.abs(walk) > 5) { + this.isDragging = true; + // Disable smooth scrolling during drag for immediate feedback + resultsEl.style.scrollBehavior = "auto"; + } + + if (this.isDragging) { + resultsEl.scrollLeft = this.scrollLeftVal - walk; + e.preventDefault(); + } + } + + handlePointerEnd(e) { + this.isPointerDown = false; + + // Restore smooth scrolling behavior + const resultsEl = this.shadowRoot.querySelector("#results"); + if (resultsEl) { + resultsEl.style.scrollBehavior = "smooth"; + } + + // Use timeout to allow for click events to fire before resetting drag state + setTimeout(() => { + this.isDragging = false; + }, 100); + } + + handleScroll(e) { + if (this.totalItems <= 1) return; + + const resultsEl = e.target; + const scrollLeft = resultsEl.scrollLeft; + const itemWidth = 264 + 24; // item width + gap + + // Calculate current index based on scroll position + this.currentIndex = Math.min( + Math.max(1, Math.round(scrollLeft / itemWidth) + 1), + this.totalItems, + ); + } + + goToPage(pageNumber) { + const resultsEl = this.shadowRoot.querySelector("#results"); + const itemWidth = 264 + 24; // item width + gap + const targetScrollLeft = (pageNumber - 1) * itemWidth; + + resultsEl.scrollTo({ + left: targetScrollLeft, + behavior: "smooth", + }); + + this.currentIndex = pageNumber; } getItemDetails(item) { diff --git a/elements/app-hax/lib/v2/app-hax-simple-hat-progress.js b/elements/app-hax/lib/v2/app-hax-simple-hat-progress.js new file mode 100644 index 0000000000..3f5c571254 --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-simple-hat-progress.js @@ -0,0 +1,124 @@ +import { LitElement, html, css } from "lit"; +import { DDDSuper } from "@haxtheweb/d-d-d/d-d-d.js"; + +export class AppHaxSimpleHatProgress extends DDDSuper(LitElement) { + static get tag() { + return "app-hax-simple-hat-progress"; + } + + constructor() { + super(); + this.progress = 0; + this.max = 100; + } + + static get properties() { + return { + progress: { type: Number }, + max: { type: Number }, + }; + } + + static get styles() { + return [ + super.styles, + css` + :host { + display: block; + width: 160px; + height: 160px; + position: relative; + } + + .hat-container { + position: relative; + width: 100%; + height: 100%; + } + + .hat-image { + width: 100%; + height: 100%; + pointer-events: none; + z-index: 2; + position: relative; + } + + .progress-bar { + position: absolute; + bottom: 24px; + left: 8px; + right: 8px; + height: 12px; + background: var(--ddd-theme-default-limestoneGray, #f5f5f5); + border-radius: var(--ddd-radius-sm, 4px); + overflow: hidden; + z-index: 1; + } + + .progress-fill { + height: 100%; + background: linear-gradient( + 90deg, + var(--ddd-theme-default-original87Pink, #e4007c) 0%, + var(--ddd-theme-default-keystoneYellow, #ffd100) 50%, + var(--ddd-theme-default-futureLime, #99cc33) 100% + ); + border-radius: var(--ddd-radius-sm, 4px); + transition: width 0.5s ease; + width: 0%; + } + + .progress-text { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + color: var(--ddd-theme-default-white, white); + font-family: var(--ddd-font-primary, sans-serif); + font-size: var(--ddd-font-size-s, 16px); + font-weight: var(--ddd-font-weight-bold, 700); + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5); + z-index: 3; + } + `, + ]; + } + + updated(changedProperties) { + if (changedProperties.has("progress")) { + const progressFill = this.shadowRoot.querySelector(".progress-fill"); + if (progressFill) { + const percentage = Math.min( + 100, + Math.max(0, (this.progress / this.max) * 100), + ); + progressFill.style.width = `${percentage}%`; + } + } + } + + render() { + const percentage = Math.min( + 100, + Math.max(0, (this.progress / this.max) * 100), + ); + + return html` +
    + Progress Hat +
    +
    +
    +
    ${Math.round(percentage)}%
    +
    + `; + } +} + +customElements.define(AppHaxSimpleHatProgress.tag, AppHaxSimpleHatProgress); diff --git a/elements/app-hax/lib/v2/app-hax-site-bar.js b/elements/app-hax/lib/v2/app-hax-site-bar.js index 0ec82d2add..98654b41b3 100644 --- a/elements/app-hax/lib/v2/app-hax-site-bar.js +++ b/elements/app-hax/lib/v2/app-hax-site-bar.js @@ -5,6 +5,9 @@ import "@haxtheweb/simple-icon/lib/simple-icons.js"; import "@haxtheweb/simple-icon/lib/simple-icon-button-lite"; import { SimpleColors } from "@haxtheweb/simple-colors/simple-colors.js"; import "@haxtheweb/simple-tooltip/simple-tooltip.js"; +import { toJS } from "mobx"; +import { store } from "./AppHaxStore.js"; +import "./app-hax-user-access-modal.js"; const DropDownBorder = new URL( "../assets/images/DropDownBorder.svg", @@ -25,7 +28,7 @@ export class AppHaxSiteBars extends SimpleColors { this.inprogress = false; this.textInfo = {}; this.siteId = ""; - this.description = ''; + this.description = ""; } // properties that you wish to use as data in HTML, CSS, and the updated life-cycle @@ -37,31 +40,198 @@ export class AppHaxSiteBars extends SimpleColors { textInfo: { type: Object }, siteId: { type: String, reflect: true, attribute: "site-id" }, title: { type: String }, - description: { type: String }, + description: { type: String }, + siteUrl: { type: String, attribute: "site-url" }, }; } // updated fires every time a property defined above changes // this allows you to react to variables changing and use javascript to perform logic - updated(changedProperties) { - } + updated(changedProperties) {} toggleOptionsMenu() { this.showOptions = !this.showOptions; } + + handleKeydown(e, callback) { + if (e.key === "Enter" || e.key === " ") { + e.preventDefault(); + callback.call(this); + } + } copySite() { - console.log("Copy clicked"); - // implement logic + this.showOptions = false; + this.siteOperation("copySite", "Copy", "icons:content-copy"); } - + downloadSite() { - console.log("Download clicked"); - // implement logic + this.showOptions = false; + this.siteOperation("downloadSite", "Download", "file-download"); } - + archiveSite() { - console.log("Archive clicked"); - // implement logic + this.showOptions = false; + this.siteOperation("archiveSite", "Archive", "icons:archive"); + } + + openUserAccess() { + console.log("User Access clicked"); + // Close the options menu first + this.showOptions = false; + + // Create and show the user access modal + const modal = document.createElement("app-hax-user-access-modal"); + + // Set the site title for context + if (this.title) { + modal.siteTitle = this.title; + } + + // Show the modal using the simple-modal system + const evt = new CustomEvent("simple-modal-show", { + bubbles: true, + cancelable: true, + detail: { + title: "User Access", + elements: { content: modal }, + invokedBy: this, + styles: { + "--simple-modal-width": "500px", + "--simple-modal-height": "auto", + "--simple-modal-max-height": "80vh", + }, + }, + }); + + this.dispatchEvent(evt); + } + + // Site operation handler similar to the site details component + siteOperation(op, opName, icon) { + if (store.appEl && store.appEl.playSound) { + store.appEl.playSound("click"); + } + + store.activeSiteOp = op; + store.activeSiteId = this.siteId; + + import("@haxtheweb/simple-modal/simple-modal.js").then(() => { + setTimeout(() => { + // Find the site data from the store + const site = toJS( + store.manifest.items.filter((item) => item.id === this.siteId).pop(), + ); + + if (!site) { + console.error("Site not found for ID:", this.siteId); + return; + } + + const div = globalThis.document.createElement("div"); + div.appendChild( + globalThis.document.createTextNode( + `Are you sure you want to ${op.replace("Site", "")} ${ + site.metadata.site.name + }?`, + ), + ); + + const bcontainer = globalThis.document.createElement("div"); + const b = globalThis.document.createElement("button"); + b.innerText = "Confirm"; + b.classList.add("hax-modal-btn"); + b.addEventListener("click", this.confirmOperation.bind(this)); + bcontainer.appendChild(b); + + const b2 = globalThis.document.createElement("button"); + b2.innerText = "Cancel"; + b2.classList.add("hax-modal-btn"); + b2.classList.add("cancel"); + b2.addEventListener("click", this.cancelOperation.bind(this)); + bcontainer.appendChild(b2); + + this.dispatchEvent( + new CustomEvent("simple-modal-show", { + bubbles: true, + cancelable: true, + composed: true, + detail: { + title: `${opName} ${site.metadata.site.name}?`, + elements: { content: div, buttons: bcontainer }, + invokedBy: this, + styles: { + "--simple-modal-titlebar-background": "orange", + "--simple-modal-titlebar-color": "black", + "--simple-modal-width": "30vw", + "--simple-modal-min-width": "300px", + "--simple-modal-z-index": "100000000", + "--simple-modal-height": "20vh", + "--simple-modal-min-height": "300px", + "--simple-modal-titlebar-height": "80px", + }, + }, + }), + ); + }, 0); + }); + } + + cancelOperation() { + store.activeSiteOp = ""; + store.activeSiteId = null; + globalThis.dispatchEvent(new CustomEvent("simple-modal-hide")); + if (store.appEl && store.appEl.playSound) { + store.appEl.playSound("error"); + } + } + + async confirmOperation() { + const op = toJS(store.activeSiteOp); + const site = toJS(store.activeSite); + + if (!site) { + console.error("No active site found for operation:", op); + return; + } + + // Make the API call to perform the operation + await store.AppHaxAPI.makeCall( + op, + { + site: { + name: site.metadata.site.name, + id: site.id, + }, + }, + true, + () => { + const activeOp = toJS(store.activeSiteOp); + // Download is special - it opens a download link + if (activeOp === "downloadSite") { + globalThis.open( + store.AppHaxAPI.lastResponse.downloadSite.data.link, + "_blank", + ); + } else { + // For copy and archive, refresh the site listing + store.refreshSiteListing(); + } + }, + ); + + globalThis.dispatchEvent(new CustomEvent("simple-modal-hide")); + + if (store.appEl && store.appEl.playSound) { + store.appEl.playSound("success"); + } + + store.toast( + `${site.metadata.site.name} ${op.replace("Site", "")} successful!`, + 3000, + { + hat: "random", + }, + ); } // CSS - specific to Lit @@ -72,7 +242,7 @@ export class AppHaxSiteBars extends SimpleColors { :host { text-align: left; max-width: 240px; - + font-family: var(--ddd-font-primary); color: var(--ddd-theme-default-nittanyNavy); background-color: white; @@ -108,20 +278,104 @@ export class AppHaxSiteBars extends SimpleColors { .options-menu { position: absolute; - top: -110px; + top: -125px; right: 0; - background: var(--haxcms-color-ui-white, #fff); - border: 1px solid var(--haxcms-color-ui-1, #ccc); - box-shadow: 0 4px 6px rgba(0,0,0,0.1); - border-radius: 8px; - padding: 8px 8px 6px 10px; + background: var(--ddd-theme-default-white, white); + border: var(--ddd-border-xs, 1px solid) + var(--ddd-theme-default-slateGray, #666); + box-shadow: var(--ddd-boxShadow-lg); + border-radius: var(--ddd-radius-md, 8px); + padding: var(--ddd-spacing-2, 8px); display: flex; flex-direction: column; + gap: var(--ddd-spacing-1, 4px); z-index: 1000; - overflow:visible; + overflow: visible; + min-width: 140px; + } + :host([dark]) .options-menu, + body.dark-mode .options-menu { + background: var(--ddd-theme-default-coalyGray, #333); + color: var(--ddd-theme-default-white, white); + border-color: var(--ddd-theme-default-slateGray, #666); } - .options-menu simple-icon-button-lite { - margin: 4px 0; + .close-menu-btn { + position: absolute; + top: var(--ddd-spacing-1, 4px); + right: var(--ddd-spacing-1, 4px); + background: transparent; + border: none; + color: var(--ddd-theme-default-slateGray, #666); + cursor: pointer; + font-size: var(--ddd-font-size-s, 16px); + font-weight: var(--ddd-font-weight-bold, 700); + padding: var(--ddd-spacing-1, 4px); + border-radius: var(--ddd-radius-xs, 2px); + line-height: 1; + min-height: auto; + box-shadow: none; + width: var(--ddd-spacing-5, 20px); + height: var(--ddd-spacing-5, 20px); + display: flex; + align-items: center; + justify-content: center; + transition: all 0.2s ease; + } + :host([dark]) .close-menu-btn, + body.dark-mode .close-menu-btn { + color: var(--ddd-theme-default-white, white); + } + .close-menu-btn:hover, + .close-menu-btn:focus { + background: var(--ddd-theme-default-slateGray, #666); + color: var(--ddd-theme-default-white, white); + transform: none; + box-shadow: none; + outline: var(--ddd-border-xs, 1px solid) + var(--ddd-theme-default-keystoneYellow, #ffd100); + } + :host([dark]) .close-menu-btn:hover, + :host([dark]) .close-menu-btn:focus, + body.dark-mode .close-menu-btn:hover, + body.dark-mode .close-menu-btn:focus { + background: var(--ddd-theme-default-keystoneYellow, #ffd100); + color: var(--ddd-theme-default-nittanyNavy, #001e44); + outline-color: var(--ddd-theme-default-white, white); + } + .menu-item { + display: flex; + align-items: center; + padding: var(--ddd-spacing-1, 4px) var(--ddd-spacing-2, 8px); + border-radius: var(--ddd-radius-xs, 2px); + cursor: pointer; + font-size: var(--ddd-font-size-3xs, 11px); + font-family: var(--ddd-font-primary, sans-serif); + transition: all 0.2s ease; + color: var(--ddd-theme-default-nittanyNavy, #001e44); + text-decoration: none; + min-height: var(--ddd-spacing-5, 20px); + } + :host([dark]) .menu-item, + body.dark-mode .menu-item { + color: var(--ddd-theme-default-white, white); + } + .menu-item:hover, + .menu-item:focus { + background: var(--ddd-theme-default-limestoneGray, #f5f5f5); + color: var(--ddd-theme-default-nittanyNavy, #001e44); + outline: var(--ddd-border-xs, 1px solid) + var(--ddd-theme-default-keystoneYellow, #ffd100); + } + :host([dark]) .menu-item:hover, + :host([dark]) .menu-item:focus, + body.dark-mode .menu-item:hover, + body.dark-mode .menu-item:focus { + background: var(--ddd-theme-default-slateGray, #555); + color: var(--ddd-theme-default-white, white); + } + .menu-item simple-icon-button-lite { + margin-right: var(--ddd-spacing-1, 4px); + flex-shrink: 0; } .titleBar { @@ -144,29 +398,37 @@ export class AppHaxSiteBars extends SimpleColors { } button { display: flex; - background-color: #005fa9; - color: white; - border: 0px; - border-radius: 4px; - font-family: var(--ddd-font-primary); - font-size: 12px; - font-weight: 20px; - padding: 12px 16px 12px 24px; - height: 16px; + background: var(--ddd-theme-default-nittanyNavy, #001e44); + color: var(--ddd-theme-default-white, white); + border: var(--ddd-border-sm, 2px solid) transparent; + border-radius: var(--ddd-radius-md, 8px); + font-family: var(--ddd-font-primary, sans-serif); + font-size: var(--ddd-font-size-xs, 14px); + font-weight: var(--ddd-font-weight-medium, 500); + padding: var(--ddd-spacing-3, 12px) var(--ddd-spacing-4, 16px); + min-height: var(--ddd-spacing-9, 36px); align-items: center; justify-content: center; + cursor: pointer; + transition: all 0.2s ease; + box-shadow: var(--ddd-boxShadow-sm); } button:hover { - background-color: var(--ddd-theme-default-nittanyNavy); + background: var(--ddd-theme-default-keystoneYellow, #ffd100); + color: var(--ddd-theme-default-nittanyNavy, #001e44); + transform: translateY(-1px); + box-shadow: var(--ddd-boxShadow-md); } .cardBottom { - display: flex; - justify-content: space-between; - align-items: center; + display: flex; + justify-content: space-between; + align-items: center; } - .cardBottom button{ - flex: 1; - margin-top: 8px; + .cardBottom button { + flex: 1; + margin-top: var(--ddd-spacing-2, 8px); + margin-left: var(--ddd-spacing-2, 8px); + margin-right: var(--ddd-spacing-2, 8px); } ::slotted(a[slot="heading"]), ::slotted(span[slot="subHeading"]), @@ -186,14 +448,20 @@ export class AppHaxSiteBars extends SimpleColors { return html`
    - +
    - + Options - - - Copy - - - - Download - - - - Archive - -
    - ` - : ''} +
    + + + + + +
    + ` + : ""}
    - + - -
    -
    -
    `; } diff --git a/elements/app-hax/lib/v2/app-hax-site-creation-modal.js b/elements/app-hax/lib/v2/app-hax-site-creation-modal.js new file mode 100644 index 0000000000..9d40b0c389 --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-site-creation-modal.js @@ -0,0 +1,852 @@ +import { LitElement, html, css } from "lit"; +import { DDDSuper } from "@haxtheweb/d-d-d/d-d-d.js"; +import "@haxtheweb/simple-icon/lib/simple-icon-lite.js"; +import "@haxtheweb/simple-icon/lib/simple-icons.js"; +import "@haxtheweb/promise-progress/promise-progress.js"; +import "./app-hax-simple-hat-progress.js"; +import { store } from "./AppHaxStore.js"; +import { toJS } from "mobx"; + +export class AppHaxSiteCreationModal extends DDDSuper(LitElement) { + static get tag() { + return "app-hax-site-creation-modal"; + } + + constructor() { + super(); + this.open = false; + this.title = ""; + this.description = ""; + this.source = ""; + this.template = ""; + this.siteName = ""; + this.currentStep = 1; // 1: naming, 2: creating, 3: success + this.isCreating = false; + this.creationProgress = 0; + this.errorMessage = ""; + this.showConfetti = false; + this.siteUrl = ""; + this.creationCancelled = false; + this.promises = []; + this.max = 100; + } + + static get properties() { + return { + open: { type: Boolean, reflect: true }, + title: { type: String }, + description: { type: String }, + source: { type: String }, + template: { type: String }, + siteName: { type: String }, + currentStep: { type: Number }, + isCreating: { type: Boolean }, + creationProgress: { type: Number }, + errorMessage: { type: String }, + showConfetti: { type: Boolean }, + siteUrl: { type: String }, + creationCancelled: { type: Boolean }, + promises: { type: Array }, + max: { type: Number }, + }; + } + + static get styles() { + return [ + super.styles, + css` + :host { + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + background: rgba(0, 0, 0, 0.6); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; + opacity: 0; + pointer-events: none; + transition: opacity 0.3s ease; + } + + :host([open]) { + opacity: 1; + pointer-events: all; + } + + .modal { + background: var(--ddd-theme-default-white, white); + border-radius: var(--ddd-radius-md, 8px); + box-shadow: var(--ddd-boxShadow-xl); + max-width: var(--ddd-spacing-32, 480px); + width: 90vw; + max-height: 80vh; + overflow: hidden; + position: relative; + transform: scale(0.9); + transition: transform 0.3s ease; + } + + :host([open]) .modal { + transform: scale(1); + } + + .modal-header { + padding: var(--ddd-spacing-4, 16px); + border-bottom: var(--ddd-border-xs, 1px solid) + var(--ddd-theme-default-limestoneGray, #f5f5f5); + display: flex; + align-items: center; + justify-content: space-between; + background: var(--ddd-theme-default-nittanyNavy, #001e44); + color: var(--ddd-theme-default-white, white); + } + + .modal-title { + font-size: var(--ddd-font-size-m, 18px); + font-weight: var(--ddd-font-weight-bold, 700); + margin: 0; + } + + .close-button { + background: transparent; + border: none; + color: var(--ddd-theme-default-white, white); + cursor: pointer; + padding: var(--ddd-spacing-2, 8px); + border-radius: var(--ddd-radius-sm, 4px); + transition: background-color 0.2s ease; + } + + .close-button:hover { + background: rgba(255, 255, 255, 0.1); + } + + .modal-content { + padding: var(--ddd-spacing-6, 24px); + min-height: var(--ddd-spacing-20, 200px); + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + } + + .step-indicator { + display: flex; + align-items: center; + justify-content: center; + gap: var(--ddd-spacing-2, 8px); + margin-bottom: var(--ddd-spacing-4, 16px); + } + + .step-dot { + width: var(--ddd-spacing-3, 12px); + height: var(--ddd-spacing-3, 12px); + border-radius: 50%; + background: var(--ddd-theme-default-limestoneGray, #f5f5f5); + transition: background-color 0.3s ease; + } + + .step-dot.active { + background: var(--ddd-theme-default-nittanyNavy, #001e44); + } + + .step-dot.completed { + background: var(--ddd-theme-default-futureLime, #99cc33); + } + + .template-info { + margin-bottom: var(--ddd-spacing-4, 16px); + padding: var(--ddd-spacing-3, 12px); + background: var(--ddd-theme-default-limestoneGray, #f5f5f5); + border-radius: var(--ddd-radius-sm, 4px); + width: 100%; + } + + .template-title { + font-size: var(--ddd-font-size-s, 16px); + font-weight: var(--ddd-font-weight-bold, 700); + color: var(--ddd-theme-default-nittanyNavy, #001e44); + margin: 0 0 var(--ddd-spacing-2, 8px) 0; + } + + .template-description { + font-size: var(--ddd-font-size-xs, 14px); + color: var(--ddd-theme-default-coalyGray, #444); + margin: 0; + } + + .form-group { + width: 100%; + margin-bottom: var(--ddd-spacing-4, 16px); + position: relative; + } + + .form-label { + display: block; + font-size: var(--ddd-font-size-xs, 14px); + font-weight: var(--ddd-font-weight-medium, 500); + color: var(--ddd-theme-default-nittanyNavy, #001e44); + margin-bottom: var(--ddd-spacing-2, 8px); + text-align: left; + } + + .form-input { + width: 100%; + padding: var(--ddd-spacing-3, 12px) var(--ddd-spacing-3, 12px) + var(--ddd-spacing-3, 12px) var(--ddd-spacing-8, 32px); + border: var(--ddd-border-xs, 1px solid) + var(--ddd-theme-default-slateGray, #666); + border-radius: var(--ddd-radius-sm, 4px); + font-size: var(--ddd-font-size-s, 16px); + font-family: var(--ddd-font-primary, sans-serif); + box-sizing: border-box; + transition: all 0.2s ease; + background: var(--ddd-theme-default-white, white); + color: var(--ddd-theme-default-coalyGray, #222); + min-height: var(--ddd-spacing-8, 32px); + } + + .form-icon { + position: absolute; + left: var(--ddd-spacing-2, 8px); + bottom: var(--ddd-spacing-2, 8px); + font-size: var(--ddd-font-size-xs, 14px); + color: var(--ddd-theme-default-nittanyNavy, #001e44); + pointer-events: none; + z-index: 1; + --simple-icon-width: var(--ddd-icon-3xs, 20px); + --simple-icon-height: var(--ddd-icon-3xs, 20px); + } + + .form-input:focus { + outline: none; + border: var(--ddd-border-md, 2px solid); + border-color: var(--ddd-theme-default-keystoneYellow, #ffd100); + background: var(--ddd-theme-default-white, white); + } + + .form-input:invalid { + border-color: var(--ddd-theme-default-original87Pink, #e4007c); + } + + .error-message { + color: var(--ddd-theme-default-original87Pink, #e4007c); + font-size: var(--ddd-font-size-xs, 12px); + margin-top: var(--ddd-spacing-2, 8px); + text-align: left; + } + + .progress-container { + width: 100%; + margin: var(--ddd-spacing-4, 16px) 0; + } + + .progress-text { + font-size: var(--ddd-font-size-s, 16px); + color: var(--ddd-theme-default-nittanyNavy, #001e44); + margin-bottom: var(--ddd-spacing-4, 16px); + } + + .hat-progress-container { + display: flex; + justify-content: center; + align-items: center; + margin: var(--ddd-spacing-4, 16px) 0; + padding: 0 var(--ddd-spacing-4, 16px); + min-height: 180px; + } + + app-hax-simple-hat-progress { + width: 160px; + height: 160px; + max-width: calc(100% - var(--ddd-spacing-8, 32px)); + } + + .progress-bar { + width: 100%; + height: var(--ddd-spacing-3, 12px); + background: var(--ddd-theme-default-limestoneGray, #f5f5f5); + border-radius: var(--ddd-radius-sm, 4px); + overflow: hidden; + margin-bottom: var(--ddd-spacing-2, 8px); + } + + .progress-fill { + height: 100%; + background: linear-gradient( + 90deg, + var(--ddd-theme-default-nittanyNavy, #001e44) 0%, + var(--ddd-theme-default-futureLime, #99cc33) 100% + ); + border-radius: var(--ddd-radius-sm, 4px); + transition: width 0.5s ease; + width: 0%; + } + + .progress-percentage { + font-size: var(--ddd-font-size-xs, 12px); + color: var(--ddd-theme-default-coalyGray, #444); + } + + promise-progress { + display: none; + } + + .success-content { + display: flex; + flex-direction: column; + align-items: center; + } + + .success-icon { + font-size: var(--ddd-font-size-4xl, 48px); + color: var(--ddd-theme-default-futureLime, #99cc33); + margin-bottom: var(--ddd-spacing-4, 16px); + } + + .success-title { + font-size: var(--ddd-font-size-l, 24px); + font-weight: var(--ddd-font-weight-bold, 700); + color: var(--ddd-theme-default-nittanyNavy, #001e44); + margin: 0 0 var(--ddd-spacing-2, 8px) 0; + } + + .success-subtitle { + font-size: var(--ddd-font-size-s, 16px); + color: var(--ddd-theme-default-coalyGray, #444); + margin: 0 0 var(--ddd-spacing-4, 16px) 0; + } + + .button-group { + display: flex; + gap: var(--ddd-spacing-3, 12px); + justify-content: center; + margin-top: var(--ddd-spacing-4, 16px); + width: 100%; + } + + .button { + padding: var(--ddd-spacing-3, 12px) var(--ddd-spacing-4, 16px); + border-radius: var(--ddd-radius-sm, 4px); + font-size: var(--ddd-font-size-xs, 14px); + font-weight: var(--ddd-font-weight-medium, 500); + font-family: var(--ddd-font-primary, sans-serif); + cursor: pointer; + transition: all 0.2s ease; + border: none; + display: flex; + align-items: center; + justify-content: center; + gap: var(--ddd-spacing-2, 8px); + } + + .button:disabled { + opacity: 0.5; + cursor: not-allowed; + } + + .button-primary { + background: var(--ddd-theme-default-nittanyNavy, #001e44); + color: var(--ddd-theme-default-white, white); + } + + .button-primary:hover:not(:disabled) { + background: var(--ddd-theme-default-keystoneYellow, #ffd100); + color: var(--ddd-theme-default-nittanyNavy, #001e44); + } + + .button-secondary { + background: transparent; + color: var(--ddd-theme-default-nittanyNavy, #001e44); + border: var(--ddd-border-sm, 2px solid) + var(--ddd-theme-default-nittanyNavy, #001e44); + } + + .button-secondary:hover:not(:disabled) { + background: var(--ddd-theme-default-nittanyNavy, #001e44); + color: var(--ddd-theme-default-white, white); + } + + .button-success { + background: var(--ddd-theme-default-futureLime, #99cc33); + color: var(--ddd-theme-default-white, white); + } + + .button-success:hover:not(:disabled) { + background: var(--ddd-theme-default-original87Pink, #e4007c); + } + + .confetti { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: none; + overflow: hidden; + } + + .confetti-piece { + position: absolute; + width: 10px; + height: 10px; + background: var(--ddd-theme-default-futureLime, #99cc33); + animation: confetti-fall 3s linear infinite; + } + + .confetti-piece:nth-child(2n) { + background: var(--ddd-theme-default-keystoneYellow, #ffd100); + animation-delay: -0.5s; + } + + .confetti-piece:nth-child(3n) { + background: var(--ddd-theme-default-original87Pink, #e4007c); + animation-delay: -1s; + } + + .confetti-piece:nth-child(4n) { + background: var(--ddd-theme-default-nittanyNavy, #001e44); + animation-delay: -1.5s; + } + + @keyframes confetti-fall { + 0% { + transform: translateY(-100vh) rotate(0deg); + opacity: 1; + } + 100% { + transform: translateY(100vh) rotate(360deg); + opacity: 0; + } + } + + @media (max-width: 600px) { + .modal { + width: 95vw; + margin: var(--ddd-spacing-2, 8px); + max-height: 90vh; + } + + .modal-content { + padding: var(--ddd-spacing-4, 16px); + } + + .button-group { + flex-direction: column; + gap: var(--ddd-spacing-2, 8px); + margin-top: var(--ddd-spacing-3, 12px); + } + + .button { + width: 100%; + min-height: var(--ddd-spacing-10, 40px); + font-size: var(--ddd-font-size-xs, 14px); + padding: var(--ddd-spacing-3, 12px); + } + + app-hax-simple-hat-progress { + width: 120px; + height: 120px; + } + + .hat-progress-container { + padding: 0 var(--ddd-spacing-2, 8px); + min-height: 140px; + } + + .modal-title { + font-size: var(--ddd-font-size-s, 16px); + } + + .form-input { + min-height: var(--ddd-spacing-10, 40px); + font-size: var(--ddd-font-size-s, 16px); + } + } + `, + ]; + } + + openModal() { + this.open = true; + this.currentStep = 1; + this.siteName = ""; + this.errorMessage = ""; + this.showConfetti = false; + this.isCreating = false; + this.creationProgress = 0; + this.creationCancelled = false; + this.siteUrl = ""; + // Focus the input after the modal opens + setTimeout(() => { + const input = this.shadowRoot.querySelector(".form-input"); + if (input) { + input.focus(); + } + }, 100); + } + + closeModal() { + // If creation is in progress, cancel it + if (this.isCreating) { + this.creationCancelled = true; + } + + const wasCancelled = this.currentStep === 1; // Only step 1 is considered a cancellation + + this.open = false; + this.currentStep = 1; + this.siteName = ""; + this.errorMessage = ""; + this.showConfetti = false; + this.isCreating = false; + this.creationProgress = 0; + this.creationCancelled = false; + this.siteUrl = ""; + + this.dispatchEvent( + new CustomEvent("modal-closed", { + bubbles: true, + composed: true, + detail: { cancelled: wasCancelled }, + }), + ); + } + + handleKeyDown(e) { + if (e.key === "Escape") { + this.closeModal(); + } else if (e.key === "Enter" && this.currentStep === 1) { + this.createSite(); + } + } + + validateSiteName() { + const name = this.siteName.trim(); + if (!name) { + this.errorMessage = "Site name is required"; + return false; + } + if (name.length < 3) { + this.errorMessage = "Site name must be at least 3 characters"; + return false; + } + if (name.length > 50) { + this.errorMessage = "Site name must be less than 50 characters"; + return false; + } + if (!/^[a-zA-Z0-9\s\-_]+$/.test(name)) { + this.errorMessage = + "Site name can only contain letters, numbers, spaces, hyphens, and underscores"; + return false; + } + this.errorMessage = ""; + return true; + } + + async createSite() { + if (!this.validateSiteName()) { + return; + } + + // Set up the site data in store for the API call + store.site.name = this.siteName; + store.site.structure = this.template || "website"; // Use template or default + store.site.type = "own"; + store.site.theme = "polaris-flex-theme"; // Default theme + + this.currentStep = 2; + this.isCreating = true; + this.creationProgress = 0; + this.creationCancelled = false; + + // Set up promises from store for real site creation + this.promises = toJS(store.newSitePromiseList); + + try { + // Start the promise progress system + await this.updateComplete; // Wait for render + const promiseProgress = + this.shadowRoot.querySelector("#promise-progress"); + if (promiseProgress) { + promiseProgress.process(); + } + } catch (error) { + if (!this.creationCancelled) { + this.errorMessage = "Failed to create site. Please try again."; + this.currentStep = 1; + this.isCreating = false; + console.error("Site creation error:", error); + } + } + } + + generateConfetti() { + const confettiContainer = this.shadowRoot.querySelector(".confetti"); + if (!confettiContainer) return; + + // Clear existing confetti + confettiContainer.innerHTML = ""; + + // Generate confetti pieces + for (let i = 0; i < 50; i++) { + const piece = document.createElement("div"); + piece.className = "confetti-piece"; + piece.style.left = Math.random() * 100 + "%"; + piece.style.animationDuration = Math.random() * 3 + 2 + "s"; + piece.style.animationDelay = Math.random() * 2 + "s"; + confettiContainer.appendChild(piece); + } + + // Remove confetti after animation + setTimeout(() => { + confettiContainer.innerHTML = ""; + this.showConfetti = false; + }, 5000); + } + + progressValueChanged(e) { + this.creationProgress = e.detail.value; + // Update the hat progress component + const hatProgress = this.shadowRoot.querySelector( + "app-hax-simple-hat-progress", + ); + if (hatProgress) { + hatProgress.progress = this.creationProgress; + hatProgress.requestUpdate(); + } + } + + progressMaxChanged(e) { + this.max = e.detail.value; + } + + promiseProgressFinished(e) { + if (e.detail.value) { + // Site creation completed successfully! + const createResponse = store.AppHaxAPI.lastResponse.createSite.data; + + // Set the real site URL from the API response + if (createResponse && createResponse.slug) { + this.siteUrl = createResponse.slug.replace("index.html", ""); + } else { + // Fallback URL if API doesn't return proper response + const siteSlug = this.siteName + .toLowerCase() + .replace(/[^a-z0-9]+/g, "-"); + this.siteUrl = `https://haxtheweb.org/sites/${siteSlug}`; + } + + // Success! + this.currentStep = 3; + this.isCreating = false; + this.showConfetti = true; + this.generateConfetti(); + + // Trigger confetti on main page + this.triggerMainPageConfetti(); + + // Play success sound if available + if (store.appEl && store.appEl.playSound) { + store.appEl.playSound("success"); + } + } + } + + triggerMainPageConfetti() { + // Find the main page confetti container and trigger confetti + const mainConfettiContainer = document.querySelector("#confetti"); + if (mainConfettiContainer) { + // Import and trigger confetti on main page + import("@haxtheweb/multiple-choice/lib/confetti-container.js").then( + () => { + setTimeout(() => { + mainConfettiContainer.setAttribute("popped", ""); + // Remove the attribute after animation to allow future confetti + setTimeout(() => { + mainConfettiContainer.removeAttribute("popped"); + }, 3000); + }, 0); + }, + ); + } + } + + goToSite() { + if (this.siteUrl) { + globalThis.open(this.siteUrl, "_blank"); + } + this.closeModal(); + } + + renderStepIndicator() { + return html` +
    + ${[1, 2, 3].map( + (step) => html` +
    + `, + )} +
    + `; + } + + renderNamingStep() { + return html` +
    +

    ${this.title}

    +

    ${this.description}

    +
    + +
    + + + + ${this.errorMessage + ? html`
    ${this.errorMessage}
    ` + : ""} +
    + +
    + + +
    + `; + } + + renderCreatingStep() { + return html` +
    +

    Creating your site...

    + +
    + +
    + + + +
    +
    +
    +
    + ${this.creationProgress}% complete +
    +
    + `; + } + + renderSuccessStep() { + return html` +
    + +

    Site Created Successfully!

    +

    + Your new site "${this.siteName}" is ready to use. +

    + +
    + + +
    +
    + `; + } + + render() { + return html` + + `; + } + + connectedCallback() { + super.connectedCallback(); + document.addEventListener("keydown", this.handleKeyDown.bind(this)); + } + + disconnectedCallback() { + super.disconnectedCallback(); + document.removeEventListener("keydown", this.handleKeyDown.bind(this)); + } +} + +customElements.define(AppHaxSiteCreationModal.tag, AppHaxSiteCreationModal); diff --git a/elements/app-hax/lib/v2/app-hax-site-details.js b/elements/app-hax/lib/v2/app-hax-site-details.js index a92503d41e..79d2ae6ad0 100644 --- a/elements/app-hax/lib/v2/app-hax-site-details.js +++ b/elements/app-hax/lib/v2/app-hax-site-details.js @@ -1,6 +1,8 @@ // dependencies / things imported import { html, css } from "lit"; import "@haxtheweb/simple-datetime/simple-datetime.js"; +import "@haxtheweb/simple-icon/lib/simple-icon-button-lite.js"; +import "@haxtheweb/simple-tooltip/simple-tooltip.js"; import { toJS } from "mobx"; import { store } from "./AppHaxStore.js"; import { SimpleColors } from "@haxtheweb/simple-colors/simple-colors.js"; @@ -105,7 +107,10 @@ export class AppHaxSiteDetails extends SimpleColors { simple-icon-button-lite:active, simple-icon-button-lite:hover, simple-icon-button-lite:focus { - background-color: var(--simple-colors-default-theme-light-blue-8, #cde8ff); + background-color: var( + --simple-colors-default-theme-light-blue-8, + #cde8ff + ); outline: 2px solid var(--simple-colors-default-theme-light-blue-1); outline-offset: 1px; } diff --git a/elements/app-hax/lib/v2/app-hax-site-login.js b/elements/app-hax/lib/v2/app-hax-site-login.js index 89738955f4..270eaf29de 100644 --- a/elements/app-hax/lib/v2/app-hax-site-login.js +++ b/elements/app-hax/lib/v2/app-hax-site-login.js @@ -1,10 +1,10 @@ -import { html, css } from "lit"; +import { LitElement, html, css } from "lit"; import "@haxtheweb/simple-icon/lib/simple-icons.js"; import "@haxtheweb/simple-icon/lib/simple-icon-lite.js"; -import { SimpleColors } from "@haxtheweb/simple-colors/simple-colors.js"; +import { DDDSuper } from "@haxtheweb/d-d-d/d-d-d.js"; import "@haxtheweb/rpg-character/rpg-character.js"; import { store } from "./AppHaxStore.js"; -export class AppHaxSiteLogin extends SimpleColors { +export class AppHaxSiteLogin extends DDDSuper(LitElement) { // a convention I enjoy so you can change the tag name in 1 place static get tag() { return "app-hax-site-login"; @@ -57,70 +57,158 @@ export class AppHaxSiteLogin extends SimpleColors { flex-direction: column; justify-content: center; align-items: center; + padding: var(--ddd-spacing-6, 24px); + text-align: center; + font-family: var(--ddd-font-primary, sans-serif); + background: var(--ddd-theme-default-white, white); + color: var(--ddd-theme-default-nittanyNavy, #001e44); + } + + rpg-character { + display: block; + margin: 0 0 var(--ddd-spacing-4, 16px) 0; + width: 120px; + height: 120px; + } + + #errorText { + color: var(--ddd-theme-default-original87Pink, #e4007c); + font-size: var(--ddd-font-size-xs, 14px); + margin: var(--ddd-spacing-2, 8px) 0; + min-height: var(--ddd-spacing-5, 20px); + font-weight: var(--ddd-font-weight-medium, 500); } + #inputcontainer { display: flex; flex-direction: column; justify-content: center; align-items: center; - } - a { - color: red; + width: 100%; + max-width: var(--ddd-spacing-30, 400px); + gap: var(--ddd-spacing-4, 16px); } - // This does not work - #errorText > p { - visibility: hidden; - background-color: lightblue; - color: red; - font-weight: bold; + .form-group { + width: 100%; + position: relative; } - rpg-character { - display: block; - margin: 0px; + + input { + width: 100%; + padding: var(--ddd-spacing-3, 12px); + border: var(--ddd-border-sm, 2px solid) + var(--ddd-theme-default-slateGray, #666); + border-radius: var(--ddd-radius-sm, 4px); + font-size: var(--ddd-font-size-s, 16px); + font-family: var(--ddd-font-primary, sans-serif); + box-sizing: border-box; + transition: border-color 0.2s ease; + background: var(--ddd-theme-default-white, white); } - .external { - text-align: center; + + input:focus { + outline: none; + border-color: var(--ddd-theme-default-nittanyNavy, #001e44); } - input { - font-family: "Press Start 2P", sans-serif; - font-size: 28px; - padding: 8px; - border: 4px solid black; - border-radius: 8px; - width: 75%; + + input::placeholder { + color: var(--ddd-theme-default-slateGray, #666); + text-transform: capitalize; } + button { - font-family: "Press Start 2P", sans-serif; - font-size: 30px; - padding: 8px; - border: 4px solid black; - border-radius: 8px; - min-width: 50%; - margin: 16px; - } - button:focus, - button:hover { - background-color: var(--simple-colors-default-theme-green-8); - color: var(--simple-colors-default-theme-grey-1); - outline: 2px solid var(--simple-colors-default-theme-grey-1); + padding: var(--ddd-spacing-3, 12px) var(--ddd-spacing-4, 16px); + border-radius: var(--ddd-radius-sm, 4px); + font-size: var(--ddd-font-size-s, 16px); + font-weight: var(--ddd-font-weight-medium, 500); + font-family: var(--ddd-font-primary, sans-serif); cursor: pointer; + transition: all 0.2s ease; + border: none; + display: flex; + align-items: center; + justify-content: center; + gap: var(--ddd-spacing-2, 8px); + width: 100%; + min-height: var(--ddd-spacing-10, 40px); + background: var(--ddd-theme-default-nittanyNavy, #001e44); + color: var(--ddd-theme-default-white, white); + } + + button:disabled { + opacity: 0.5; + cursor: not-allowed; + } + + button:hover:not(:disabled) { + background: var(--ddd-theme-default-keystoneYellow, #ffd100); + color: var(--ddd-theme-default-nittanyNavy, #001e44); + transform: translateY(-1px); + box-shadow: var(--ddd-boxShadow-md); } + .notyou { - padding: 8px; + padding: var(--ddd-spacing-2, 8px); + font-size: var(--ddd-font-size-s, 16px); + color: var(--ddd-theme-default-coalyGray, #444); + } + + .notyou a { + color: var(--ddd-theme-default-nittanyNavy, #001e44); + text-decoration: underline; + cursor: pointer; + font-weight: var(--ddd-font-weight-medium, 500); } + + .notyou a:hover { + color: var(--ddd-theme-default-keystoneYellow, #ffd100); + } + .visibility-icon { - color: var(--simple-colors-default-theme-grey-12); - background-color: var(--simple-colors-default-theme-grey-3); - border: 2px solid var(--simple-colors-default-theme-grey-12); - position: relative; - margin-top: -44px; - margin-bottom: 20px; - margin-left: 70%; - z-index: 1; - padding: 2px; - --simple-icon-width: 26px; - --simple-icon-height: 26px; + position: absolute; + right: var(--ddd-spacing-3, 12px); + top: 50%; + transform: translateY(-50%); + background: transparent; + border: none; + color: var(--ddd-theme-default-slateGray, #666); + cursor: pointer; + padding: var(--ddd-spacing-1, 4px); + border-radius: var(--ddd-radius-xs, 2px); + transition: color 0.2s ease; + --simple-icon-width: var(--ddd-icon-xs, 16px); + --simple-icon-height: var(--ddd-icon-xs, 16px); + } + + .visibility-icon:hover { + color: var(--ddd-theme-default-nittanyNavy, #001e44); + } + + .external { + text-align: center; + width: 100%; + margin-top: var(--ddd-spacing-4, 16px); + } + + @media (max-width: 600px) { + :host { + padding: var(--ddd-spacing-4, 16px); + } + + rpg-character { + width: 80px; + height: 80px; + } + + #inputcontainer { + max-width: 100%; + } + + button { + font-size: var(--ddd-font-size-xs, 14px); + padding: var(--ddd-spacing-2, 8px) var(--ddd-spacing-3, 12px); + } } `, ]; @@ -236,36 +324,44 @@ export class AppHaxSiteLogin extends SimpleColors {

    ${this.errorMSG}

    ${this.hidePassword - ? html` + ? html`
    + +
    ` - : html`
    - Hey ${this.username}! not you? + : html`
    + Welcome back, ${this.username}! + Not you? +
    +
    + +
    - - `}
    diff --git a/elements/app-hax/lib/v2/app-hax-steps.js b/elements/app-hax/lib/v2/app-hax-steps.js index f5780ce397..a14884f472 100644 --- a/elements/app-hax/lib/v2/app-hax-steps.js +++ b/elements/app-hax/lib/v2/app-hax-steps.js @@ -697,7 +697,7 @@ export class AppHaxSteps extends SimpleColors { } #grid-container { display: grid; - grid-template-columns: 200px 200px 200px; + grid-template-columns: 160px 160px 160px; background: transparent; } .carousel-with-snapping-track { @@ -864,7 +864,7 @@ export class AppHaxSteps extends SimpleColors { font-size: 20px; } #grid-container { - grid-template-columns: 150px 150px 150px; + grid-template-columns: 120px 120px 120px; } } @media (max-height: 600px) { diff --git a/elements/app-hax/lib/v2/app-hax-use-case-filter.js b/elements/app-hax/lib/v2/app-hax-use-case-filter.js index 7c3f657bbe..194f77c390 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case-filter.js +++ b/elements/app-hax/lib/v2/app-hax-use-case-filter.js @@ -1,11 +1,14 @@ /* eslint-disable no-return-assign */ import { LitElement, html, css } from "lit"; import "@haxtheweb/simple-tooltip/simple-tooltip.js"; +import "@haxtheweb/simple-icon/lib/simple-icons.js"; +import "@haxtheweb/simple-icon/lib/simple-icon-lite.js"; import { store } from "./AppHaxStore.js"; import "./app-hax-use-case.js"; import "./app-hax-search-results.js"; import "./app-hax-filter-tag.js"; import "./app-hax-scroll-button.js"; +import "./app-hax-site-creation-modal.js"; export class AppHaxUseCaseFilter extends LitElement { static get tag() { @@ -29,13 +32,23 @@ export class AppHaxUseCaseFilter extends LitElement { this.selectedCardIndex = null; this.returningSites = []; this.allFilters = new Set(); + this.dark = false; + + // Listen to store changes for dark mode + if (typeof store !== "undefined") { + import("mobx").then(({ autorun, toJS }) => { + autorun(() => { + this.dark = toJS(store.darkMode); + }); + }); + } } static get properties() { return { searchTerm: { type: String }, showSearch: { type: Boolean, reflect: true, attribute: "show-search" }, - showFilter: {type: Boolean, reflect: true, attribute: "show-filter"}, + showFilter: { type: Boolean, reflect: true, attribute: "show-filter" }, disabled: { type: Boolean, reflect: true }, items: { type: Array }, filteredItems: { type: Array }, @@ -43,12 +56,13 @@ export class AppHaxUseCaseFilter extends LitElement { activeFilters: { type: Array }, filters: { type: Array }, searchQuery: { type: String }, - demoLink: { type: String}, + demoLink: { type: String }, errorMessage: { type: String }, loading: { type: Boolean }, selectedCardIndex: { type: Number }, returningSites: { type: Array }, - allFilters: { attribute: false } + allFilters: { attribute: false }, + dark: { type: Boolean, reflect: true }, }; } @@ -59,15 +73,20 @@ export class AppHaxUseCaseFilter extends LitElement { overflow: hidden; display: block; max-width: 100%; + font-family: var(--ddd-font-primary, sans-serif); } .contentSection { - display: flex; - align-items: flex-start; - justify-content: flex-start; - gap: 16px; - width: 100%; + display: flex; + align-items: flex-start; + justify-content: flex-start; + gap: var(--ddd-spacing-4, 16px); + width: 100%; + margin: 0 var(--ddd-spacing-4, 16px); + padding-right: var(--ddd-spacing-4, 16px); + box-sizing: border-box; } - .leftSection, .rightSection { + .leftSection, + .rightSection { display: flex; flex-direction: column; flex: 1 1 0; @@ -77,41 +96,41 @@ export class AppHaxUseCaseFilter extends LitElement { min-width: 260px; max-width: 380px; margin-left: 0; - margin-right: 24px; + margin-right: var(--ddd-spacing-1, 4px); padding-top: 0; box-sizing: border-box; position: sticky; } .rightSection { flex: 1; - min-width: 0; + min-width: 800px; width: 100%; + max-width: calc(100vw - 420px); box-sizing: border-box; display: flex; flex-direction: column; } .template-results { display: grid; - grid-template-columns: repeat(auto-fit, minmax(260px, 0.3fr)); + grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); width: 100%; min-height: 330px; box-sizing: border-box; + gap: var(--ddd-spacing-2, 8px); } #returnToSection { width: 100%; } #returnToSection app-hax-search-results { display: flex; - gap: 24px; - max-width: 824px; - min-width: 824px; + gap: var(--ddd-spacing-6, 24px); + min-width: calc(3 * 264px + 2 * var(--ddd-spacing-6, 24px)); min-height: 120px; box-sizing: border-box; justify-content: flex-start; align-items: stretch; flex-direction: row; flex-wrap: nowrap; - overflow-x: auto; scroll-behavior: smooth; } :host(:not([show-filter])) app-hax-search-results { @@ -121,14 +140,14 @@ export class AppHaxUseCaseFilter extends LitElement { h4, .returnTo h4, .startNew h4 { - font-family: var(--ddd-font-primary); - font-size: 24px; + font-family: var(--ddd-font-primary, sans-serif); + font-size: var(--ddd-font-size-l, 24px); color: var(--app-hax-accent-color, var(--accent-color)); - margin: 0 0 var(--ddd-spacing-4) 0; + margin: 0 0 var(--ddd-spacing-4, 16px) 0; } .startNew, .returnTo { - padding-top: 8px; + padding-top: var(--ddd-spacing-2, 8px); position: relative; display: flex; flex-direction: column; @@ -138,60 +157,86 @@ export class AppHaxUseCaseFilter extends LitElement { margin-right: 0; } .upper-filter { - margin-bottom: var(--ddd-spacing-3); + margin-bottom: var(--ddd-spacing-4, 16px); position: relative; display: inline-block; + width: 100%; } input[type="text"] { width: 100%; - max-width: 25vw; - padding: var(--ddd-spacing-3) var(--ddd-spacing-3) var(--ddd-spacing-3) 44px; - font-size: 15px; - border-radius: var(--ddd-radius-md); - border: var(--ddd-border-xs); - background: var(--simple-colors-default-theme-accent-2, var(--accent-color)); - color: #222; - transition: border 0.2s; + padding: var(--ddd-spacing-2, 8px) var(--ddd-spacing-2, 8px) + var(--ddd-spacing-2, 8px) var(--ddd-spacing-8, 32px); + font-size: var(--ddd-font-size-xs, 12px); + border-radius: var(--ddd-radius-sm, 4px); + border: var(--ddd-border-xs, 1px solid); + border-color: var(--ddd-theme-default-slateGray, #666); + background: var(--ddd-theme-default-white, white); + color: var(--ddd-theme-default-coalyGray, #222); + transition: all 0.2s ease; box-sizing: border-box; - font-family: var(--ddd-font-primary); - margin: 4px 0 0 4px; - height: 20px; - } + font-family: var(--ddd-font-primary, sans-serif); + margin: 0; + min-height: var(--ddd-spacing-8, 32px); + } + :host([dark]) input[type="text"], + body.dark-mode input[type="text"] { + background: var(--ddd-theme-default-coalyGray, #333); + color: var(--ddd-theme-default-white, white); + border-color: var(--ddd-theme-default-slateGray, #666); + } input[type="text"]:focus { - border: var(--ddd-border-sm); - background: var(--simple-colors-default-theme-accent-1, var(--accent-color)); + border: var(--ddd-border-md, 2px solid); + border-color: var(--ddd-theme-default-keystoneYellow, #ffd100); + background: var(--ddd-theme-default-white, white); outline: none; - } + } + :host([dark]) input[type="text"]:focus, + body.dark-mode input[type="text"]:focus { + background: var(--ddd-theme-default-coalyGray, #333); + border-color: var(--ddd-theme-default-keystoneYellow, #ffd100); + } .search-icon { position: absolute; - left: 16px; - top: 65%; - transform: translateY(-60%); - font-size: 18px; - color: var(--ddd-primary-8, #009cde); - align-self: center; - } + left: var(--ddd-spacing-2, 8px); + top: 50%; + transform: translateY(-50%); + font-size: var(--ddd-font-size-xs, 14px); + color: var(--ddd-theme-default-nittanyNavy, #001e44); + pointer-events: none; + z-index: 1; + --simple-icon-width: var(--ddd-icon-3xs, 20px); + --simple-icon-height: var(--ddd-icon-3xs, 20px); + } + :host([dark]) .search-icon, + body.dark-mode .search-icon { + color: var(--ddd-theme-default-white, white); + } .filter { - padding: 24px; position: sticky; top: 0; display: flex; flex-direction: column; - gap: var(--ddd-spacing-4); - background: var(--simple-colors-default-theme-accent-1, var(--accent-color)); - border-radius: var(--ddd-radius-lg); + gap: var(--ddd-spacing-5, 20px); + background: var(--ddd-theme-default-white, white); + border-radius: var(--ddd-radius-lg, 12px); box-shadow: var(--ddd-boxShadow-lg); - border: var(--ddd-border-xs); - border-color: var(--simple-colors-default-theme-accent-3, var(accent-color)); - padding: var(--ddd-spacing-6) var(--ddd-spacing-5) var(--ddd-spacing-5) var(--ddd-spacing-5); + border: var(--ddd-border-xs, 1px solid); + border-color: var(--ddd-theme-default-slateGray, #666); + padding: var(--ddd-spacing-6, 24px); margin-top: 0; - margin-left: 24px; + margin-left: var(--ddd-spacing-6, 24px); margin-bottom: 0; width: 100%; max-width: 320px; box-sizing: border-box; - font-family: var(--ddd-font-primary); - transition: box-shadow 0.2s; + font-family: var(--ddd-font-primary, sans-serif); + transition: box-shadow 0.2s ease; + } + :host([dark]) .filter, + body.dark-mode .filter { + background: var(--ddd-theme-default-coalyGray, #222); + border-color: var(--ddd-theme-default-slateGray, #666); + color: var(--ddd-theme-default-white, white); } .filter:hover { box-shadow: var(--ddd-boxShadow-xl); @@ -199,71 +244,126 @@ export class AppHaxUseCaseFilter extends LitElement { .filterButtons { display: flex; flex-direction: column; - gap: var(--ddd-spacing-3); + gap: var(--ddd-spacing-3, 12px); margin-top: 0; width: 100%; } .filter-btn { display: flex; align-items: center; - gap: var(--ddd-spacing-3); - padding: var(--ddd-spacing-3) var(--ddd-spacing-5); - border-radius: var(--ddd-radius-rounded); - border: none; - background: var(--simple-colors-default-theme-accent-2, var(--accent-color)); - color: var( --simple-colors-default-theme-blue-11, var(--accent-color)); - font-size: 1rem; - font-family: var(--ddd-font-primary); - font-weight: 600; + justify-content: flex-start; + gap: var(--ddd-spacing-1, 4px); + padding: var(--ddd-spacing-2, 8px) var(--ddd-spacing-3, 12px); + border-radius: var(--ddd-radius-sm, 4px); + border: var(--ddd-border-xs, 1px solid) transparent; + background: var(--ddd-theme-default-limestoneGray, #f5f5f5); + color: var(--ddd-theme-default-nittanyNavy, #001e44); + font-size: var(--ddd-font-size-3xs, 11px); + font-family: var(--ddd-font-primary, sans-serif); + font-weight: var(--ddd-font-weight-medium, 500); cursor: pointer; box-shadow: var(--ddd-boxShadow-sm); - transition: box-shadow 0.2s; + transition: all 0.2s ease; outline: none; - min-height: 44px; + min-height: var(--ddd-spacing-7, 28px); + text-align: left; + } + :host([dark]) .filter-btn, + body.dark-mode .filter-btn { + background: var(--ddd-theme-default-slateGray, #444); + color: var(--ddd-theme-default-white, white); } .filter-btn.active, .filter-btn:active { - background: var(--ddd-primary-8, #009cde); - color: #fff; + background: var(--ddd-theme-default-nittanyNavy, #001e44); + color: var(--ddd-theme-default-white, white); + border-color: var(--ddd-theme-default-keystoneYellow, #ffd100); box-shadow: var(--ddd-boxShadow-md); } + :host([dark]) .filter-btn.active, + :host([dark]) .filter-btn:active, + body.dark-mode .filter-btn.active, + body.dark-mode .filter-btn:active { + background: var(--ddd-theme-default-keystoneYellow, #ffd100); + color: var(--ddd-theme-default-nittanyNavy, #001e44); + border-color: var(--ddd-theme-default-white, white); + } .filter-btn:hover { - background: var(--ddd-accent-3, #e4e5e7); + background: var(--ddd-theme-default-slateGray, #666); + color: var(--ddd-theme-default-white, white); + transform: translateY(-1px); + } + :host([dark]) .filter-btn:hover, + body.dark-mode .filter-btn:hover { + background: var(--ddd-theme-default-limestoneGray, #f5f5f5); + color: var(--ddd-theme-default-nittanyNavy, #001e44); } .filter-btn .icon { - font-size: 18px; + font-size: var(--ddd-font-size-3xs, 12px); color: inherit; display: flex; align-items: center; + flex-shrink: 0; + width: var(--ddd-icon-3xs, 20px); + height: var(--ddd-icon-3xs, 20px); + } + .filter-btn .icon simple-icon-lite { + color: inherit; + --simple-icon-width: var(--ddd-icon-3xs, 20px); + --simple-icon-height: var(--ddd-icon-3xs, 20px); + } + .filter-btn.active .icon, + .filter-btn.active .icon simple-icon-lite { + color: inherit; + } + :host([dark]) .filter-btn.active .icon, + :host([dark]) .filter-btn.active .icon simple-icon-lite, + body.dark-mode .filter-btn.active .icon, + body.dark-mode .filter-btn.active .icon simple-icon-lite { + color: inherit; + } + .filter-btn:hover .icon simple-icon-lite, + .filter-btn:focus .icon simple-icon-lite { + color: inherit; } input[type="checkbox"] { display: none; } .reset-button { - margin-top: var(--ddd-spacing-5); - background: var(--ddd-primary-2, #001e44); - border: none; - color: #fff; - border-radius: var(--ddd-radius-rounded); - font-size: 1rem; - font-family: var(--ddd-font-primary); - font-weight: 600; - padding: var(--ddd-spacing-3) var(--ddd-spacing-5); + margin-top: var(--ddd-spacing-1, 4px); + background: var(--ddd-theme-default-original87Pink, #e4007c); + border: var(--ddd-border-xs, 1px solid) transparent; + color: var(--ddd-theme-default-white, white); + border-radius: var(--ddd-radius-sm, 4px); + font-size: var(--ddd-font-size-3xs, 11px); + font-family: var(--ddd-font-primary, sans-serif); + font-weight: var(--ddd-font-weight-medium, 500); + padding: var(--ddd-spacing-2, 8px) var(--ddd-spacing-3, 12px); display: flex; align-items: center; justify-content: center; - gap: var(--ddd-spacing-3); + gap: var(--ddd-spacing-1, 4px); box-shadow: var(--ddd-boxShadow-sm); - } + cursor: pointer; + transition: all 0.2s ease; + min-height: var(--ddd-spacing-7, 28px); + } .reset-button:hover { - background-color: var(--simple-colors-default-theme-light-blue-7, var(--accent-color)); - //background: var(--ddd-primary-8, var(--ddd-primary-1)); - //background: #009cde; + background: var(--ddd-theme-default-beaver70, #c85c2c); + transform: translateY(-1px); + } + :host([dark]) .reset-button, + body.dark-mode .reset-button { + background: var(--ddd-theme-default-beaver70, #c85c2c); + } + :host([dark]) .reset-button:hover, + body.dark-mode .reset-button:hover { + background: var(--ddd-theme-default-original87Pink, #e4007c); } .collapseFilter { display: none; } - + @media (max-width: 780px) { :host .filter { display: none; @@ -277,7 +377,7 @@ export class AppHaxUseCaseFilter extends LitElement { display: flex; } } - + @media (max-width: 600px) { :host .filter { display: none; @@ -294,7 +394,7 @@ export class AppHaxUseCaseFilter extends LitElement { `, ]; } - + testKeydown(e) { if (e.key === "Escape" || e.key === "Enter") { this.toggleSearch(); @@ -308,12 +408,15 @@ export class AppHaxUseCaseFilter extends LitElement { render() { return html`
    -
    +
    - + - ` + `, )}
    - +
    @@ -355,29 +464,29 @@ export class AppHaxUseCaseFilter extends LitElement {

    Return to...

    - + .searchTerm=${this.searchTerm} + ?dark="${this.dark}" + >
    - +

    Create New Site

    -
    - ${this.activeFilters.map( - (filter) => html` - - ` - )} -
    ${this.filteredItems.length > 0 ? this.filteredItems.map( (item, index) => html`
    - + this.toggleDisplay(index, e)} @continue-action=${() => this.continueAction(index)} >
    - ` + `, ) : html`

    No templates match the filters specified.

    `}
    + + + `; } - - - iconForFilter(filter) { switch (filter.toLowerCase()) { case "blog": @@ -426,11 +539,10 @@ export class AppHaxUseCaseFilter extends LitElement { this.applyFilters(); this.requestUpdate(); } - firstUpdated() { super.firstUpdated(); - this.updateRecipeResults(); + this.updateRecipeResults(); this.updateSiteResults(); } @@ -470,24 +582,31 @@ export class AppHaxUseCaseFilter extends LitElement { store.searchTerm = searchTerm; // Update store with search term // Filter templates (recipes) - this.filteredItems = [...this.items.filter( - item => - item.dataType === "recipe" && - ( - item.useCaseTitle.toLowerCase().includes(searchTerm) || - (item.useCaseTag && item.useCaseTag.some(tag => tag.toLowerCase().includes(searchTerm))) - ) - )]; + this.filteredItems = [ + ...this.items.filter( + (item) => + item.dataType === "recipe" && + (item.useCaseTitle.toLowerCase().includes(searchTerm) || + (item.useCaseTag && + item.useCaseTag.some((tag) => + tag.toLowerCase().includes(searchTerm), + ))), + ), + ]; // Filter returning sites - this.filteredSites = [...this.items.filter( - item => - item.dataType === "site" && - ( - (item.originalData.title && item.originalData.title.toLowerCase().includes(searchTerm)) || - (item.useCaseTag && item.useCaseTag.some(tag => tag.toLowerCase().includes(searchTerm))) - ) - )]; + this.filteredSites = [ + ...this.items.filter( + (item) => + item.dataType === "site" && + ((item.originalData.title && + item.originalData.title.toLowerCase().includes(searchTerm)) || + (item.useCaseTag && + item.useCaseTag.some((tag) => + tag.toLowerCase().includes(searchTerm), + ))), + ), + ]; this.requestUpdate(); } @@ -496,7 +615,9 @@ export class AppHaxUseCaseFilter extends LitElement { const filterValue = event.target.value; if (this.activeFilters.includes(filterValue)) { - this.activeFilters = [...this.activeFilters.filter((f) => f !== filterValue)]; + this.activeFilters = [ + ...this.activeFilters.filter((f) => f !== filterValue), + ]; } else { this.activeFilters = [...this.activeFilters, filterValue]; } @@ -505,39 +626,53 @@ export class AppHaxUseCaseFilter extends LitElement { applyFilters() { const lowerCaseQuery = this.searchTerm.toLowerCase(); - + // Filter recipes (from this.items) - this.filteredItems = [...this.items.filter((item) => { - if (item.dataType !== "recipe") return false; - const matchesSearch = - lowerCaseQuery === "" || - item.useCaseTitle.toLowerCase().includes(lowerCaseQuery) || - (item.useCaseTag && item.useCaseTag.some(tag => tag.toLowerCase().includes(lowerCaseQuery))); - - const matchesFilters = - this.activeFilters.length === 0 || - (item.useCaseTag && this.activeFilters.some(filter => item.useCaseTag.includes(filter))); - - return matchesSearch && matchesFilters; - })]; + this.filteredItems = [ + ...this.items.filter((item) => { + if (item.dataType !== "recipe") return false; + const matchesSearch = + lowerCaseQuery === "" || + item.useCaseTitle.toLowerCase().includes(lowerCaseQuery) || + (item.useCaseTag && + item.useCaseTag.some((tag) => + tag.toLowerCase().includes(lowerCaseQuery), + )); + + const matchesFilters = + this.activeFilters.length === 0 || + (item.useCaseTag && + this.activeFilters.some((filter) => + item.useCaseTag.includes(filter), + )); + + return matchesSearch && matchesFilters; + }), + ]; // Filter sites (from this.returningSites) - this.filteredSites = [...this.returningSites.filter((item) => { - if (item.dataType !== "site") return false; - const siteCategory = item.originalData.metadata?.site?.category || []; - const matchesSearch = - lowerCaseQuery === "" || - (item.originalData.category && item.originalData.category && item.originalData.category.includes(lowerCaseQuery)) || - (item.useCaseTag && item.useCaseTag.some(tag => tag.toLowerCase().includes(lowerCaseQuery))); - const matchesFilters = - this.activeFilters.length === 0 || - this.activeFilters.some((filter) => { - return siteCategory.includes(filter); - }); - return matchesSearch && matchesFilters; - })]; + this.filteredSites = [ + ...this.returningSites.filter((item) => { + if (item.dataType !== "site") return false; + const siteCategory = item.originalData.metadata?.site?.category || []; + const matchesSearch = + lowerCaseQuery === "" || + (item.originalData.category && + item.originalData.category && + item.originalData.category.includes(lowerCaseQuery)) || + (item.useCaseTag && + item.useCaseTag.some((tag) => + tag.toLowerCase().includes(lowerCaseQuery), + )); + const matchesFilters = + this.activeFilters.length === 0 || + this.activeFilters.some((filter) => { + return siteCategory.includes(filter); + }); + return matchesSearch && matchesFilters; + }), + ]; } - - + removeFilter(event) { const filterToRemove = event.detail; this.activeFilters = this.activeFilters.filter((f) => f !== filterToRemove); @@ -550,12 +685,16 @@ export class AppHaxUseCaseFilter extends LitElement { store.searchTerm = ""; this.activeFilters = []; // Show all templates and all sites - this.filteredItems = [...this.items.filter(item => item.dataType === "recipe")]; + this.filteredItems = [ + ...this.items.filter((item) => item.dataType === "recipe"), + ]; this.filteredSites = [...this.returningSites]; // Clear UI elements this.shadowRoot.querySelector("#searchField").value = ""; - this.shadowRoot.querySelectorAll('input[type="checkbox"]').forEach(cb => cb.checked = false); + this.shadowRoot + .querySelectorAll('input[type="checkbox"]') + .forEach((cb) => (cb.checked = false)); this.requestUpdate(); } @@ -563,54 +702,62 @@ export class AppHaxUseCaseFilter extends LitElement { updateRecipeResults() { this.loading = true; this.errorMessage = ""; - - const recipesUrl = new URL('./app-hax-recipes.json', import.meta.url).href; - + + const recipesUrl = new URL("./app-hax-recipes.json", import.meta.url).href; + fetch(recipesUrl) - .then(response => { - if (!response.ok) throw new Error(`Failed Recipes (${response.status})`); + .then((response) => { + if (!response.ok) + throw new Error(`Failed Recipes (${response.status})`); return response.json(); }) - .then(recipesData => { - const recipeItems = Array.isArray(recipesData.item) ? recipesData.item.map(item => { - let tags = []; - if (Array.isArray(item.category)) { - tags = item.category.filter(c => typeof c === 'string' && c.trim() !== ''); - } else if (typeof item.category === 'string' && item.category.trim() !== '') { - tags = [item.category.trim()]; - } - if (tags.length === 0) tags = ['Empty']; - tags.forEach(tag => this.allFilters.add(tag)); // Add to global Set - - const icons = Array.isArray(item.attributes) - ? item.attributes.map(attr => ({ - icon: attr.icon || '', - tooltip: attr.tooltip || '' - })) - : []; - - return { - dataType: 'recipe', - useCaseTitle: item.title || 'Untitled Template', - useCaseImage: item.image || '', - useCaseDescription: item.description || '', - useCaseIcon: icons, - useCaseTag: tags, - demoLink: item["demo-url"] || '#', - originalData: item - }; - }) : []; - + .then((recipesData) => { + const recipeItems = Array.isArray(recipesData.item) + ? recipesData.item.map((item) => { + let tags = []; + if (Array.isArray(item.category)) { + tags = item.category.filter( + (c) => typeof c === "string" && c.trim() !== "", + ); + } else if ( + typeof item.category === "string" && + item.category.trim() !== "" + ) { + tags = [item.category.trim()]; + } + if (tags.length === 0) tags = ["Empty"]; + tags.forEach((tag) => this.allFilters.add(tag)); // Add to global Set + + const icons = Array.isArray(item.attributes) + ? item.attributes.map((attr) => ({ + icon: attr.icon || "", + tooltip: attr.tooltip || "", + })) + : []; + + return { + dataType: "recipe", + useCaseTitle: item.title || "Untitled Template", + useCaseImage: item.image || "", + useCaseDescription: item.description || "", + useCaseIcon: icons, + useCaseTag: tags, + demoLink: item["demo-url"] || "#", + originalData: item, + }; + }) + : []; + this.items = recipeItems; this.filters = Array.from(this.allFilters).sort(); // Set AFTER all items - + if (this.items.length === 0 && !this.errorMessage) { - this.errorMessage = 'No Recipes Found'; + this.errorMessage = "No Recipes Found"; } - + this.resetFilters(); }) - .catch(error => { + .catch((error) => { this.errorMessage = `Failed to load data: ${error.message}`; this.items = []; this.filters = []; @@ -618,48 +765,55 @@ export class AppHaxUseCaseFilter extends LitElement { .finally(() => { this.loading = false; }); - } + } updateSiteResults() { this.loading = true; this.errorMessage = ""; - - const sitesUrl = new URL('../../demo/sites.json', import.meta.url).href; - + + const sitesUrl = new URL("../../demo/sites.json", import.meta.url).href; + fetch(sitesUrl) - .then(response => { + .then((response) => { if (!response.ok) throw new Error(`Failed Sites (${response.status})`); return response.json(); }) - .then(sitesData => { - const siteItems = Array.isArray(sitesData.data.items) ? sitesData.data.items.map(item => { - let categorySource = item.metadata.site.category; - let tags = []; - if (Array.isArray(categorySource)) { - tags = categorySource.filter(c => typeof c === 'string' && c.trim() !== ''); - } else if (typeof categorySource === 'string' && categorySource.trim() !== '') { - tags = [categorySource.trim()]; - } - if (tags.length === 0) tags = ['Empty']; - tags.forEach(tag => this.allFilters.add(tag)); // Add to global Set - return { - dataType: 'site', - useCaseTag: tags, - originalData: item, - ...item // this spreads every prop into this area that way it can be filtered correctly - }; - }) : []; + .then((sitesData) => { + const siteItems = Array.isArray(sitesData.data.items) + ? sitesData.data.items.map((item) => { + let categorySource = item.metadata.site.category; + let tags = []; + if (Array.isArray(categorySource)) { + tags = categorySource.filter( + (c) => typeof c === "string" && c.trim() !== "", + ); + } else if ( + typeof categorySource === "string" && + categorySource.trim() !== "" + ) { + tags = [categorySource.trim()]; + } + if (tags.length === 0) tags = ["Empty"]; + tags.forEach((tag) => this.allFilters.add(tag)); // Add to global Set + return { + dataType: "site", + useCaseTag: tags, + originalData: item, + ...item, // this spreads every prop into this area that way it can be filtered correctly + }; + }) + : []; this.returningSites = [...siteItems]; this.filters = Array.from(this.allFilters).sort(); // Set AFTER all items this.filteredSites = [...siteItems]; - + if (siteItems.length === 0 && !this.errorMessage) { - this.errorMessage = 'No Sites Found'; + this.errorMessage = "No Sites Found"; } - + this.requestUpdate(); }) - .catch(error => { + .catch((error) => { this.errorMessage = `Failed to load data: ${error.message}`; this.returningSites = []; this.filteredSites = []; @@ -669,8 +823,7 @@ export class AppHaxUseCaseFilter extends LitElement { this.loading = false; }); } - - + toggleDisplay(index, event) { const isSelected = event.detail.isSelected; @@ -694,8 +847,36 @@ export class AppHaxUseCaseFilter extends LitElement { } continueAction(index) { - console.log(`Continue action for item at index ${index}`); - // Implement the continue action for the selected item + const selectedTemplate = this.filteredItems[index]; + const modal = this.shadowRoot.querySelector("#siteCreationModal"); + + if (modal && selectedTemplate) { + // Set the template details in the modal + modal.title = selectedTemplate.useCaseTitle; + modal.description = selectedTemplate.useCaseDescription; + modal.source = selectedTemplate.useCaseImage; + modal.template = selectedTemplate.useCaseTitle; + + // Open the modal + modal.openModal(); + } + } + + handleModalClosed(event) { + // If modal was cancelled (not completed), reset selected states + if (event.detail && event.detail.cancelled) { + // Reset the selected card if one was selected + if ( + this.selectedCardIndex !== null && + this.filteredItems[this.selectedCardIndex] + ) { + this.filteredItems[this.selectedCardIndex].isSelected = false; + this.filteredItems[this.selectedCardIndex].showContinue = false; + this.selectedCardIndex = null; + this.requestUpdate(); + } + } + console.log("Site creation modal closed", event.detail); } } -customElements.define("app-hax-use-case-filter", AppHaxUseCaseFilter); \ No newline at end of file +customElements.define("app-hax-use-case-filter", AppHaxUseCaseFilter); diff --git a/elements/app-hax/lib/v2/app-hax-use-case.js b/elements/app-hax/lib/v2/app-hax-use-case.js index 7a2c9c822a..0c25ad09d8 100644 --- a/elements/app-hax/lib/v2/app-hax-use-case.js +++ b/elements/app-hax/lib/v2/app-hax-use-case.js @@ -4,17 +4,16 @@ import "@haxtheweb/simple-tooltip/simple-tooltip.js"; import { store } from "./AppHaxStore.js"; export class AppHaxUseCase extends LitElement { - static get tag() { return "app-hax-use-case"; } constructor() { super(); - this.title = ''; - this.description = ''; - this.source = ''; - this.demoLink = ''; + this.title = ""; + this.description = ""; + this.source = ""; + this.demoLink = ""; this.iconImage = []; this.isSelected = false; this.showContinue = false; @@ -22,19 +21,17 @@ export class AppHaxUseCase extends LitElement { static get properties() { return { - title: { type: String }, - description: { type: String }, - source: { type: String }, - demoLink: { type: String }, - iconImage: { type: Array }, - isSelected: { type: Boolean , reflect: true}, - showContinue: { type: Boolean } + title: { type: String }, + description: { type: String }, + source: { type: String }, + demoLink: { type: String }, + iconImage: { type: Array }, + isSelected: { type: Boolean, reflect: true }, + showContinue: { type: Boolean }, }; } - updated(changedProperties) { - - } + updated(changedProperties) {} static get styles() { return [ @@ -43,24 +40,24 @@ export class AppHaxUseCase extends LitElement { display: flex; flex-direction: column; text-align: left; - max-width: 240px; - margin:12px; + max-width: 200px; + margin: 8px; font-family: var(--ddd-font-primary); color: var(--ddd-theme-default-nittanyNavy); background-color: white; - min-height: 270px; + min-height: 240px; box-shadow: 2px 2px 12px #1c1c1c; - border-radius: 8px; + border-radius: 4px; } .cardContent { - padding: 12px 16px 20px; + padding: 8px 12px 16px; } .image img { - width: 240px; - height: 142px; - border-top-right-radius: 8px; - border-top-left-radius: 8px; - border-bottom: solid var(--ddd-theme-default-nittanyNavy) 12px; + width: 200px; + height: 120px; + border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-bottom: solid var(--ddd-theme-default-nittanyNavy) 8px; overflow: clip; justify-self: center; } @@ -70,23 +67,23 @@ export class AppHaxUseCase extends LitElement { } .icons { position: absolute; - bottom: 18px; - left: 10px; + bottom: 14px; + left: 8px; display: flex; - gap: 6px; + gap: 4px; z-index: 10; } .icon-wrapper { position: relative; - width: 32px; - height: 32px; - flex-shrink: 0; + width: 24px; + height: 24px; + flex-shrink: 0; display: flex; align-items: center; justify-content: center; } .icon-wrapper::before { - content: ''; + content: ""; position: absolute; width: 100%; height: 100%; @@ -137,52 +134,79 @@ export class AppHaxUseCase extends LitElement { width: 20px; height: 20px; } - h3, p { - margin: 2px; + h3 { + font-size: var(--ddd-font-size-4xs); } p { - font-size: 12px; + font-size: var(--ddd-font-size-4xs); + padding: 0; + margin: 0; } a:link { - color: var(--ddd-theme-defaut-skyBlue); + color: var(--ddd-theme-default-nittanyNavy, #001e44); + text-decoration: underline; + font-family: var(--ddd-font-primary, sans-serif); + font-size: var(--ddd-font-size-3xs, 11px); + font-weight: var(--ddd-font-weight-medium, 500); + transition: color 0.2s ease; + display: flex; + align-items: center; + justify-content: center; + } + + a:visited { + color: var(--ddd-theme-default-slateGray, #666); + } + + a:hover, + a:focus { + color: var(--ddd-theme-default-keystoneYellow, #ffd100); text-decoration: none; - font-family: var(--ddd-font-primary); - font-size: 16px; } button { display: flex; - background-color: #005fa9; - color: white; - border: 0px; - border-radius: 4px; - font-family: var(--ddd-font-primary); - font-size: 12px; - font-weight: 20px; - padding: 12px 16px 12px 24px; - margin: 0px 4px 0px 4px; - height: 16px; + background: var(--ddd-theme-default-nittanyNavy, #001e44); + color: var(--ddd-theme-default-white, white); + border: var(--ddd-border-xs, 1px solid) transparent; + border-radius: var(--ddd-radius-sm, 4px); + font-family: var(--ddd-font-primary, sans-serif); + font-size: var(--ddd-font-size-3xs, 11px); + font-weight: var(--ddd-font-weight-medium, 500); + padding: var(--ddd-spacing-2, 8px) var(--ddd-spacing-3, 12px); + margin: 0px var(--ddd-spacing-1, 4px); + min-height: var(--ddd-spacing-7, 28px); align-items: center; justify-content: center; + cursor: pointer; + transition: all 0.2s ease; + box-shadow: var(--ddd-boxShadow-sm); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } button:hover { - background-color: var(--ddd-theme-default-nittanyNavy); + background: var(--ddd-theme-default-keystoneYellow, #ffd100); + color: var(--ddd-theme-default-nittanyNavy, #001e44); + transform: translateY(-1px); + box-shadow: var(--ddd-boxShadow-md); } .cardBottom { display: flex; justify-content: space-between; align-items: center; - margin-top: 8px; - padding: 0px 16px 20px 16px; + margin-top: 6px; + padding: 0px 12px 16px 12px; + gap: 4px; } - .cardBottom button, .cardBottom a { + .cardBottom button, + .cardBottom a { flex: 1; - margin: 0 4px; + margin: 0 2px; + min-width: 0; + font-size: var(--ddd-font-size-3xs, 11px); } - .cardBottom a:visited { - color: var(--simple-colors-default-theme-light-blue-9); - } - + :host([isSelected]) button.select { background-color: var(--ddd-theme-default-nittanyNavy); } @@ -190,10 +214,25 @@ export class AppHaxUseCase extends LitElement { display: inline-flex; flex-direction: column; text-align: left; - padding: 0px 16px; + padding: 0px 12px; + } + @media (max-width: 768px) { + .cardBottom { + gap: var(--ddd-spacing-1, 4px); + padding: 0px var(--ddd-spacing-2, 8px) var(--ddd-spacing-3, 12px) + var(--ddd-spacing-2, 8px); + } + .cardBottom button, + .cardBottom a { + font-size: var(--ddd-font-size-4xs, 10px); + padding: var(--ddd-spacing-1, 4px) var(--ddd-spacing-2, 8px); + min-height: var(--ddd-spacing-6, 24px); + margin: 0; + } } @media (max-width: 1440px) { - :host, .image img { + :host, + .image img { display: flex; width: 250px; max-width: 20vw; @@ -209,63 +248,91 @@ export class AppHaxUseCase extends LitElement { toggleDisplay() { this.isSelected = !this.isSelected; this.showContinue = this.isSelected; - this.dispatchEvent(new CustomEvent('toggle-display', { - detail: { isSelected: this.isSelected }, - bubbles: true, - composed: true - })); + + this.dispatchEvent( + new CustomEvent("toggle-display", { + detail: { isSelected: this.isSelected }, + bubbles: true, + composed: true, + }), + ); + + // If selected, immediately trigger the continue action to open modal + if (this.isSelected) { + setTimeout(() => { + this.continueAction(); + }, 100); // Small delay to allow state to update + } } continueAction() { - if (confirm("Are you sure?")) { - this.dispatchEvent(new CustomEvent('continue-action')); + this.dispatchEvent( + new CustomEvent("continue-action", { + detail: { + title: this.title, + description: this.description, + source: this.source, + template: this.title, // Using title as template identifier + }, + bubbles: true, + composed: true, + }), + ); + } + + openDemo() { + if (this.demoLink) { + globalThis.open(this.demoLink, "_blank"); } - } render() { return html` -
    -
    - - ${this.title} -
    - ${this.iconImage.map( - (icon) => html` -
    - -
    - ` - )} -
    +
    +
    + ${this.title} +
    ${this.iconImage.map( (icon) => html` -
    - -
    ${icon.tooltip}
    +
    +
    - ` + `, )} +
    + ${this.iconImage.map( + (icon) => html` +
    + +
    ${icon.tooltip}
    +
    + `, + )} +
    -
    -

    ${this.title}

    +

    ${this.title}

    ${this.description}

    -
    - - ${this.isSelected - ? html`` - : html`Demo -> ` - } + ${!this.isSelected + ? html`` + : ""}
    -
    `; } - } customElements.define(AppHaxUseCase.tag, AppHaxUseCase); diff --git a/elements/app-hax/lib/v2/app-hax-user-access-modal.js b/elements/app-hax/lib/v2/app-hax-user-access-modal.js new file mode 100644 index 0000000000..b81b4382f5 --- /dev/null +++ b/elements/app-hax/lib/v2/app-hax-user-access-modal.js @@ -0,0 +1,481 @@ +/** + * Copyright 2025 The Pennsylvania State University + * @license Apache-2.0, see License.md for full text. + */ +import { html, css } from "lit"; +import { DDDSuper } from "@haxtheweb/d-d-d/d-d-d.js"; +import { I18NMixin } from "@haxtheweb/i18n-manager/lib/I18NMixin.js"; +import "@haxtheweb/rpg-character/rpg-character.js"; +import "@haxtheweb/simple-icon/lib/simple-icons.js"; +import "@haxtheweb/simple-icon/lib/simple-icon-button.js"; +import { store } from "./AppHaxStore.js"; + +/** + * `app-hax-user-access-modal` + * `Modal for managing user access to HAXiam sites` + * + * @demo demo/index.html + * @element app-hax-user-access-modal + */ +class AppHaxUserAccessModal extends I18NMixin(DDDSuper) { + /** + * Convention we use + */ + static get tag() { + return "app-hax-user-access-modal"; + } + + constructor() { + super(); + this.username = ""; + this.loading = false; + this.error = ""; + this.siteTitle = ""; + this.t = { + userAccess: "User Access", + enterUsername: "Enter username to grant access", + usernamePlaceholder: "Username", + addUser: "Add User", + cancel: "Cancel", + userAccessGranted: "User access granted successfully!", + userNotFound: "User not found or unauthorized", + loadingAddingUser: "Adding user...", + grantAccessTo: "Grant access to:", + }; + } + + static get properties() { + return { + ...super.properties, + /** + * Username to add + */ + username: { + type: String, + }, + /** + * Loading state + */ + loading: { + type: Boolean, + }, + /** + * Error message + */ + error: { + type: String, + }, + /** + * Current site title + */ + siteTitle: { + type: String, + }, + }; + } + + static get styles() { + return [ + super.styles, + css` + :host { + display: block; + font-family: var(--ddd-font-primary); + background-color: var(--ddd-theme-default-white); + border-radius: var(--ddd-radius-sm); + padding: var(--ddd-spacing-6); + min-width: 420px; + max-width: 500px; + } + + .modal-content { + display: flex; + flex-direction: column; + align-items: center; + gap: var(--ddd-spacing-4); + } + + .site-info { + text-align: center; + margin-bottom: var(--ddd-spacing-2); + } + + .site-title { + color: var(--ddd-theme-default-nittanyNavy); + font-weight: var(--ddd-font-weight-bold); + font-size: var(--ddd-font-size-s); + margin: var(--ddd-spacing-1) 0; + } + + .character-container { + display: flex; + justify-content: center; + margin: var(--ddd-spacing-2) 0; + padding: var(--ddd-spacing-3); + border-radius: var(--ddd-radius-sm); + background-color: var(--ddd-theme-default-limestoneLight); + } + + rpg-character { + width: 120px; + height: auto; + } + + .input-container { + width: 100%; + display: flex; + flex-direction: column; + gap: var(--ddd-spacing-2); + } + + input { + padding: var(--ddd-spacing-3); + border: var(--ddd-border-sm); + border-radius: var(--ddd-radius-xs); + font-family: var(--ddd-font-primary); + font-size: var(--ddd-font-size-s); + width: 100%; + box-sizing: border-box; + transition: + border-color 0.2s ease, + box-shadow 0.2s ease; + } + + input:focus { + outline: none; + border-color: var(--ddd-theme-default-nittanyNavy); + box-shadow: 0 0 0 2px var(--ddd-theme-default-potential30); + } + + .buttons { + display: flex; + gap: var(--ddd-spacing-3); + justify-content: center; + width: 100%; + margin-top: var(--ddd-spacing-3); + } + + button { + background: var(--ddd-theme-default-nittanyNavy, #001e44); + color: var(--ddd-theme-default-white, white); + border: none; + border-radius: var(--ddd-radius-sm); + padding: var(--ddd-spacing-3) var(--ddd-spacing-5); + font-family: var(--ddd-font-primary); + font-size: var(--ddd-font-size-s); + font-weight: var(--ddd-font-weight-medium); + cursor: pointer; + transition: all 0.2s ease; + min-width: 100px; + display: flex; + align-items: center; + justify-content: center; + } + + button:hover:not(:disabled) { + background: var(--ddd-theme-default-keystoneYellow, #ffd100); + color: var(--ddd-theme-default-nittanyNavy, #001e44); + transform: translateY(-1px); + box-shadow: var(--ddd-boxShadow-sm); + } + + button:disabled { + background: var(--ddd-theme-default-slateGray); + cursor: not-allowed; + transform: none; + box-shadow: none; + opacity: 0.6; + } + + .cancel-button { + background: transparent; + color: var(--ddd-theme-default-nittanyNavy); + border: var(--ddd-border-sm); + } + + .cancel-button:hover:not(:disabled) { + background: var(--ddd-theme-default-slateLight); + color: var(--ddd-theme-default-nittanyNavy); + transform: translateY(-1px); + } + + .error { + color: var(--ddd-theme-default-original87Pink); + font-size: var(--ddd-font-size-xs); + text-align: center; + background-color: var(--ddd-theme-default-original87Pink10); + padding: var(--ddd-spacing-2); + border-radius: var(--ddd-radius-xs); + border: 1px solid var(--ddd-theme-default-original87Pink30); + } + + .loading { + display: flex; + align-items: center; + gap: var(--ddd-spacing-2); + justify-content: center; + } + + .loading simple-icon { + --simple-icon-width: 16px; + --simple-icon-height: 16px; + animation: spin 1s linear infinite; + } + + @keyframes spin { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } + } + + h3 { + margin: 0; + color: var(--ddd-theme-default-nittanyNavy); + font-size: var(--ddd-font-size-l); + text-align: center; + font-weight: var(--ddd-font-weight-bold); + } + + p { + margin: 0; + color: var(--ddd-theme-default-coalyGray); + font-size: var(--ddd-font-size-s); + text-align: center; + line-height: 1.4; + } + + .empty-character { + display: flex; + align-items: center; + justify-content: center; + width: 120px; + height: 120px; + color: var(--ddd-theme-default-slateGray); + font-size: var(--ddd-font-size-xs); + text-align: center; + } + `, + ]; + } + + render() { + return html` + + `; + } + + /** + * Handle username input changes + */ + _handleUsernameInput(e) { + this.username = e.target.value; + // Clear error when user types + if (this.error) { + this.error = ""; + } + } + + /** + * Handle keydown events + */ + _handleKeydown(e) { + if (e.key === "Enter" && this.username.trim() && !this.loading) { + this._handleAddUser(); + } else if (e.key === "Escape") { + this._handleCancel(); + } + } + + /** + * Handle add user button click + */ + async _handleAddUser() { + if (!this.username.trim()) { + return; + } + + this.loading = true; + this.error = ""; + + try { + const response = await this._addUserAccess(this.username.trim()); + + if (response.ok) { + // Success - show toast and close modal + this._showSuccessToast(); + this._closeModal(); + // Reset form + this.username = ""; + } else if (response.status === 403) { + // User not found or unauthorized + this.error = this.t.userNotFound; + } else { + // Other error + this.error = `Error: ${response.status} ${response.statusText}`; + } + } catch (error) { + console.error("Error adding user access:", error); + this.error = "Network error occurred. Please try again."; + } finally { + this.loading = false; + } + } + + /** + * Handle cancel button click + */ + _handleCancel() { + this._closeModal(); + } + + /** + * Add user access via HAXiam API + */ + async _addUserAccess(username) { + // This calls the HAXiam API endpoint implemented via hooks system in HAXcms-php + const endpoint = `${globalThis.location.origin}/api/haxiam/addUserAccess`; + + return fetch(endpoint, { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${globalThis.jwt || store.jwt || ""}`, + }, + body: JSON.stringify({ + username: username, + siteId: store.activeSite?.id || null, + sitePath: store.activeSite?.location || null, + }), + }); + } + + /** + * Show success toast with RPG character matching the added user + */ + _showSuccessToast() { + // Use the existing toast system but with the character seed matching the added user + store.toast(this.t.userAccessGranted, 4000, { + hat: "construction", + userName: this.username, // This ensures the toast character matches the user we just added + }); + } + + /** + * Close the modal + */ + _closeModal() { + globalThis.dispatchEvent( + new CustomEvent("simple-modal-hide", { + bubbles: true, + cancelable: true, + detail: {}, + }), + ); + } + + /** + * Focus input when modal opens + */ + firstUpdated() { + super.firstUpdated(); + // Set site title from store if available + if (store.activeSite?.title) { + this.siteTitle = store.activeSite.title; + } + + // Focus input after a brief delay + setTimeout(() => { + const input = this.shadowRoot.querySelector("input"); + if (input) { + input.focus(); + } + }, 100); + } + + /** + * Reset form when modal opens + */ + connectedCallback() { + super.connectedCallback(); + this.username = ""; + this.error = ""; + this.loading = false; + } +} + +globalThis.customElements.define( + AppHaxUserAccessModal.tag, + AppHaxUserAccessModal, +); +export { AppHaxUserAccessModal }; diff --git a/elements/app-hax/lib/v2/app-hax-user-menu-button.js b/elements/app-hax/lib/v2/app-hax-user-menu-button.js index a3870224ac..301fa174c9 100644 --- a/elements/app-hax/lib/v2/app-hax-user-menu-button.js +++ b/elements/app-hax/lib/v2/app-hax-user-menu-button.js @@ -2,8 +2,10 @@ // dependencies / things imported import { LitElement, html, css } from "lit"; +import { DDDSuper } from "@haxtheweb/d-d-d/d-d-d.js"; +import "@haxtheweb/simple-icon/lib/simple-icon-lite.js"; -export class AppHaxUserMenuButton extends LitElement { +export class AppHaxUserMenuButton extends DDDSuper(LitElement) { // a convention I enjoy so you can change the tag name in 1 place static get tag() { return "app-hax-user-menu-button"; @@ -15,6 +17,15 @@ export class AppHaxUserMenuButton extends LitElement { this.label = "Default"; } + handleClick(e) { + // Find the parent anchor element and trigger its click + const parentAnchor = this.parentElement; + if (parentAnchor && parentAnchor.tagName.toLowerCase() === "a") { + e.stopPropagation(); + parentAnchor.click(); + } + } + static get properties() { return { icon: { type: String }, @@ -23,46 +34,94 @@ export class AppHaxUserMenuButton extends LitElement { } static get styles() { - return css` - :host { - font-family: "Press Start 2P", sans-serif; - text-align: center; - width: 100%; - --background-color: var(--app-hax-background-color); - --accent-color: var(--app-hax-accent-color); - } + return [ + super.styles, + css` + :host { + font-family: var(--ddd-font-primary, sans-serif); + text-align: center; + width: 100%; + display: block; + } - .menu-button { - display: block; - width: 100%; - border: 2px solid var(--accent-color); - margin: 0; - padding: 8px; - font-size: 16px; - text-align: left; - color: var(--accent-color); - background-color: var(--background-color); - cursor: pointer; - } + .menu-button { + display: flex; + align-items: center; + width: 100%; + border: none; + margin: 0; + padding: var(--ddd-spacing-2, 8px) var(--ddd-spacing-3, 12px); + font-size: var(--ddd-font-size-3xs, 12px); + text-align: left; + color: var(--ddd-theme-default-nittanyNavy, #001e44); + background: transparent; + cursor: pointer; + font-family: var(--ddd-font-primary, sans-serif); + transition: all 0.2s ease; + min-height: var(--ddd-spacing-8, 32px); + box-sizing: border-box; + } - .menu-button:hover, - .menu-button:active, - .menu-button:focus { - background-color: var(--accent-color); - color: var(--background-color); - } + :host([dark]) .menu-button, + body.dark-mode .menu-button { + color: var(--ddd-theme-default-white, white); + } - .icon { - padding-right: 16px; - } - `; + .menu-button:hover, + .menu-button:active, + .menu-button:focus { + background: var(--ddd-theme-default-limestoneGray, #f5f5f5); + color: var(--ddd-theme-default-nittanyNavy, #001e44); + outline: none; + } + + :host([dark]) .menu-button:hover, + :host([dark]) .menu-button:active, + :host([dark]) .menu-button:focus, + body.dark-mode .menu-button:hover, + body.dark-mode .menu-button:active, + body.dark-mode .menu-button:focus { + background: var(--ddd-theme-default-slateGray, #666); + color: var(--ddd-theme-default-white, white); + } + + :host(.logout) .menu-button:hover, + :host(.logout) .menu-button:active, + :host(.logout) .menu-button:focus { + background: var(--ddd-theme-default-original87Pink, #e4007c); + color: var(--ddd-theme-default-white, white); + } + + .icon { + padding-right: var(--ddd-spacing-2, 8px); + font-size: var(--ddd-font-size-xs, 14px); + flex-shrink: 0; + display: flex; + align-items: center; + } + + .label { + flex: 1; + text-align: left; + } + `, + ]; } render() { return html` - `; } diff --git a/elements/app-hax/lib/v2/app-hax-user-menu.js b/elements/app-hax/lib/v2/app-hax-user-menu.js index 8b03e726e3..4086a6f6e4 100644 --- a/elements/app-hax/lib/v2/app-hax-user-menu.js +++ b/elements/app-hax/lib/v2/app-hax-user-menu.js @@ -3,8 +3,10 @@ // dependencies / things imported import { LitElement, html, css } from "lit"; +import { DDDSuper } from "@haxtheweb/d-d-d/d-d-d.js"; +import "@haxtheweb/simple-icon/lib/simple-icon-lite.js"; -export class AppHaxUserMenu extends LitElement { +export class AppHaxUserMenu extends DDDSuper(LitElement) { // a convention I enjoy so you can change the tag name in 1 place static get tag() { return "app-hax-user-menu"; @@ -24,63 +26,113 @@ export class AppHaxUserMenu extends LitElement { } static get styles() { - return css` - :host { - font-family: "Press Start 2P", sans-serif; - text-align: center; - display: inline-block; - margin: 0px; - padding: 0px; - } - - .entireComponent { - max-height: 48px; - } - - .menuToggle { - cursor: pointer; - max-height: 48px; - } - - .user-menu { - display: none; - } - - .user-menu.open { - display: block; - top: 50px; - right: 0px; - position: absolute; - border: 1px solid var(--app-hax-accent-color); - background-color: var(--app-hax-background-color); - } - - .user-menu.open ::slotted(*) { - display: block; - width: 100%; - margin: 0; - font-size: 16px; - text-align: left; - font-family: "Press Start 2P", sans-serif; - color: var(--app-hax-accent-color); - background-color: var(--app-hax-background-color); - } - - .user-menu.open .main-menu ::slotted(*:hover), - .user-menu.open .main-menu ::slotted(*:active), - .user-menu.open .main-menu ::slotted(*:focus) { - background-color: var(--app-hax-background-color-active); - color: var(--app-hax-background-color); - } - - .user-menu ::slotted(button) { - cursor: pointer; - } - - .user-menu ::slotted(*) simple-icon-lite { - padding-right: 16px; - } - `; + return [ + super.styles, + css` + :host { + font-family: var(--ddd-font-primary, sans-serif); + text-align: center; + display: inline-block; + margin: 0px; + padding: 0px; + position: relative; + } + + .entireComponent { + max-height: var(--ddd-spacing-10, 40px); + } + + .menuToggle { + cursor: pointer; + max-height: var(--ddd-spacing-10, 40px); + } + + .user-menu { + display: none; + } + + .user-menu.open { + display: block; + top: var(--ddd-spacing-12, 48px); + right: 0px; + position: absolute; + border: var(--ddd-border-xs, 1px solid) + var(--ddd-theme-default-slateGray, #666); + background: var(--ddd-theme-default-white, white); + border-radius: var(--ddd-radius-sm, 4px); + box-shadow: var(--ddd-boxShadow-lg); + min-width: var(--ddd-spacing-30, 200px); + z-index: 1000; + overflow: hidden; + } + + :host([dark]) .user-menu.open, + body.dark-mode .user-menu.open { + background: var(--ddd-theme-default-coalyGray, #333); + border-color: var(--ddd-theme-default-slateGray, #666); + } + + .user-menu.open ::slotted(*) { + display: block; + width: 100%; + margin: 0; + font-size: var(--ddd-font-size-3xs, 12px); + text-align: left; + font-family: var(--ddd-font-primary, sans-serif); + color: var(--ddd-theme-default-nittanyNavy, #001e44); + background: transparent; + text-decoration: none; + } + + :host([dark]) .user-menu.open ::slotted(*), + body.dark-mode .user-menu.open ::slotted(*) { + color: var(--ddd-theme-default-white, white); + } + + .user-menu.open .main-menu ::slotted(*:hover), + .user-menu.open .main-menu ::slotted(*:active), + .user-menu.open .main-menu ::slotted(*:focus) { + background: var(--ddd-theme-default-limestoneGray, #f5f5f5); + color: var(--ddd-theme-default-nittanyNavy, #001e44); + } + + :host([dark]) .user-menu.open .main-menu ::slotted(*:hover), + :host([dark]) .user-menu.open .main-menu ::slotted(*:active), + :host([dark]) .user-menu.open .main-menu ::slotted(*:focus), + body.dark-mode .user-menu.open .main-menu ::slotted(*:hover), + body.dark-mode .user-menu.open .main-menu ::slotted(*:active), + body.dark-mode .user-menu.open .main-menu ::slotted(*:focus) { + background: var(--ddd-theme-default-slateGray, #666); + color: var(--ddd-theme-default-white, white); + } + + .user-menu.open .post-menu ::slotted(*:hover), + .user-menu.open .post-menu ::slotted(*:active), + .user-menu.open .post-menu ::slotted(*:focus) { + background: var(--ddd-theme-default-original87Pink, #e4007c); + color: var(--ddd-theme-default-white, white); + } + + .user-menu ::slotted(button) { + cursor: pointer; + } + + .user-menu ::slotted(*) simple-icon-lite { + padding-right: var(--ddd-spacing-2, 8px); + } + + .pre-menu, + .post-menu { + border-top: var(--ddd-border-xs, 1px solid) + var(--ddd-theme-default-limestoneGray, #f5f5f5); + } + + .pre-menu:first-child, + .main-menu:first-child { + border-top: none; + } + `, + ]; } render() { diff --git a/elements/app-hax/lib/wired-darkmode-toggle/wired-darkmode-toggle.js b/elements/app-hax/lib/wired-darkmode-toggle/wired-darkmode-toggle.js index 3bb5a7effe..91f5f3e4d4 100644 --- a/elements/app-hax/lib/wired-darkmode-toggle/wired-darkmode-toggle.js +++ b/elements/app-hax/lib/wired-darkmode-toggle/wired-darkmode-toggle.js @@ -9,7 +9,8 @@ import { html, css, unsafeCSS } from "lit"; // need to highjack in order to alter the scale so we can fit our icon // for states const sun = new URL("./images/sunIcon.png", import.meta.url).href; -const lightModeCircle = new URL("./images/lightModeIcon.png", import.meta.url).href; +const lightModeCircle = new URL("./images/lightModeIcon.png", import.meta.url) + .href; const moon = new URL("./images/moonIcon.png", import.meta.url).href; export class WiredDarkmodeToggle extends WiredToggle { @@ -35,11 +36,14 @@ export class WiredDarkmodeToggle extends WiredToggle { this.knob = svgNode("g"); this.knob.classList.add("knob"); svg.appendChild(this.knob); - + this.knobFill.setAttribute("cx", 26); this.knobFill.setAttribute("cy", 26); this.knobFill.setAttribute("r", 20); - this.knobFill.setAttribute("style", "fill: var(--wired-toggle-off-color); transition: fill 0.3s ease-in-out;"); + this.knobFill.setAttribute( + "style", + "fill: var(--wired-toggle-off-color); transition: fill 0.3s ease-in-out;", + ); this.knobFill.classList.add("knobfill"); this.knob.appendChild(this.knobFill); ellipse(this.knob, 26, 26, 40, 40, this.seed); @@ -47,9 +51,15 @@ export class WiredDarkmodeToggle extends WiredToggle { toggleMode(checked) { if (checked) { - this.knobFill.setAttribute("style", "fill: var(--wired-toggle-on-color);"); + this.knobFill.setAttribute( + "style", + "fill: var(--wired-toggle-on-color);", + ); } else { - this.knobFill.setAttribute("style", "fill: var(--wired-toggle-off-color);"); + this.knobFill.setAttribute( + "style", + "fill: var(--wired-toggle-off-color);", + ); } } @@ -57,7 +67,7 @@ export class WiredDarkmodeToggle extends WiredToggle { this.checked = event.target.checked; this.toggleMode(this.checked); this.dispatchEvent(new Event("change", { bubbles: true, composed: true })); -} + } static get properties() { return { @@ -78,7 +88,7 @@ export class WiredDarkmodeToggle extends WiredToggle { render() { return html`
    - + { - if (store.soundStatus && store.appReady) { - let playSound = [ - "click", - "click2", - "coin", - "coin2", - "hit", - "success", - ].includes(sound) - ? sound - : "hit"; - this.audio = new Audio( - new URL(`./lib/assets/sounds/${playSound}.mp3`, import.meta.url).href, - ); - this.audio.volume = 0.3; - this.audio.onended = (event) => { - resolve(); - }; - this.audio.play(); - // resolve after 1s if sound failed to load - setTimeout(() => { - resolve(); - }, 1000); - } else { - resolve(); - } - }); - } - - /** - * A token refresh just failed so force to login prompt / state - */ - _tokenRefreshFailed(e) { - globalThis.dispatchEvent( - new CustomEvent("jwt-login-logout", { - composed: true, - bubbles: true, - cancelable: false, - detail: true, - }), - ); - setTimeout(() => { - this.reset(true); - }, 100); - } - - connectedCallback() { - super.connectedCallback(); - globalThis - .matchMedia("(prefers-color-scheme: dark)") - .addEventListener("change", darkToggle, { - signal: this.windowControllers.signal, - }); - globalThis.addEventListener("jwt-logged-in", this._jwtLoggedIn.bind(this), { - signal: this.windowControllers.signal, - }); - - globalThis.addEventListener( - "jwt-login-refresh-error", - this._tokenRefreshFailed.bind(this), - { signal: this.windowControllers.signal }, - ); - } - - goToLocation(location) { - globalThis.location = location; - } - - disconnectedCallback() { - this.windowControllers.abort(); - super.disconnectedCallback(); - } - - constructor() { - super(); - this.unlockComingSoon = false; - this.unlockTerrible = false; - this.t = this.t || {}; - - this.t = { - ...this.t, - selectPage: "Select page", - backToSiteList: "Back to site list", - listMySites: "List my sites", - cancel: "Cancel", - editDetails: "Page details", - add: "Add", - editSettings: "Edit settings", - source: "Source", - viewSource: "View source", - findMedia: "Find media", - undo: "Undo", - redo: "Redo", - media: "Media", - outline: "Outline", - blocks: "Blocks", - addBlock: "Add block", - addPage: "Add page", - addChildPage: "Add child page", - clonePage: "Clone page", - delete: "Delete page", - siteSettings: "Site settings", - close: "Close", - settings: "Settings", - edit: "Edit", - configureBlock: "Configure block", - configure: "Configure", - save: "Save", - home: "Home", - startNewJourney: "Start new journey", - newJourney: "New Journey", - accountInfo: "Account Info", - outlineDesigner: "Outline designer", - pageOutline: "Page outline", - more: "More", - siteActions: "Site actions", - insights: "Insights dashboard", - merlin: "Merlin", - summonMerlin: "Summon Merlin", - logOut: "Log out", - menu: "Menu", - showMore: "More", - }; - if ( - typeof globalThis.speechSynthesis !== "undefined" && - (globalThis.SpeechRecognition || - globalThis.webkitSpeechRecognition || - globalThis.mozSpeechRecognition || - globalThis.msSpeechRecognition || - globalThis.oSpeechRecognition) - ) { - SuperDaemonInstance.voiceSearch = true; - } - SuperDaemonInstance.icon = "hax:wizard-hat"; - SuperDaemonInstance.appendContext("*"); - // ensure we are running HAX / ready and in edit mode before allowing commands to go through - SuperDaemonInstance.allowedCallback = () => { - if (toJS(store.appReady) && toJS(store.isLoggedIn)) { - return true; - } - return false; - }; - - // contribution helpers - SuperDaemonInstance.defineOption({ - title: "Tour of top menu buttons", - icon: "help", - tags: ["Help", "ui", "tour"], - priority: -1000, - value: { - target: this, - method: "helpClick", - args: [], - }, - eventName: "super-daemon-element-method", - path: "HAX/app/tour", - context: ["*"], - }); - - // contribution helpers - SuperDaemonInstance.defineOption({ - title: "Unlock hidden features", - icon: "hax:hax2022", - tags: ["Developer", "features", "hidden"], - value: { - target: this, - method: "fireUnlocked", - args: [], - }, - eventName: "super-daemon-element-method", - path: ">developer/hax/unlockAll", - context: [">"], - }); - // contribution helpers - SuperDaemonInstance.defineOption({ - title: "Unlock terrible 2000s themes", - icon: "hax:table-multiple", - tags: ["Developer", "terrible", "2000", "tables"], - value: { - target: this, - method: "fireTerrible", - args: [], - }, - eventName: "super-daemon-element-method", - path: ">developer/hax/terrible2000s", - context: [">"], - }); - SuperDaemonInstance.defineOption({ - title: "Go to site", - icon: "hax:hax2022", - tags: ["Sites", "Administration", "change"], - eventName: "super-daemon-run-program", - path: "HAX/action/goToSite", - value: { - name: "Go to site", - program: async (input, values) => { - let results = []; - const items = toJS(store.manifest.items); - items.forEach(async (site) => { - if ( - input == "" || - (site.metadata.site && - site.metadata.site.name && - site.metadata.site.name.includes(input)) - ) { - results.push({ - title: site.title, - icon: - site.metadata.theme && - site.metadata.theme.variables && - site.metadata.theme.variables.icon - ? site.metadata.theme.variables.icon - : "hax:hax2022", - tags: ["site", site.description], - value: { - target: this, - method: "goToLocation", - args: [site.slug], - }, - eventName: "super-daemon-element-method", - context: [ - "*", - "HAX/action/goToSite/" + site.metadata.site.name, - ], - path: "HAX/action/goToSite/" + site.metadata.site.name, - }); - } - }); - return results; - }, - }, - context: ["*"], - }); - // contribution helpers - SuperDaemonInstance.defineOption({ - title: "Join our Community", - icon: "hax:discord", - priority: -100, - tags: ["community", "discord", "chat", "help"], - value: { - target: this, - method: "_openExternalLink", - args: ["https://bit.ly/hax-discord"], - }, - eventName: "super-daemon-element-method", - path: "HAX/community/join", - context: ["logged-in", "CMS", "HAX", "*"], - }); - SuperDaemonInstance.defineOption({ - title: "User Tutorials", - icon: "hax:hax2022", - priority: -1000, - tags: ["Documentation", "community", "help"], - value: { - target: this, - method: "_openExternalLink", - args: ["https://haxtheweb.org/tutorials"], - }, - eventName: "super-daemon-element-method", - path: "HAX/community/tutorials", - context: ["logged-in", "CMS", "HAX", "*"], - }); - SuperDaemonInstance.defineOption({ - title: "User Documentation", - icon: "hax:hax2022", - tags: ["Documentation", "community", "help"], - value: { - target: this, - method: "_openExternalLink", - args: ["https://haxtheweb.org/documentation"], - }, - eventName: "super-daemon-element-method", - path: "HAX/community/documentation", - context: ["logged-in", "CMS", "HAX", "*"], - }); - SuperDaemonInstance.defineOption({ - title: "HAX Teaching Excellence", - icon: "hax:hax2022", - tags: ["Ontology", "community", "pedagogy", "documentation", "help"], - value: { - target: this, - method: "_openExternalLink", - args: ["https://haxtheweb.org/ontology"], - }, - eventName: "super-daemon-element-method", - path: "HAX/community/pedagogy", - context: ["logged-in", "CMS", "HAX", "*"], - }); - SuperDaemonInstance.defineOption({ - title: "Bug / issue", - icon: "mdi-social:github-circle", - tags: ["Bug report", "github", "git", "community", "issue queue"], - value: { - target: this, - method: "_haxStoreContribute", - args: ["bug", "POP,bug"], - }, - eventName: "super-daemon-element-method", - path: "HAX/community/contribute", - context: ["logged-in", "CMS", "HAX", "*"], - }); - SuperDaemonInstance.defineOption({ - title: "Idea / Feature request", - icon: "mdi-social:github-circle", - tags: [ - "Feature request", - "idea", - "github", - "git", - "community", - "issue queue", - ], - value: { - target: this, - method: "_haxStoreContribute", - args: ["feature", "POP,enhancement"], - }, - context: ["logged-in", "CMS", "HAX", "*"], - eventName: "super-daemon-element-method", - path: "HAX/community/contribute", - }); - this.windowControllers = new AbortController(); - this.__tour = SimpleTourManager; - this.__tour.registerNewTour({ - key: "hax", - name: "HAX top menu", - style: ` - simple-popover-manager::part(simple-popover) { - max-width: 250px; - font-family: sans-serif; - } - simple-popover-manager button { - font-family: sans-serif; - font-size: 12px; - margin: 0px 2px; - color: var(--simple-colors-default-theme-grey-12); - } - simple-popover-manager p { - font-family: sans-serif; - padding: 0; - margin: 0; - width: 250px; - font-size: 10px; - line-height: 20px; - } - simple-popover-manager h1 { - font-family: sans-serif; - margin: 0; - font-size: 12px; - width: 250px; - padding: 0; - } - simple-popover-manager::part(simple-popover-body), - simple-popover-manager::part(simple-popover-heading) { - color: black; - background-color: white; - font-family: sans-serif; - } - body.dark-mode simple-popover-manager::part(simple-popover-body), - body.dark-mode simple-popover-manager::part(simple-popover-heading) { - color: white; - background-color: black; - font-family: sans-serif; - } - body.dark-mode simple-popover-manager simple-icon-button-lite { - color: white; - background-color: black; - font-family: sans-serif; - } - `, - }); - this.tourName = "hax"; - // manage title when activeItem changes - autorun(() => { - const item = toJS(store.activeItem); - if (item && item.title) { - store.setPageTitle(item.title); - } - }); - autorun(() => { - this.siteReady = toJS(store.siteReady); - }); - autorun(() => { - const badDevice = toJS(store.badDevice); - if (badDevice === false) { - import("@haxtheweb/rpg-character/rpg-character.js"); - } else if (badDevice === true) { - globalThis.document.body.classList.add("bad-device"); - } - }); - this.userMenuOpen = false; - this.courses = []; - this.activeItem = {}; - this.phrases = { - new: [ - "What's ya name?", - "HAX to the moon", - "Welcome to the Jungle", - "We like to party", - "Build something awesome", - "Everything is awesome!", - "Everything is cool", - "When you're part of the team", - "When you're living our dream", - "Welcome to the up-side-down", - ], - return: [ - "Welcome back, take 2?", - "That wasn't very long", - "Stranger thiings have happened", - "Student driven platform", - "Faculty centered platform", - "Instructional designer influenced platform", - "Free, Open, Community driven", - "One brick at a time..", - "Sup?", - "You again? Awesome!", - "Let's do this", - "There can only be one ring...", - "There is another", - "Fancy that, I love HAX and you show up", - ], - }; - this.isNewUser = null; - this.basePath = "/"; - this.searchTerm = ""; - this.appMode = ""; - this.soundIcon = ""; - // full on store that does the heavy lifting - this.store = store; - // centralized sound source to not flood sounds when playing - this.sound = new Audio(); - // @todo need this from app deploy itself - autorun(() => { - this.isNewUser = toJS(store.isNewUser); - if ( - this.isNewUser && - toJS(store.appMode) !== "create" && - toJS(store.appMode) !== "404" - ) { - store.appMode = "create"; - setTimeout(() => { - store.createSiteSteps = true; - }, 0); - } - }); - autorun(() => { - this.userName = toJS(store.user.name); - }); - autorun(() => { - this.appMode = toJS(store.appMode); - }); - autorun(() => { - this.searchTerm = toJS(store.searchTerm); - }); - - /** - * When location changes update activeItem / mode of app - */ - autorun(async () => { - const location = toJS(store.location); - if (location && location.route) { - // verify this is a step vs other operations - if (!location.route.step) { - // support external site links - if (location.route.slug) { - this.reset(); - setTimeout(() => { - globalThis.location = location.route.slug; - }, 0); - } - // page miss is high check too - else if (location.route.name === "404") { - store.createSiteSteps = false; - store.appMode = "404"; - setTimeout(() => { - store.toast("the page miss.. it burns!!!", 3000, { - fire: true, - walking: true, - }); - }, 500); - } - // then home / landing page which is default expectation - else if ( - location.route.name === "home" || - location.route.name === "search" - ) { - store.appMode = "home"; - store.createSiteSteps = false; - } else { - //console.warn(location.route); - } - } else { - // we have a "step" based operation - store.appMode = "create"; - store.createSiteSteps = true; - } - } - }); - - autorun(() => { - if (store.routes.length > 0 && store.location === null) { - store.location = toJS(store.routes[0]); - } - }); - // manage dark mode - // only set this initially if we don't have an app state of our own - if (localStorageGet("app-hax-darkMode", null) === null) { - store.darkMode = globalThis.matchMedia( - "(prefers-color-scheme: dark)", - ).matches; - } - autorun(() => { - localStorageSet("app-hax-darkMode", toJS(store.darkMode)); - requestAnimationFrame(() => { - if (toJS(store.darkMode)) { - globalThis.document.body.classList.add("dark-mode"); - store.toast("I'm ascared of the dark", 2000, { fire: true }); - this.dark = true; - SuperDaemonInstance.dark = true; - SuperDaemonInstance.toastInstance.darkMode = true; - } else { - globalThis.document.body.classList.remove("dark-mode"); - store.toast("Sunny day it is", 2000, { hat: "random" }); - this.dark = false; - SuperDaemonInstance.dark = false; - SuperDaemonInstance.toastInstance.darkMode = false; - } - }); - }); - autorun(() => { - const mode = toJS(store.appMode); - if (mode) { - globalThis.document.body.classList.remove("app-hax-search"); - globalThis.document.body.classList.remove("app-hax-create"); - globalThis.document.body.classList.remove("app-hax-404"); - globalThis.document.body.classList.remove("app-hax-home"); - globalThis.document.body.classList.add(`app-hax-${mode}`); - } - }); - } - - static get properties() { - return { - ...super.properties, - unlockComingSoon: { type: Boolean }, - unlockTerrible: { type: Boolean }, - courses: { type: Array }, - userName: { type: String }, - activeItem: { type: Object }, - soundIcon: { type: String }, - searchTerm: { type: String }, - appMode: { type: String }, // minor context of what we're doing in the app for rendering - isNewUser: { type: Boolean }, - phrases: { type: Object }, - userMenuOpen: { type: Boolean }, // leave here to ensure hat change and sound effects happen - siteReady: { type: Boolean }, - basePath: { type: String, attribute: "base-path" }, - token: { type: String }, - }; - } - - // eslint-disable-next-line class-methods-use-this - reset(reload = false) { - // localStorage possible to be blocked by permission of system - try { - globalThis.localStorage.removeItem("app-hax-step"); - globalThis.localStorage.removeItem("app-hax-site"); - if (reload) { - // should always be a base tag for a SPA but just checking - if (document.querySelector("base")) { - globalThis.location = globalThis.document.querySelector("base").href; - } else { - globalThis.location.reload(); - } - } - } catch (e) { - //console.warn(e); - } - } - fireTerrible() { - this.unlockTerrible = true; - store.appEl.playSound("coin").then(() => { - store.appEl.playSound("coin2").then(() => { - store.appEl.playSound("success").then(() => { - SuperDaemonInstance.merlinSpeak( - "Enjoy these early 2000s table based layouts. May they remind you how never to web, again.", - ); - }); - }); - }); - } - fireUnlocked() { - this.unlockComingSoon = true; - store.appEl.playSound("coin").then(() => { - store.appEl.playSound("coin2").then(() => { - store.appEl.playSound("success").then(() => { - SuperDaemonInstance.merlinSpeak( - "Unbelievable! You, (Subject Name), must be the pride of (Subject Hometown). Enjoy all locked features as a boon!", - ); - }); - }); - }); - } - // eslint-disable-next-line class-methods-use-this - logout() { - globalThis.dispatchEvent( - new CustomEvent("jwt-login-logout", { - composed: true, - bubbles: true, - cancelable: false, - detail: true, - }), - ); - this.closeMenu(); - this.__logoutUserAction = true; - } - // only care about logouts - _jwtLoggedIn(e) { - if (e.detail === false && this.__logoutUserAction) { - this.__logoutUserAction = false; - setTimeout(() => { - this.reset(true); - }, 100); - } - } - - // eslint-disable-next-line class-methods-use-this - login() { - import("./lib/v2/app-hax-site-login.js").then(() => { - const p = globalThis.document.createElement("app-hax-site-login"); - if (this.querySelector('[slot="externalproviders"]')) { - const cloneSlot = this.querySelector( - '[slot="externalproviders"]', - ).cloneNode(true); - p.appendChild(cloneSlot); - } - import("@haxtheweb/simple-modal/simple-modal.js").then(() => { - setTimeout(() => { - this.dispatchEvent( - new CustomEvent("simple-modal-show", { - bubbles: true, - cancelable: true, - composed: true, - detail: { - title: "< login >", - elements: { content: p }, - modal: true, - styles: { - "--simple-modal-titlebar-background": "transparent", - "--simple-modal-titlebar-color": "black", - "--simple-modal-width": "40vw", - "--simple-modal-min-width": "300px", - "--simple-modal-z-index": "100000000", - "--simple-modal-height": "62vh", - "--simple-modal-min-height": "400px", - "--simple-modal-titlebar-height": "64px", - }, - }, - }), - ); - }, 0); - }); - }); - } - - static get styles() { - return [ - super.styles, - css` - :host { - display: block; - --app-hax-background-color-active: var(--app-hax-accent-color); - } - #home { - display: inline-flex; - } - #wt { - border: solid 1px var(--simple-colors-default-theme-accent-12, var(--accent-color)); - } - simple-toolbar-button { - min-width: 48px; - margin: 0; - --simple-toolbar-border-color: #dddddddd; - height: 48px; - --simple-toolbar-button-disabled-border-color: transparent; - --simple-toolbar-button-disabled-opacity: 0.3; - --simple-toolbar-button-padding: 3px 6px; - --simple-toolbar-border-radius: 0; - } - simple-toolbar-button:hover, - simple-toolbar-button:active, - simple-toolbar-button:focus { - background-color: var(--hax-ui-background-color-accent); - color: var(--hax-ui-color); - } - simple-toolbar-button:hover, - simple-toolbar-button:active, - simple-toolbar-button:focus { - --simple-toolbar-border-color: var(--hax-ui-color-accent); - } - .wired-button-label { - clip: rect(0 0 0 0); - clip-path: inset(50%); - height: 1px; - overflow: hidden; - position: absolute; - white-space: nowrap; - width: 1px; - } - .topbar-character { - cursor: pointer; - display: inline-block; - border: none; - border-radius: 0px; - padding: 0 8px; - margin: 0 0 0 16px; - background-color: transparent; - height: 48px; - max-width: 160px; - } - .characterbtn-name { - color: var(--simple-colors-default-theme-grey-12); - font-family: "Press Start 2P", sans-serif; - margin-left: 8px; - font-size: 12px; - vertical-align: bottom; - line-height: 48px; - overflow: hidden; - text-overflow: ellipsis; - height: 48px; - word-break: break-all; - } - .topbar-character:hover, - .topbar-character:focus { - background-color: var(--simple-colors-default-theme-light-blue-4); - outline: var(--haxcms-color) solid 3px; - outline-offset: -3px; - height: 48px; - } - .topbar-character rpg-character { - margin: -4px -14px 0px -10px; - height: 52px; - width: 64px; - display: inline-block; - } - .content { - text-align: center; - margin-top: 24px; - } - .four04-character { - margin-top: 16px; - } - .start-journey { - display: flex; - padding-top: 20px; - justify-content: center; - } - app-hax-site-button { - max-width: 60vw; - justify-content: center; - } - app-hax-top-bar { - top: 0; - z-index: 1000; - right: 0; - left: 0; - position: fixed; - } - @media (max-width: 640px) { - simple-tooltip { - --simple-tooltip-font-size: 10px; - } - } - .label { - display: inline-flex; - text-align: flex-start; - align-items: center; - } - app-hax-label { - animation: 0.8s ease-in-out 0s scrollin; - -webkit-animation: 0.8s ease-in-out 0s scrollin; - display: flex; - align-self: flex-start; - overflow: hidden; - margin-left: 24px; - margin-right: 24px; - } - app-hax-label h1 { - font-weight: normal; - font-size: 4vw; - margin: 0; - padding: 0; - } - @keyframes scrollin { - from { - margin-top: -240px; - margin-bottom: 240px; - } - to { - margin-top: 0; - margin-bottom: 0; - } - } - .haxLogo { - --simple-icon-height: 40px; - --simple-icon-width: 40px; - margin: 4px; - color: var(--simple-colors-default-theme-grey-12); - cursor: pointer; - } - .soundToggle { - margin-right: 16px; - position: relative; - display: inline-flex; - vertical-align: top; - } - - .soundToggle img { - width: 24px; - height: 24px; - } - - app-hax-search-bar { - display: inline-flex; - } - main { - padding-top: 80px; - } - @media (max-width: 900px) { - .characterbtn-name { - display: none; - } - main { - padding-top: 64px; - } - } - app-hax-user-menu { - z-index: 1003; - } - .logout::part(menu-button) { - background-image: url("${unsafeCSS(logoutBtn)}"); - background-repeat: no-repeat; - background-position: center; - text-align: center; - background-size: cover; - border-top: 0px; - border-bottom: 0px; - padding: 10px; - } - app-hax-user-menu app-hax-user-menu-button::part(menu-button) { - font-family: "Press Start 2P", sans-serif; - font-size: 12px; - } - #helpbtn { - --simple-icon-height: 50px; - --simple-icon-width: 50px; - right: 200px; - top: 100px; - padding: 4px; - background-color: var(--simple-colors-default-theme-grey-1); - border-radius: 50%; - position: absolute; - color: var(--simple-colors-default-theme-grey-12); - border: var(--simple-colors-default-theme-grey-12) 4px solid; - cursor: pointer; - } - @media (max-width: 800px) { - app-hax-site-button { - width: 320px; - max-width: 60vw; - --app-hax-site-button-font-size: 16px; - } - #helpbtn { - --simple-icon-height: 40px; - --simple-icon-width: 40px; - right: 8px; - top: 64px; - padding: 2px; - border: var(--simple-colors-default-theme-grey-12) 2px solid; - } - } - @media (prefers-reduced-motion: reduce) { - app-hax-label { - animation: none; - -webkit-animation: none; - } - } - @media (max-width: 640px) { - .content { - margin-top: 4px; - } - .start-journey { - padding-top: 0; - } - - app-hax-site-button { - --app-hax-site-button-font-size: 12px; - } - } - @media (max-height: 500px) { - app-hax-label h1 { - font-family: monospace; - font-weight: normal; - font-size: 4vw; - margin: 0; - padding: 0; - } - } - `, - ]; - } - helpClick() { - // start the tour - store.appEl.playSound("coin2"); - this.__tour.startTour("hax"); - } - - updated(changedProperties) { - if (super.updated) { - super.updated(changedProperties); - } - // update the store as these get set via entrypoint of the app - // but used downstream in calls - changedProperties.forEach((oldValue, propName) => { - // API backend broker settings - if (["basePath"].includes(propName) && this[propName]) { - store.AppHaxAPI[propName] = this[propName]; - } - // settings for the store itself - if (["token"].includes(propName) && this[propName]) { - store[propName] = this[propName]; - } - }); - } - - firstUpdated(changedProperties) { - if (super.firstUpdated) { - super.firstUpdated(changedProperties); - } - // required for our early siteList updating - if (store.AppHaxAPI && this.basePath) { - store.AppHaxAPI.basePath = this.basePath; - } - import("./lib/v2/app-hax-steps.js"); - import("./lib/v2/app-hax-site-button.js"); - import("wired-elements/lib/wired-button.js"); - import("./lib/v2/app-hax-toast.js"); - import("./lib/v2/app-hax-wired-toggle.js"); - import("./lib/v2/app-hax-search-bar.js"); - import("./lib/v2/app-hax-search-results.js"); - import("./lib/v2/app-hax-user-menu.js"); - import("./lib/v2/app-hax-user-menu-button.js"); - this.dispatchEvent( - new CustomEvent("app-hax-loaded", { - composed: true, - bubbles: true, - cancelable: false, - detail: true, - }), - ); - store.appReady = true; - autorun(() => { - if (toJS(store.appReady)) { - globalThis.document.body.classList.add("app-loaded"); - } else { - globalThis.document.body.classList.remove("app-loaded"); - } - }); - store.appEl = this; - autorun(() => { - if (store.activeItem) { - this.activeItem = toJS(store.activeItem); - } - }); - autorun(() => { - this.soundIcon = toJS(store.soundStatus) - ? new URL("./lib/assets/images/FullVolume.svg", import.meta.url).href - : new URL("./lib/assets/images/Silence.svg", import.meta.url).href; - if (!toJS(store.soundStatus)) { - store.toast("Sound off.. hey! HELLO!?!", 2000, { fire: true }); - } else { - store.toast("You can hear me now? Good.", 2000, { hat: "random" }); - } - }); - // App is ready and the user is Logged in - autorun(async () => { - if ( - toJS(store.appReady) && - store.AppHaxAPI && - toJS(store.isLoggedIn) && - toJS(store.appSettings) && - toJS(store.refreshSiteList) - ) { - // Need this for the auto run when testing new user - // if we get new data source, trigger a rebuild of the site list - const results = await AppHaxAPI.makeCall("getSitesList"); - store.manifest = results.data; - } else if (toJS(store.appReady) && !toJS(store.isLoggedIn)) { - this.login(); - } - }); - } - - toggleMenu() { - this.userMenuOpen = !this.userMenuOpen; - store.appEl.playSound("click"); - } - - closeMenu() { - this.userMenuOpen = false; - } - - openMerlin() { - store.appEl.playSound("click"); - SuperDaemonInstance.open(); - } - - render() { - return html` -
    - - - - - - ${this.t.home} - - - Toggle sound effects - - -
    - Not a fan of the (awesome) sound effects? You can mute them if you - prefer. -
    -
    - Toggle sound - - Toggle dark mode - -
    - You want to log out and be someone else? Create a new site? Click - your character. Your character is unique to you! -
    - - - - - - - - - -
    -
    -
    -
    - -
    - - ${this.activeItem && !this.siteReady - ? html` -

    ${this.activeItem.label}

    -
    - ${this.activeItem && this.activeItem.statement - ? this.activeItem.statement.replace( - ":structure", - toJS(store.site.structure), - ) - : ""} -
    - ` - : ``} - ${this.activeItem && this.siteReady - ? html` -

    ${toJS(store.site.name)}

    -
    - Is all ready, are you ready to build? -
    - ` - : ``} -
    -
    - -
    ${this.appBody(this.appMode)}
    -
    -
    `; - } - - appBody(routine) { - let template = html``; - switch (routine) { - case "home": - case "search": - template = this.templateHome(); - break; - case "create": - template = this.templateCreate(); - break; - case "404": - default: - template = this.template404(); - break; - } - return template; - } - - //EDIT HERE - templateHome() { - return html` -
    - -
    - - `; - } - - // eslint-disable-next-line class-methods-use-this - templateCreate() { - return html``; - } - - siteReadyToGo(e) { - import("@haxtheweb/multiple-choice/lib/confetti-container.js").then( - (module) => { - setTimeout(() => { - this.shadowRoot.querySelector("#confetti").setAttribute("popped", ""); - }, 0); - }, - ); - if (e.detail) { - store.siteReady = true; - } - } - - template404() { - return html`
    - - - - - This - fine - is -
    `; - } - - // ensure internal data is unset for store - startJourney() { - this.userMenuOpen = false; - store.createSiteSteps = false; - store.siteReady = false; - store.site.structure = null; - store.site.type = null; - store.site.theme = null; - store.site.name = null; - store.appMode = "create"; - store.appEl.playSound("click2"); - } -} -customElements.define(AppHax.tag, AppHax); - -globalThis.AppHax = globalThis.AppHax || {}; - -globalThis.AppHax.requestAvailability = () => { - if (!globalThis.AppHax.instance && globalThis.document) { - globalThis.AppHax.instance = globalThis.document.querySelector(AppHax.tag); - } - return globalThis.AppHax.instance; -}; \ No newline at end of file diff --git a/elements/app-hax/test-use-cases/app-hax-copy.js b/elements/app-hax/test-use-cases/app-hax-copy.js deleted file mode 100644 index 6e2cee568e..0000000000 --- a/elements/app-hax/test-use-cases/app-hax-copy.js +++ /dev/null @@ -1,1412 +0,0 @@ -import { css, html, unsafeCSS } from "lit"; -import { toJS, autorun } from "mobx"; -import { localStorageSet, localStorageGet } from "@haxtheweb/utils/utils.js"; -import "@haxtheweb/simple-tooltip/simple-tooltip.js"; -import { SimpleColors } from "@haxtheweb/simple-colors/simple-colors.js"; -import { store } from "./lib/v2/AppHaxStore.js"; -import { I18NMixin } from "@haxtheweb/i18n-manager/lib/I18NMixin.js"; -import { AppHaxAPI } from "./lib/v2/AppHaxBackendAPI.js"; -import { SimpleTourManager } from "@haxtheweb/simple-popover/lib/simple-tour.js"; -import { SuperDaemonInstance } from "@haxtheweb/super-daemon/super-daemon.js"; -import "@haxtheweb/simple-toolbar/lib/simple-toolbar-button.js"; -import "@haxtheweb/simple-colors-shared-styles/simple-colors-shared-styles.js"; -import "./lib/v2/AppHaxRouter.js"; -import "./lib/v2/app-hax-label.js"; -import "./lib/v2/app-hax-top-bar.js"; -import { SimpleTourFinder } from "@haxtheweb/simple-popover/lib/SimpleTourFinder.js"; - -const logoutBtn = new URL("./lib/assets/images/Logout.svg", import.meta.url) - .href; -// toggle store darkmode -function darkToggle(e) { - if (e.matches) { - // dark mode - store.darkMode = true; - } else { - // light mode - store.darkMode = false; - } -} - -function soundToggle() { - store.soundStatus = !toJS(store.soundStatus); - localStorageSet("app-hax-soundStatus", toJS(store.soundStatus)); - store.appEl.playSound("click"); -} - -export class AppHax extends I18NMixin(SimpleTourFinder(SimpleColors)) { - static get tag() { - return "app-hax"; - } - - _openExternalLink(link) { - globalThis.open(link, "_blank"); - } - - async _haxStoreContribute(type, tags, daemonTerm = null) { - let body = ""; - if (type == "merlin") { - var title = `[${type}] New command request from HAX daemon`; - body = `Location: ${globalThis.location.href} -Merlin command: ${daemonTerm} -What did you want merlin to do? -`; - } else { - var title = `[${type}] User report from HAX daemon`; - body = `Location: ${globalThis.location.href} -Browser: ${navigator.userAgent} -OS: ${navigator.userAgentData.platform} - ${navigator.deviceMemory}GB RAM - ${navigator.hardwareConcurrency} cores -Screen: ${globalThis.screen.width}x${globalThis.screen.height} -Window size: ${globalThis.innerWidth}x${globalThis.innerHeight} -`; - if (navigator.getBattery) { - const stats = await globalThis.navigator.getBattery(); - body += `Battery: ${stats.level * 100}% -`; - } - // some things report the "type" of internet connection speed - // for terrible connections lets save frustration - if ( - navigator.connection && - globalThis.navigator.connection.effectiveType - ) { - body += `Connection: ${navigator.connection.effectiveType} -`; - } - body += `${type == "feature" ? `Your idea:` : `Bug you experienced:`} -`; - } - globalThis.open( - `https://github.com/haxtheweb/issues/issues/new?assignees=&labels=${tags}&template=issue-report.md&title=${title}&body=${encodeURIComponent( - body, - )}`, - "_blank", - ); - } - // eslint-disable-next-line class-methods-use-this - playSound(sound = "coin2") { - return new Promise((resolve) => { - if (store.soundStatus && store.appReady) { - let playSound = [ - "click", - "click2", - "coin", - "coin2", - "hit", - "success", - ].includes(sound) - ? sound - : "hit"; - this.audio = new Audio( - new URL(`./lib/assets/sounds/${playSound}.mp3`, import.meta.url).href, - ); - this.audio.volume = 0.3; - this.audio.onended = (event) => { - resolve(); - }; - this.audio.play(); - // resolve after 1s if sound failed to load - setTimeout(() => { - resolve(); - }, 1000); - } else { - resolve(); - } - }); - } - - /** - * A token refresh just failed so force to login prompt / state - */ - _tokenRefreshFailed(e) { - globalThis.dispatchEvent( - new CustomEvent("jwt-login-logout", { - composed: true, - bubbles: true, - cancelable: false, - detail: true, - }), - ); - setTimeout(() => { - this.reset(true); - }, 100); - } - - connectedCallback() { - super.connectedCallback(); - globalThis - .matchMedia("(prefers-color-scheme: dark)") - .addEventListener("change", darkToggle, { - signal: this.windowControllers.signal, - }); - globalThis.addEventListener("jwt-logged-in", this._jwtLoggedIn.bind(this), { - signal: this.windowControllers.signal, - }); - - globalThis.addEventListener( - "jwt-login-refresh-error", - this._tokenRefreshFailed.bind(this), - { signal: this.windowControllers.signal }, - ); - } - - goToLocation(location) { - globalThis.location = location; - } - - disconnectedCallback() { - this.windowControllers.abort(); - super.disconnectedCallback(); - } - - constructor() { - super(); - this.unlockComingSoon = false; - this.unlockTerrible = false; - this.t = this.t || {}; - - this.t = { - ...this.t, - selectPage: "Select page", - backToSiteList: "Back to site list", - listMySites: "List my sites", - cancel: "Cancel", - editDetails: "Page details", - add: "Add", - editSettings: "Edit settings", - source: "Source", - viewSource: "View source", - findMedia: "Find media", - undo: "Undo", - redo: "Redo", - media: "Media", - outline: "Outline", - blocks: "Blocks", - addBlock: "Add block", - addPage: "Add page", - addChildPage: "Add child page", - clonePage: "Clone page", - delete: "Delete page", - siteSettings: "Site settings", - close: "Close", - settings: "Settings", - edit: "Edit", - configureBlock: "Configure block", - configure: "Configure", - save: "Save", - home: "Home", - startNewJourney: "Start new journey", - newJourney: "New Journey", - accountInfo: "Account Info", - outlineDesigner: "Outline designer", - pageOutline: "Page outline", - more: "More", - siteActions: "Site actions", - insights: "Insights dashboard", - merlin: "Merlin", - summonMerlin: "Summon Merlin", - logOut: "Log out", - menu: "Menu", - showMore: "More", - }; - if ( - typeof globalThis.speechSynthesis !== "undefined" && - (globalThis.SpeechRecognition || - globalThis.webkitSpeechRecognition || - globalThis.mozSpeechRecognition || - globalThis.msSpeechRecognition || - globalThis.oSpeechRecognition) - ) { - SuperDaemonInstance.voiceSearch = true; - } - SuperDaemonInstance.icon = "hax:wizard-hat"; - SuperDaemonInstance.appendContext("*"); - // ensure we are running HAX / ready and in edit mode before allowing commands to go through - SuperDaemonInstance.allowedCallback = () => { - if (toJS(store.appReady) && toJS(store.isLoggedIn)) { - return true; - } - return false; - }; - - // contribution helpers - SuperDaemonInstance.defineOption({ - title: "Tour of top menu buttons", - icon: "help", - tags: ["Help", "ui", "tour"], - priority: -1000, - value: { - target: this, - method: "helpClick", - args: [], - }, - eventName: "super-daemon-element-method", - path: "HAX/app/tour", - context: ["*"], - }); - - // contribution helpers - SuperDaemonInstance.defineOption({ - title: "Unlock hidden features", - icon: "hax:hax2022", - tags: ["Developer", "features", "hidden"], - value: { - target: this, - method: "fireUnlocked", - args: [], - }, - eventName: "super-daemon-element-method", - path: ">developer/hax/unlockAll", - context: [">"], - }); - // contribution helpers - SuperDaemonInstance.defineOption({ - title: "Unlock terrible 2000s themes", - icon: "hax:table-multiple", - tags: ["Developer", "terrible", "2000", "tables"], - value: { - target: this, - method: "fireTerrible", - args: [], - }, - eventName: "super-daemon-element-method", - path: ">developer/hax/terrible2000s", - context: [">"], - }); - SuperDaemonInstance.defineOption({ - title: "Go to site", - icon: "hax:hax2022", - tags: ["Sites", "Administration", "change"], - eventName: "super-daemon-run-program", - path: "HAX/action/goToSite", - value: { - name: "Go to site", - program: async (input, values) => { - let results = []; - const items = toJS(store.manifest.items); - items.forEach(async (site) => { - if ( - input == "" || - (site.metadata.site && - site.metadata.site.name && - site.metadata.site.name.includes(input)) - ) { - results.push({ - title: site.title, - icon: - site.metadata.theme && - site.metadata.theme.variables && - site.metadata.theme.variables.icon - ? site.metadata.theme.variables.icon - : "hax:hax2022", - tags: ["site", site.description], - value: { - target: this, - method: "goToLocation", - args: [site.slug], - }, - eventName: "super-daemon-element-method", - context: [ - "*", - "HAX/action/goToSite/" + site.metadata.site.name, - ], - path: "HAX/action/goToSite/" + site.metadata.site.name, - }); - } - }); - return results; - }, - }, - context: ["*"], - }); - // contribution helpers - SuperDaemonInstance.defineOption({ - title: "Join our Community", - icon: "hax:discord", - priority: -100, - tags: ["community", "discord", "chat", "help"], - value: { - target: this, - method: "_openExternalLink", - args: ["https://bit.ly/hax-discord"], - }, - eventName: "super-daemon-element-method", - path: "HAX/community/join", - context: ["logged-in", "CMS", "HAX", "*"], - }); - SuperDaemonInstance.defineOption({ - title: "User Tutorials", - icon: "hax:hax2022", - priority: -1000, - tags: ["Documentation", "community", "help"], - value: { - target: this, - method: "_openExternalLink", - args: ["https://haxtheweb.org/tutorials"], - }, - eventName: "super-daemon-element-method", - path: "HAX/community/tutorials", - context: ["logged-in", "CMS", "HAX", "*"], - }); - SuperDaemonInstance.defineOption({ - title: "User Documentation", - icon: "hax:hax2022", - tags: ["Documentation", "community", "help"], - value: { - target: this, - method: "_openExternalLink", - args: ["https://haxtheweb.org/documentation"], - }, - eventName: "super-daemon-element-method", - path: "HAX/community/documentation", - context: ["logged-in", "CMS", "HAX", "*"], - }); - SuperDaemonInstance.defineOption({ - title: "HAX Teaching Excellence", - icon: "hax:hax2022", - tags: ["Ontology", "community", "pedagogy", "documentation", "help"], - value: { - target: this, - method: "_openExternalLink", - args: ["https://haxtheweb.org/ontology"], - }, - eventName: "super-daemon-element-method", - path: "HAX/community/pedagogy", - context: ["logged-in", "CMS", "HAX", "*"], - }); - SuperDaemonInstance.defineOption({ - title: "Bug / issue", - icon: "mdi-social:github-circle", - tags: ["Bug report", "github", "git", "community", "issue queue"], - value: { - target: this, - method: "_haxStoreContribute", - args: ["bug", "POP,bug"], - }, - eventName: "super-daemon-element-method", - path: "HAX/community/contribute", - context: ["logged-in", "CMS", "HAX", "*"], - }); - SuperDaemonInstance.defineOption({ - title: "Idea / Feature request", - icon: "mdi-social:github-circle", - tags: [ - "Feature request", - "idea", - "github", - "git", - "community", - "issue queue", - ], - value: { - target: this, - method: "_haxStoreContribute", - args: ["feature", "POP,enhancement"], - }, - context: ["logged-in", "CMS", "HAX", "*"], - eventName: "super-daemon-element-method", - path: "HAX/community/contribute", - }); - this.windowControllers = new AbortController(); - this.__tour = SimpleTourManager; - this.__tour.registerNewTour({ - key: "hax", - name: "HAX top menu", - style: ` - simple-popover-manager::part(simple-popover) { - max-width: 250px; - font-family: sans-serif; - } - simple-popover-manager button { - font-family: sans-serif; - font-size: 12px; - margin: 0px 2px; - color: var(--simple-colors-default-theme-grey-12); - } - simple-popover-manager p { - font-family: sans-serif; - padding: 0; - margin: 0; - width: 250px; - font-size: 10px; - line-height: 20px; - } - simple-popover-manager h1 { - font-family: sans-serif; - margin: 0; - font-size: 12px; - width: 250px; - padding: 0; - } - simple-popover-manager::part(simple-popover-body), - simple-popover-manager::part(simple-popover-heading) { - color: black; - background-color: white; - font-family: sans-serif; - } - body.dark-mode simple-popover-manager::part(simple-popover-body), - body.dark-mode simple-popover-manager::part(simple-popover-heading) { - color: white; - background-color: black; - font-family: sans-serif; - } - body.dark-mode simple-popover-manager simple-icon-button-lite { - color: white; - background-color: black; - font-family: sans-serif; - } - `, - }); - this.tourName = "hax"; - // manage title when activeItem changes - autorun(() => { - const item = toJS(store.activeItem); - if (item && item.title) { - store.setPageTitle(item.title); - } - }); - autorun(() => { - this.siteReady = toJS(store.siteReady); - }); - autorun(() => { - const badDevice = toJS(store.badDevice); - if (badDevice === false) { - import("@haxtheweb/rpg-character/rpg-character.js"); - import("./lib/random-word/random-word.js"); - } else if (badDevice === true) { - globalThis.document.body.classList.add("bad-device"); - } - }); - this.userMenuOpen = false; - this.courses = []; - this.activeItem = {}; - this.phrases = { - new: [ - "What's ya name?", - "HAX to the moon", - "Welcome to the Jungle", - "We like to party", - "Build something awesome", - "Everything is awesome!", - "Everything is cool", - "When you're part of the team", - "When you're living our dream", - "Welcome to the up-side-down", - ], - return: [ - "Welcome back, take 2?", - "That wasn't very long", - "Stranger thiings have happened", - "Student driven platform", - "Faculty centered platform", - "Instructional designer influenced platform", - "Free, Open, Community driven", - "One brick at a time..", - "Sup?", - "You again? Awesome!", - "Let's do this", - "There can only be one ring...", - "There is another", - "Fancy that, I love HAX and you show up", - ], - }; - this.isNewUser = null; - this.basePath = "/"; - this.searchTerm = ""; - this.appMode = ""; - this.soundIcon = ""; - // full on store that does the heavy lifting - this.store = store; - // centralized sound source to not flood sounds when playing - this.sound = new Audio(); - // @todo need this from app deploy itself - autorun(() => { - this.isNewUser = toJS(store.isNewUser); - if ( - this.isNewUser && - toJS(store.appMode) !== "create" && - toJS(store.appMode) !== "404" - ) { - store.appMode = "create"; - setTimeout(() => { - store.createSiteSteps = true; - }, 0); - } - }); - autorun(() => { - this.userName = toJS(store.user.name); - }); - autorun(() => { - this.appMode = toJS(store.appMode); - }); - autorun(() => { - this.searchTerm = toJS(store.searchTerm); - }); - - /** - * When location changes update activeItem / mode of app - */ - autorun(async () => { - const location = toJS(store.location); - if (location && location.route) { - // verify this is a step vs other operations - if (!location.route.step) { - // support external site links - if (location.route.slug) { - this.reset(); - setTimeout(() => { - globalThis.location = location.route.slug; - }, 0); - } - // page miss is high check too - else if (location.route.name === "404") { - store.createSiteSteps = false; - store.appMode = "404"; - setTimeout(() => { - store.toast("the page miss.. it burns!!!", 3000, { - fire: true, - walking: true, - }); - }, 500); - } - // then home / landing page which is default expectation - else if ( - location.route.name === "home" || - location.route.name === "search" - ) { - store.appMode = "home"; - store.createSiteSteps = false; - } else { - //console.warn(location.route); - } - } else { - // we have a "step" based operation - store.appMode = "create"; - store.createSiteSteps = true; - } - } - }); - - autorun(() => { - if (store.routes.length > 0 && store.location === null) { - store.location = toJS(store.routes[0]); - } - }); - // manage dark mode - // only set this initially if we don't have an app state of our own - if (localStorageGet("app-hax-darkMode", null) === null) { - store.darkMode = globalThis.matchMedia( - "(prefers-color-scheme: dark)", - ).matches; - } - autorun(() => { - localStorageSet("app-hax-darkMode", toJS(store.darkMode)); - requestAnimationFrame(() => { - if (toJS(store.darkMode)) { - globalThis.document.body.classList.add("dark-mode"); - store.toast("I'm ascared of the dark", 2000, { fire: true }); - this.dark = true; - SuperDaemonInstance.dark = true; - SuperDaemonInstance.toastInstance.darkMode = true; - } else { - globalThis.document.body.classList.remove("dark-mode"); - store.toast("Sunny day it is", 2000, { hat: "random" }); - this.dark = false; - SuperDaemonInstance.dark = false; - SuperDaemonInstance.toastInstance.darkMode = false; - } - }); - }); - autorun(() => { - const mode = toJS(store.appMode); - if (mode) { - globalThis.document.body.classList.remove("app-hax-search"); - globalThis.document.body.classList.remove("app-hax-create"); - globalThis.document.body.classList.remove("app-hax-404"); - globalThis.document.body.classList.remove("app-hax-home"); - globalThis.document.body.classList.add(`app-hax-${mode}`); - } - }); - } - - static get properties() { - return { - ...super.properties, - unlockComingSoon: { type: Boolean }, - unlockTerrible: { type: Boolean }, - courses: { type: Array }, - userName: { type: String }, - activeItem: { type: Object }, - soundIcon: { type: String }, - searchTerm: { type: String }, - appMode: { type: String }, // minor context of what we're doing in the app for rendering - isNewUser: { type: Boolean }, - phrases: { type: Object }, - userMenuOpen: { type: Boolean }, // leave here to ensure hat change and sound effects happen - siteReady: { type: Boolean }, - basePath: { type: String, attribute: "base-path" }, - token: { type: String }, - }; - } - - // eslint-disable-next-line class-methods-use-this - reset(reload = false) { - // localStorage possible to be blocked by permission of system - try { - globalThis.localStorage.removeItem("app-hax-step"); - globalThis.localStorage.removeItem("app-hax-site"); - if (reload) { - // should always be a base tag for a SPA but just checking - if (document.querySelector("base")) { - globalThis.location = globalThis.document.querySelector("base").href; - } else { - globalThis.location.reload(); - } - } - } catch (e) { - //console.warn(e); - } - } - fireTerrible() { - this.unlockTerrible = true; - store.appEl.playSound("coin").then(() => { - store.appEl.playSound("coin2").then(() => { - store.appEl.playSound("success").then(() => { - SuperDaemonInstance.merlinSpeak( - "Enjoy these early 2000s table based layouts. May they remind you how never to web, again.", - ); - }); - }); - }); - } - fireUnlocked() { - this.unlockComingSoon = true; - store.appEl.playSound("coin").then(() => { - store.appEl.playSound("coin2").then(() => { - store.appEl.playSound("success").then(() => { - SuperDaemonInstance.merlinSpeak( - "Unbelievable! You, (Subject Name), must be the pride of (Subject Hometown). Enjoy all locked features as a boon!", - ); - }); - }); - }); - } - // eslint-disable-next-line class-methods-use-this - logout() { - globalThis.dispatchEvent( - new CustomEvent("jwt-login-logout", { - composed: true, - bubbles: true, - cancelable: false, - detail: true, - }), - ); - this.closeMenu(); - this.__logoutUserAction = true; - } - // only care about logouts - _jwtLoggedIn(e) { - if (e.detail === false && this.__logoutUserAction) { - this.__logoutUserAction = false; - setTimeout(() => { - this.reset(true); - }, 100); - } - } - - // eslint-disable-next-line class-methods-use-this - login() { - import("./lib/2/app-hax-site-login.js").then(() => { - const p = globalThis.document.createElement("app-hax-site-login"); - if (this.querySelector('[slot="externalproviders"]')) { - const cloneSlot = this.querySelector( - '[slot="externalproviders"]', - ).cloneNode(true); - p.appendChild(cloneSlot); - } - import("@haxtheweb/simple-modal/simple-modal.js").then(() => { - setTimeout(() => { - this.dispatchEvent( - new CustomEvent("simple-modal-show", { - bubbles: true, - cancelable: true, - composed: true, - detail: { - title: "< login >", - elements: { content: p }, - modal: true, - styles: { - "--simple-modal-titlebar-background": "transparent", - "--simple-modal-titlebar-color": "black", - "--simple-modal-width": "40vw", - "--simple-modal-min-width": "300px", - "--simple-modal-z-index": "100000000", - "--simple-modal-height": "62vh", - "--simple-modal-min-height": "400px", - "--simple-modal-titlebar-height": "64px", - }, - }, - }), - ); - }, 0); - }); - }); - } - - static get styles() { - return [ - super.styles, - css` - :host { - display: block; - --app-hax-background-color-active: var(--app-hax-accent-color); - } - #home { - display: inline-flex; - } - simple-toolbar-button { - min-width: 48px; - margin: 0; - --simple-toolbar-border-color: #dddddddd; - height: 48px; - --simple-toolbar-button-disabled-border-color: transparent; - --simple-toolbar-button-disabled-opacity: 0.3; - --simple-toolbar-button-padding: 3px 6px; - --simple-toolbar-border-radius: 0; - } - simple-toolbar-button:hover, - simple-toolbar-button:active, - simple-toolbar-button:focus { - background-color: var(--hax-ui-background-color-accent); - color: var(--hax-ui-color); - } - simple-toolbar-button:hover, - simple-toolbar-button:active, - simple-toolbar-button:focus { - --simple-toolbar-border-color: var(--hax-ui-color-accent); - } - .wired-button-label { - clip: rect(0 0 0 0); - clip-path: inset(50%); - height: 1px; - overflow: hidden; - position: absolute; - white-space: nowrap; - width: 1px; - } - .topbar-character { - cursor: pointer; - display: inline-block; - border: none; - border-radius: 0px; - padding: 0 8px; - margin: 0 0 0 16px; - background-color: transparent; - height: 48px; - max-width: 160px; - } - .characterbtn-name { - color: var(--simple-colors-default-theme-grey-12); - font-family: "Press Start 2P", sans-serif; - margin-left: 8px; - font-size: 12px; - vertical-align: bottom; - line-height: 48px; - overflow: hidden; - text-overflow: ellipsis; - height: 48px; - word-break: break-all; - } - .topbar-character:hover, - .topbar-character:focus { - background-color: var(--simple-colors-default-theme-light-blue-4); - outline: var(--haxcms-color) solid 3px; - outline-offset: -3px; - height: 48px; - } - .topbar-character rpg-character { - margin: -4px -14px 0px -10px; - height: 52px; - width: 64px; - display: inline-block; - } - .content { - text-align: center; - margin-top: 24px; - } - .four04-character { - margin-top: 16px; - } - .start-journey { - display: flex; - padding-top: 20px; - justify-content: center; - } - app-hax-site-button { - max-width: 60vw; - justify-content: center; - } - app-hax-top-bar { - top: 0; - z-index: 1000; - right: 0; - left: 0; - position: fixed; - } - @media (max-width: 640px) { - simple-tooltip { - --simple-tooltip-font-size: 10px; - } - } - .label { - text-align: center; - } - app-hax-label { - animation: 0.8s ease-in-out 0s scrollin; - -webkit-animation: 0.8s ease-in-out 0s scrollin; - display: block; - overflow: hidden; - } - app-hax-label h1 { - font-weight: normal; - font-size: 4vw; - margin: 0; - padding: 0; - } - @keyframes scrollin { - from { - margin-top: -240px; - margin-bottom: 240px; - } - to { - margin-top: 0; - margin-bottom: 0; - } - } - .haxLogo { - --simple-icon-height: 40px; - --simple-icon-width: 40px; - margin: 4px; - color: var(--simple-colors-default-theme-grey-12); - cursor: pointer; - } - .soundToggle { - margin-right: 16px; - position: relative; - display: inline-flex; - vertical-align: top; - } - - .soundToggle img { - width: 24px; - height: 24px; - } - - app-hax-search-bar { - display: inline-flex; - } - main { - padding-top: 80px; - } - @media (max-width: 900px) { - .characterbtn-name { - display: none; - } - main { - padding-top: 64px; - } - } - app-hax-user-menu { - z-index: 1003; - } - .logout::part(menu-button) { - background-image: url("${unsafeCSS(logoutBtn)}"); - background-repeat: no-repeat; - background-position: center; - text-align: center; - background-size: cover; - border-top: 0px; - border-bottom: 0px; - padding: 10px; - } - app-hax-user-menu app-hax-user-menu-button::part(menu-button) { - font-family: "Press Start 2P", sans-serif; - font-size: 12px; - } - - random-word:not(:defined) { - display: none; - } - random-word { - transform: rotate(25deg); - position: absolute; - right: 10px; - top: 120px; - padding: 12px; - font-size: 12px; - border: 4px solid var(--simple-colors-default-theme-grey-12); - background-color: var(--simple-colors-default-theme-yellow-5); - color: var(--simple-colors-default-theme-grey-12); - width: 100px; - word-wrap: break-word; - text-align: center; - cursor: pointer; - user-select: none; - opacity: 1; - visibility: visible; - transition: all 0.3s ease-in-out; - } - #helpbtn { - --simple-icon-height: 50px; - --simple-icon-width: 50px; - right: 200px; - top: 100px; - padding: 4px; - background-color: var(--simple-colors-default-theme-grey-1); - border-radius: 50%; - position: absolute; - color: var(--simple-colors-default-theme-grey-12); - border: var(--simple-colors-default-theme-grey-12) 4px solid; - cursor: pointer; - } - @media (max-width: 800px) { - app-hax-site-button { - width: 320px; - max-width: 60vw; - --app-hax-site-button-font-size: 16px; - } - #helpbtn { - --simple-icon-height: 40px; - --simple-icon-width: 40px; - right: 8px; - top: 64px; - padding: 2px; - border: var(--simple-colors-default-theme-grey-12) 2px solid; - } - } - @media (prefers-reduced-motion: reduce) { - app-hax-label { - animation: none; - -webkit-animation: none; - } - } - @media (max-width: 640px) { - random-word { - display: none; - } - .content { - margin-top: 4px; - } - .start-journey { - padding-top: 0; - } - - app-hax-site-button { - --app-hax-site-button-font-size: 12px; - } - } - @media (max-height: 500px) { - app-hax-label h1 { - font-family: monospace; - font-weight: normal; - font-size: 4vw; - margin: 0; - padding: 0; - } - } - `, - ]; - } - helpClick() { - // start the tour - store.appEl.playSound("coin2"); - this.__tour.startTour("hax"); - } - - updated(changedProperties) { - if (super.updated) { - super.updated(changedProperties); - } - // update the store as these get set via entrypoint of the app - // but used downstream in calls - changedProperties.forEach((oldValue, propName) => { - // API backend broker settings - if (["basePath"].includes(propName) && this[propName]) { - store.AppHaxAPI[propName] = this[propName]; - } - // settings for the store itself - if (["token"].includes(propName) && this[propName]) { - store[propName] = this[propName]; - } - }); - } - - firstUpdated(changedProperties) { - if (super.firstUpdated) { - super.firstUpdated(changedProperties); - } - // required for our early siteList updating - if (store.AppHaxAPI && this.basePath) { - store.AppHaxAPI.basePath = this.basePath; - } - import("./lib/v2/app-hax-steps.js"); - import("./lib/v2/app-hax-site-button.js"); - import("wired-elements/lib/wired-button.js"); - import("./lib/v2/app-hax-toast.js"); - import("./lib/v2/app-hax-wired-toggle.js"); - import("./lib/v2/app-hax-search-bar.js"); - import("./lib/v2/app-hax-search-results.js"); - import("./lib/v2/app-hax-user-menu.js"); - import("./lib/v2/app-hax-user-menu-button.js"); - this.dispatchEvent( - new CustomEvent("app-hax-loaded", { - composed: true, - bubbles: true, - cancelable: false, - detail: true, - }), - ); - store.appReady = true; - autorun(() => { - if (toJS(store.appReady)) { - globalThis.document.body.classList.add("app-loaded"); - } else { - globalThis.document.body.classList.remove("app-loaded"); - } - }); - store.appEl = this; - autorun(() => { - if (store.activeItem) { - this.activeItem = toJS(store.activeItem); - } - }); - autorun(() => { - this.soundIcon = toJS(store.soundStatus) - ? new URL("./lib/assets/images/FullVolume.svg", import.meta.url).href - : new URL("./lib/assets/images/Silence.svg", import.meta.url).href; - if (!toJS(store.soundStatus)) { - store.toast("Sound off.. hey! HELLO!?!", 2000, { fire: true }); - } else { - store.toast("You can hear me now? Good.", 2000, { hat: "random" }); - } - }); - // App is ready and the user is Logged in - autorun(async () => { - if ( - toJS(store.appReady) && - store.AppHaxAPI && - toJS(store.isLoggedIn) && - toJS(store.appSettings) && - toJS(store.refreshSiteList) - ) { - // Need this for the auto run when testing new user - // if we get new data source, trigger a rebuild of the site list - const results = await AppHaxAPI.makeCall("getSitesList"); - store.manifest = results.data; - } else if (toJS(store.appReady) && !toJS(store.isLoggedIn)) { - this.login(); - } - }); - } - - toggleMenu() { - this.userMenuOpen = !this.userMenuOpen; - store.appEl.playSound("click"); - } - - closeMenu() { - this.userMenuOpen = false; - } - - openMerlin() { - store.appEl.playSound("click"); - SuperDaemonInstance.open(); - } - - render() { - return html` -
    - - - - - - ${this.t.home} - - - - Toggle sound effects - - -
    - Not a fan of the (awesome) sound effects? You can mute them if you - prefer. -
    -
    - Toggle sound - - Toggle dark mode - -
    - You want to log out and be someone else? Create a new site? Click - your character. Your character is unique to you! -
    - - - - - - - - - -
    -
    -
    -
    - -
    - - ${this.activeItem && !this.siteReady - ? html` -

    ${this.activeItem.label}

    -
    - ${this.activeItem && this.activeItem.statement - ? this.activeItem.statement.replace( - ":structure", - toJS(store.site.structure), - ) - : ""} -
    - ` - : ``} - ${this.activeItem && this.siteReady - ? html` -

    ${toJS(store.site.name)}

    -
    - Is all ready, are you ready to build? -
    - ` - : ``} -
    -
    - -
    ${this.appBody(this.appMode)}
    -
    -
    `; - } - - getNewWord() { - this.shadowRoot.querySelector("random-word").getNewWord(); - store.appEl.playSound("click"); - } - - appBody(routine) { - let template = html``; - switch (routine) { - case "home": - case "search": - template = this.templateHome(); - break; - case "create": - template = this.templateCreate(); - break; - case "404": - default: - template = this.template404(); - break; - } - return template; - } - - templateHome() { - return html`
    - - - -
    - `; - } - - // eslint-disable-next-line class-methods-use-this - templateCreate() { - return html``; - } - - siteReadyToGo(e) { - import("@haxtheweb/multiple-choice/lib/confetti-container.js").then( - (module) => { - setTimeout(() => { - this.shadowRoot.querySelector("#confetti").setAttribute("popped", ""); - }, 0); - }, - ); - if (e.detail) { - store.siteReady = true; - } - } - - template404() { - return html`
    - - - - - This - fine - is -
    `; - } - - // ensure internal data is unset for store - startJourney() { - this.userMenuOpen = false; - store.createSiteSteps = false; - store.siteReady = false; - store.site.structure = null; - store.site.type = null; - store.site.theme = null; - store.site.name = null; - store.appMode = "create"; - store.appEl.playSound("click2"); - } -} -customElements.define(AppHax.tag, AppHax); - -globalThis.AppHax = globalThis.AppHax || {}; - -globalThis.AppHax.requestAvailability = () => { - if (!globalThis.AppHax.instance && globalThis.document) { - globalThis.AppHax.instance = globalThis.document.querySelector(AppHax.tag); - } - return globalThis.AppHax.instance; -}; \ No newline at end of file diff --git a/elements/awesome-explosion/test/awesome-explosion.test.js b/elements/awesome-explosion/test/awesome-explosion.test.js index 77b278e8aa..e5c3c97bb8 100644 --- a/elements/awesome-explosion/test/awesome-explosion.test.js +++ b/elements/awesome-explosion/test/awesome-explosion.test.js @@ -4,26 +4,26 @@ import "../awesome-explosion.js"; describe("awesome-explosion test", () => { let element; let originalAudio; - + beforeEach(async () => { // Mock global audio to prevent actual sound playback during tests originalAudio = globalThis.audio; globalThis.audio = { play: () => Promise.resolve(), pause: () => {}, - currentTime: 0 + currentTime: 0, }; - + element = await fixture(html` - `); await element.updateComplete; }); - + afterEach(() => { // Restore original global audio globalThis.audio = originalAudio; @@ -51,10 +51,10 @@ describe("awesome-explosion test", () => { }); it("should have default image and sound URLs", () => { - expect(element.image).to.be.a('string'); - expect(element.image).to.include('explode.gif'); - expect(element.sound).to.be.a('string'); - expect(element.sound).to.include('.mp3'); + expect(element.image).to.be.a("string"); + expect(element.image).to.include("explode.gif"); + expect(element.sound).to.be.a("string"); + expect(element.sound).to.include(".mp3"); }); }); @@ -70,14 +70,14 @@ describe("awesome-explosion test", () => { describe("Size property", () => { it("should handle all valid size values and maintain accessibility", async () => { - const validSizes = ['tiny', 'small', 'medium', 'large', 'epic']; - + const validSizes = ["tiny", "small", "medium", "large", "epic"]; + for (const size of validSizes) { testElement.size = size; await testElement.updateComplete; expect(testElement.size).to.equal(size); - expect(testElement.hasAttribute('size')).to.be.true; - expect(testElement.getAttribute('size')).to.equal(size); + expect(testElement.hasAttribute("size")).to.be.true; + expect(testElement.getAttribute("size")).to.equal(size); await expect(testElement).shadowDom.to.be.accessible(); } }); @@ -89,15 +89,15 @@ describe("awesome-explosion test", () => { describe("Color property", () => { it("should handle all valid color values and maintain accessibility", async () => { - const validColors = ['red', 'purple', 'blue', 'orange', 'yellow', '']; - + const validColors = ["red", "purple", "blue", "orange", "yellow", ""]; + for (const color of validColors) { testElement.color = color; await testElement.updateComplete; expect(testElement.color).to.equal(color); if (color) { - expect(testElement.hasAttribute('color')).to.be.true; - expect(testElement.getAttribute('color')).to.equal(color); + expect(testElement.hasAttribute("color")).to.be.true; + expect(testElement.getAttribute("color")).to.equal(color); } await expect(testElement).shadowDom.to.be.accessible(); } @@ -110,14 +110,14 @@ describe("awesome-explosion test", () => { describe("State property", () => { it("should handle all valid state values and maintain accessibility", async () => { - const validStates = ['play', 'pause', 'stop']; - + const validStates = ["play", "pause", "stop"]; + for (const state of validStates) { testElement.state = state; await testElement.updateComplete; expect(testElement.state).to.equal(state); - expect(testElement.hasAttribute('state')).to.be.true; - expect(testElement.getAttribute('state')).to.equal(state); + expect(testElement.hasAttribute("state")).to.be.true; + expect(testElement.getAttribute("state")).to.equal(state); await expect(testElement).shadowDom.to.be.accessible(); } }); @@ -132,33 +132,33 @@ describe("awesome-explosion test", () => { testElement.resetSound = true; await testElement.updateComplete; expect(testElement.resetSound).to.equal(true); - expect(testElement.hasAttribute('reset-sound')).to.be.true; + expect(testElement.hasAttribute("reset-sound")).to.be.true; await expect(testElement).shadowDom.to.be.accessible(); testElement.resetSound = false; await testElement.updateComplete; expect(testElement.resetSound).to.equal(false); - expect(testElement.hasAttribute('reset-sound')).to.be.false; + expect(testElement.hasAttribute("reset-sound")).to.be.false; await expect(testElement).shadowDom.to.be.accessible(); }); it("should handle computed boolean properties", async () => { // Test stopped state - testElement.state = 'stop'; + testElement.state = "stop"; await testElement.updateComplete; expect(testElement.stopped).to.be.true; expect(testElement.playing).to.be.false; expect(testElement.paused).to.be.false; // Test playing state - testElement.state = 'play'; + testElement.state = "play"; await testElement.updateComplete; expect(testElement.stopped).to.be.false; expect(testElement.playing).to.be.true; expect(testElement.paused).to.be.false; // Test paused state - testElement.state = 'pause'; + testElement.state = "pause"; await testElement.updateComplete; expect(testElement.stopped).to.be.false; expect(testElement.playing).to.be.false; @@ -172,9 +172,11 @@ describe("awesome-explosion test", () => { it("should handle custom image property", async () => { testElement.image = "https://example.com/custom-explosion.gif"; await testElement.updateComplete; - expect(testElement.image).to.equal("https://example.com/custom-explosion.gif"); - - const img = testElement.shadowRoot.querySelector('#image'); + expect(testElement.image).to.equal( + "https://example.com/custom-explosion.gif", + ); + + const img = testElement.shadowRoot.querySelector("#image"); expect(img.src).to.equal("https://example.com/custom-explosion.gif"); await expect(testElement).shadowDom.to.be.accessible(); }); @@ -182,7 +184,9 @@ describe("awesome-explosion test", () => { it("should handle custom sound property", async () => { testElement.sound = "https://example.com/custom-explosion.mp3"; await testElement.updateComplete; - expect(testElement.sound).to.equal("https://example.com/custom-explosion.mp3"); + expect(testElement.sound).to.equal( + "https://example.com/custom-explosion.mp3", + ); await expect(testElement).shadowDom.to.be.accessible(); }); }); @@ -190,48 +194,50 @@ describe("awesome-explosion test", () => { describe("Visual rendering and image display", () => { it("should render image element with correct attributes", () => { - const img = element.shadowRoot.querySelector('#image'); + const img = element.shadowRoot.querySelector("#image"); expect(img).to.exist; - expect(img.tagName.toLowerCase()).to.equal('img'); - expect(img.getAttribute('loading')).to.equal('lazy'); - expect(img.getAttribute('alt')).to.equal(''); - expect(img.classList.contains('image-tag')).to.be.true; + expect(img.tagName.toLowerCase()).to.equal("img"); + expect(img.getAttribute("loading")).to.equal("lazy"); + expect(img.getAttribute("alt")).to.equal(""); + expect(img.classList.contains("image-tag")).to.be.true; }); it("should update image source when image property changes", async () => { const testElement = await fixture(html` - + `); await testElement.updateComplete; - - const img = testElement.shadowRoot.querySelector('#image'); + + const img = testElement.shadowRoot.querySelector("#image"); expect(img.src).to.equal("https://example.com/test.gif"); }); it("should apply size-based CSS classes correctly", async () => { - const sizes = ['tiny', 'small', 'medium', 'large', 'epic']; - + const sizes = ["tiny", "small", "medium", "large", "epic"]; + for (const size of sizes) { const testElement = await fixture(html` `); await testElement.updateComplete; - - expect(testElement.getAttribute('size')).to.equal(size); + + expect(testElement.getAttribute("size")).to.equal(size); await expect(testElement).shadowDom.to.be.accessible(); } }); it("should apply color-based CSS filters correctly", async () => { - const colors = ['red', 'purple', 'blue', 'orange', 'yellow']; - + const colors = ["red", "purple", "blue", "orange", "yellow"]; + for (const color of colors) { const testElement = await fixture(html` `); await testElement.updateComplete; - - expect(testElement.getAttribute('color')).to.equal(color); + + expect(testElement.getAttribute("color")).to.equal(color); await expect(testElement).shadowDom.to.be.accessible(); } }); @@ -239,11 +245,11 @@ describe("awesome-explosion test", () => { describe("Sound functionality and audio controls", () => { let mockAudio; - + beforeEach(() => { let playCallCount = 0; let pauseCallCount = 0; - + mockAudio = { play: () => { playCallCount++; @@ -254,9 +260,9 @@ describe("awesome-explosion test", () => { }, currentTime: 0, getPlayCallCount: () => playCallCount, - getPauseCallCount: () => pauseCallCount + getPauseCallCount: () => pauseCallCount, }; - + globalThis.audio = mockAudio; }); @@ -264,10 +270,10 @@ describe("awesome-explosion test", () => { const testElement = await fixture(html` `); - - testElement.state = 'play'; + + testElement.state = "play"; await testElement.updateComplete; - + expect(mockAudio.getPlayCallCount()).to.be.greaterThan(0); expect(testElement.playing).to.be.true; }); @@ -276,10 +282,10 @@ describe("awesome-explosion test", () => { const testElement = await fixture(html` `); - - testElement.state = 'pause'; + + testElement.state = "pause"; await testElement.updateComplete; - + expect(mockAudio.getPauseCallCount()).to.be.greaterThan(0); expect(testElement.paused).to.be.true; }); @@ -288,10 +294,10 @@ describe("awesome-explosion test", () => { const testElement = await fixture(html` `); - - testElement.state = 'stop'; + + testElement.state = "stop"; await testElement.updateComplete; - + expect(mockAudio.getPauseCallCount()).to.be.greaterThan(0); expect(testElement.stopped).to.be.true; expect(mockAudio.currentTime).to.equal(0); @@ -301,85 +307,85 @@ describe("awesome-explosion test", () => { const testElement = await fixture(html` `); - + mockAudio.currentTime = 5.5; // Set some progress - testElement.state = 'pause'; + testElement.state = "pause"; await testElement.updateComplete; - + expect(mockAudio.currentTime).to.equal(0); }); it("should create new Audio instance if not exists", async () => { delete globalThis.audio; - + const testElement = await fixture(html` `); - + // Mock the Audio constructor const originalAudio = globalThis.Audio; let audioCreated = false; - globalThis.Audio = function(src) { + globalThis.Audio = function (src) { audioCreated = true; this.play = () => Promise.resolve(); this.pause = () => {}; this.currentTime = 0; return this; }; - - testElement.state = 'play'; + + testElement.state = "play"; await testElement.updateComplete; - + expect(audioCreated).to.be.true; - + globalThis.Audio = originalAudio; }); }); describe("Event handling and user interaction", () => { it("should respond to click events", (done) => { - const testElement = new (element.constructor)(); - + const testElement = new element.constructor(); + // Wait for event listeners to be attached setTimeout(() => { - expect(testElement.state).to.equal('stop'); - + expect(testElement.state).to.equal("stop"); + testElement.click(); - + setTimeout(() => { - expect(testElement.state).to.equal('play'); + expect(testElement.state).to.equal("play"); done(); }, 10); }, 10); }); it("should respond to mouseover events", (done) => { - const testElement = new (element.constructor)(); - + const testElement = new element.constructor(); + setTimeout(() => { - expect(testElement.state).to.equal('stop'); - - const mouseoverEvent = new MouseEvent('mouseover'); + expect(testElement.state).to.equal("stop"); + + const mouseoverEvent = new MouseEvent("mouseover"); testElement.dispatchEvent(mouseoverEvent); - + setTimeout(() => { - expect(testElement.state).to.equal('play'); + expect(testElement.state).to.equal("play"); done(); }, 10); }, 10); }); it("should respond to mouseout events", (done) => { - const testElement = new (element.constructor)(); - + const testElement = new element.constructor(); + setTimeout(() => { - testElement.state = 'play'; - - const mouseoutEvent = new MouseEvent('mouseout'); + testElement.state = "play"; + + const mouseoutEvent = new MouseEvent("mouseout"); testElement.dispatchEvent(mouseoutEvent); - + setTimeout(() => { - expect(testElement.state).to.equal('pause'); + expect(testElement.state).to.equal("pause"); done(); }, 10); }, 10); @@ -388,46 +394,46 @@ describe("awesome-explosion test", () => { describe("Custom events and communication", () => { it("should dispatch awesome-event when playing", (done) => { - const testElement = new (element.constructor)(); - - testElement.addEventListener('awesome-event', (e) => { - expect(e.detail.message).to.equal('Sound played'); + const testElement = new element.constructor(); + + testElement.addEventListener("awesome-event", (e) => { + expect(e.detail.message).to.equal("Sound played"); expect(e.bubbles).to.be.true; expect(e.cancelable).to.be.true; expect(e.composed).to.be.true; done(); }); - - testElement.state = 'play'; + + testElement.state = "play"; }); it("should dispatch awesome-event when paused", (done) => { - const testElement = new (element.constructor)(); - - testElement.addEventListener('awesome-event', (e) => { - expect(e.detail.message).to.equal('Sound paused'); + const testElement = new element.constructor(); + + testElement.addEventListener("awesome-event", (e) => { + expect(e.detail.message).to.equal("Sound paused"); done(); }); - - testElement.state = 'pause'; + + testElement.state = "pause"; }); it("should dispatch awesome-event when stopped", (done) => { - const testElement = new (element.constructor)(); - - testElement.addEventListener('awesome-event', (e) => { - expect(e.detail.message).to.equal('Sound stopped'); + const testElement = new element.constructor(); + + testElement.addEventListener("awesome-event", (e) => { + expect(e.detail.message).to.equal("Sound stopped"); done(); }); - - testElement.state = 'stop'; + + testElement.state = "stop"; }); }); describe("Accessibility scenarios", () => { it("should remain accessible with different sizes", async () => { - const sizes = ['tiny', 'small', 'medium', 'large', 'epic']; - + const sizes = ["tiny", "small", "medium", "large", "epic"]; + for (const size of sizes) { const testElement = await fixture(html` @@ -438,8 +444,8 @@ describe("awesome-explosion test", () => { }); it("should remain accessible with different colors", async () => { - const colors = ['red', 'purple', 'blue', 'orange', 'yellow']; - + const colors = ["red", "purple", "blue", "orange", "yellow"]; + for (const color of colors) { const testElement = await fixture(html` @@ -453,8 +459,8 @@ describe("awesome-explosion test", () => { const testElement = await fixture(html` `); - - const states = ['play', 'pause', 'stop']; + + const states = ["play", "pause", "stop"]; for (const state of states) { testElement.state = state; await testElement.updateComplete; @@ -479,9 +485,9 @@ describe("awesome-explosion test", () => { describe("Edge cases and error handling", () => { it("should handle missing global audio gracefully", () => { delete globalThis.audio; - - const testElement = new (element.constructor)(); - + + const testElement = new element.constructor(); + expect(() => { testElement._stopSound(); }).to.not.throw(); @@ -491,11 +497,11 @@ describe("awesome-explosion test", () => { const testElement = await fixture(html` `); - - testElement.state = 'invalid-state'; + + testElement.state = "invalid-state"; await testElement.updateComplete; - - expect(testElement.state).to.equal('invalid-state'); + + expect(testElement.state).to.equal("invalid-state"); expect(testElement.stopped).to.be.false; expect(testElement.playing).to.be.false; expect(testElement.paused).to.be.false; @@ -504,12 +510,15 @@ describe("awesome-explosion test", () => { it("should handle invalid size and color values", async () => { const testElement = await fixture(html` - + `); await testElement.updateComplete; - - expect(testElement.size).to.equal('invalid-size'); - expect(testElement.color).to.equal('invalid-color'); + + expect(testElement.size).to.equal("invalid-size"); + expect(testElement.color).to.equal("invalid-color"); await expect(testElement).shadowDom.to.be.accessible(); }); @@ -521,30 +530,32 @@ describe("awesome-explosion test", () => { > `); await testElement.updateComplete; - - expect(testElement.image).to.equal('invalid-url'); - expect(testElement.sound).to.equal('malformed-url'); + + expect(testElement.image).to.equal("invalid-url"); + expect(testElement.sound).to.equal("malformed-url"); await expect(testElement).shadowDom.to.be.accessible(); }); it("should handle unusual property values", async () => { - const testElement = await fixture(html``); - + const testElement = await fixture( + html``, + ); + const edgeCaseValues = [ " \t\n ", // whitespace "💥 explosion with emoji 💥", // emoji "Very long size name that might cause issues", "Multi\nline\nvalue", // multiline - "Value with 'quotes' and \"double quotes\" and special chars: !@#$%^&*()" + "Value with 'quotes' and \"double quotes\" and special chars: !@#$%^&*()", ]; - + for (const value of edgeCaseValues) { testElement.size = value; testElement.color = value; testElement.image = value; testElement.sound = value; await testElement.updateComplete; - + expect(testElement.size).to.equal(value); expect(testElement.color).to.equal(value); expect(testElement.image).to.equal(value); @@ -559,17 +570,17 @@ describe("awesome-explosion test", () => { const styles = element.constructor.styles; expect(styles).to.exist; expect(styles.length).to.be.greaterThan(0); - + const styleString = styles[0].cssText || styles[0].toString(); - expect(styleString).to.include(':host'); - expect(styleString).to.include('display: inline-block'); - expect(styleString).to.include('#image'); + expect(styleString).to.include(":host"); + expect(styleString).to.include("display: inline-block"); + expect(styleString).to.include("#image"); }); it("should include size-specific CSS rules", () => { const styles = element.constructor.styles; const styleString = styles[0].cssText || styles[0].toString(); - + expect(styleString).to.include(':host([size="tiny"])'); expect(styleString).to.include(':host([size="small"])'); expect(styleString).to.include(':host([size="medium"])'); @@ -580,39 +591,39 @@ describe("awesome-explosion test", () => { it("should include color filter CSS rules", () => { const styles = element.constructor.styles; const styleString = styles[0].cssText || styles[0].toString(); - + expect(styleString).to.include(':host([color="red"])'); expect(styleString).to.include(':host([color="purple"])'); expect(styleString).to.include(':host([color="blue"])'); expect(styleString).to.include(':host([color="orange"])'); expect(styleString).to.include(':host([color="yellow"])'); - expect(styleString).to.include('filter: sepia()'); + expect(styleString).to.include("filter: sepia()"); }); }); describe("Lifecycle and initialization", () => { it("should set up event listeners after timeout", (done) => { - const testElement = new (element.constructor)(); - + const testElement = new element.constructor(); + // Initially the event listeners shouldn't be set up yet - expect(testElement.state).to.equal('stop'); - + expect(testElement.state).to.equal("stop"); + // After timeout, event listeners should work setTimeout(() => { testElement.click(); setTimeout(() => { - expect(testElement.state).to.equal('play'); + expect(testElement.state).to.equal("play"); done(); }, 10); }, 10); }); it("should initialize with correct default media URLs", () => { - const testElement = new (element.constructor)(); - - expect(testElement.image).to.include('explode.gif'); - expect(testElement.sound).to.include('.mp3'); - expect(testElement.sound).to.include('fireworks'); + const testElement = new element.constructor(); + + expect(testElement.image).to.include("explode.gif"); + expect(testElement.sound).to.include(".mp3"); + expect(testElement.sound).to.include("fireworks"); }); }); }); diff --git a/elements/chartist-render/test/chartist-render.test.js b/elements/chartist-render/test/chartist-render.test.js index a405024666..548a9c63fb 100644 --- a/elements/chartist-render/test/chartist-render.test.js +++ b/elements/chartist-render/test/chartist-render.test.js @@ -6,55 +6,55 @@ beforeEach(() => { // Mock global Chartist library globalThis.Chartist = { Bar: (target, data, options, responsiveOptions) => ({ - type: 'Bar', + type: "Bar", target, data, options, responsiveOptions, on: (event, callback) => { setTimeout(() => { - if (event === 'created' || event === 'draw') { + if (event === "created" || event === "draw") { callback({ type: event, target, data }); } }, 10); - } + }, }), Line: (target, data, options, responsiveOptions) => ({ - type: 'Line', + type: "Line", target, data, options, responsiveOptions, on: (event, callback) => { setTimeout(() => { - if (event === 'created' || event === 'draw') { + if (event === "created" || event === "draw") { callback({ type: event, target, data }); } }, 10); - } + }, }), Pie: (target, data, options, responsiveOptions) => ({ - type: 'Pie', + type: "Pie", target, data, options, responsiveOptions, on: (event, callback) => { setTimeout(() => { - if (event === 'created' || event === 'draw') { + if (event === "created" || event === "draw") { callback({ type: event, target, data }); } }, 10); - } + }, }), noop: () => {}, plugins: { - ctAxisTitle: (options) => ({ type: 'ctAxisTitle', options }), - ctPointLabels: (options) => ({ type: 'ctPointLabels', options }), - fillDonut: (options) => ({ type: 'fillDonut', options }) - } + ctAxisTitle: (options) => ({ type: "ctAxisTitle", options }), + ctPointLabels: (options) => ({ type: "ctPointLabels", options }), + fillDonut: (options) => ({ type: "fillDonut", options }), + }, }; - + // Mock ESGlobalBridge globalThis.ESGlobalBridge = { requestAvailability: () => ({ @@ -62,18 +62,18 @@ beforeEach(() => { setTimeout(() => { globalThis.dispatchEvent(new CustomEvent(`es-bridge-${name}-loaded`)); }, 10); - } - }) + }, + }), }; - + // Mock fetch for CSV loading globalThis.fetch = (url) => { - const csvData = 'Label A,Label B,Label C\n10,20,30\n40,50,60'; + const csvData = "Label A,Label B,Label C\n10,20,30\n40,50,60"; return Promise.resolve({ - text: () => Promise.resolve(csvData) + text: () => Promise.resolve(csvData), }); }; - + // Mock AbortController if (!globalThis.AbortController) { globalThis.AbortController = class { @@ -95,13 +95,15 @@ aftereEach(() => { describe("chartist-render test", () => { let element; - + beforeEach(async () => { element = await fixture( html`

    A pie chart of favorite pies (chart)

    - + @@ -123,7 +125,7 @@ describe("chartist-render test", () => {
    A pie chart of favorite pies (table) + A pie chart of favorite pies (table) +
    Key Lime
    -
    ` + `, ); await element.updateComplete; }); @@ -147,17 +149,17 @@ describe("chartist-render test", () => { expect(element.type).to.equal("pie"); expect(element.scale).to.equal("ct-square"); expect(element.showTable).to.be.false; - expect(element.data).to.be.an('array'); - expect(element.responsiveOptions).to.be.an('array'); + expect(element.data).to.be.an("array"); + expect(element.responsiveOptions).to.be.an("array"); }); it("should have required chart structure elements", () => { - const chartDiv = element.shadowRoot.querySelector('#chart'); - const titleDiv = element.shadowRoot.querySelector('.title'); - const descDiv = element.shadowRoot.querySelector('.desc'); - const tableDiv = element.shadowRoot.querySelector('.table'); - const slot = element.shadowRoot.querySelector('slot'); - + const chartDiv = element.shadowRoot.querySelector("#chart"); + const titleDiv = element.shadowRoot.querySelector(".title"); + const descDiv = element.shadowRoot.querySelector(".desc"); + const tableDiv = element.shadowRoot.querySelector(".table"); + const slot = element.shadowRoot.querySelector("slot"); + expect(chartDiv).to.exist; expect(titleDiv).to.exist; expect(descDiv).to.exist; @@ -166,23 +168,23 @@ describe("chartist-render test", () => { }); it("should have proper ARIA attributes", () => { - const chartDiv = element.shadowRoot.querySelector('#chart'); - - expect(chartDiv.getAttribute('role')).to.equal('presentation'); - expect(chartDiv.hasAttribute('aria-label')).to.be.true; - expect(chartDiv.hasAttribute('aria-describedby')).to.be.true; + const chartDiv = element.shadowRoot.querySelector("#chart"); + + expect(chartDiv.getAttribute("role")).to.equal("presentation"); + expect(chartDiv.hasAttribute("aria-label")).to.be.true; + expect(chartDiv.hasAttribute("aria-describedby")).to.be.true; }); }); describe("Property validation with accessibility", () => { describe("type property", () => { it("should handle different chart types and maintain accessibility", async () => { - const chartTypes = ['bar', 'line', 'pie']; - + const chartTypes = ["bar", "line", "pie"]; + for (const type of chartTypes) { element.type = type; await element.updateComplete; - + expect(element.type).to.equal(type); await expect(element).shadowDom.to.be.accessible(); } @@ -192,21 +194,21 @@ describe("chartist-render test", () => { describe("scale property", () => { it("should handle different scale values and maintain accessibility", async () => { const scales = [ - 'ct-square', - 'ct-minor-second', - 'ct-major-second', - 'ct-minor-third', - 'ct-perfect-fourth', - 'ct-golden-section', - 'ct-octave' + "ct-square", + "ct-minor-second", + "ct-major-second", + "ct-minor-third", + "ct-perfect-fourth", + "ct-golden-section", + "ct-octave", ]; - + for (const scale of scales) { element.scale = scale; await element.updateComplete; - + expect(element.scale).to.equal(scale); - const chartDiv = element.shadowRoot.querySelector('#chart'); + const chartDiv = element.shadowRoot.querySelector("#chart"); expect(chartDiv.className).to.include(scale); await expect(element).shadowDom.to.be.accessible(); } @@ -217,16 +219,16 @@ describe("chartist-render test", () => { it("should control table visibility and maintain accessibility", async () => { // Table hidden by default expect(element.showTable).to.be.false; - let tableDiv = element.shadowRoot.querySelector('.table'); - expect(tableDiv.className).to.include('sr-only'); - + let tableDiv = element.shadowRoot.querySelector(".table"); + expect(tableDiv.className).to.include("sr-only"); + // Show table element.showTable = true; await element.updateComplete; - + expect(element.showTable).to.be.true; - tableDiv = element.shadowRoot.querySelector('.table'); - expect(tableDiv.className).to.not.include('sr-only'); + tableDiv = element.shadowRoot.querySelector(".table"); + expect(tableDiv.className).to.not.include("sr-only"); await expect(element).shadowDom.to.be.accessible(); }); }); @@ -234,19 +236,19 @@ describe("chartist-render test", () => { describe("chartTitle property", () => { it("should handle chart titles and maintain accessibility", async () => { const titles = [ - 'Test Chart', - 'Sales Data 2023', - 'Performance Metrics', - '' + "Test Chart", + "Sales Data 2023", + "Performance Metrics", + "", ]; - + for (const title of titles) { element.chartTitle = title; await element.updateComplete; - + expect(element.chartTitle).to.equal(title); - const chartDiv = element.shadowRoot.querySelector('#chart'); - expect(chartDiv.getAttribute('aria-label')).to.equal(title); + const chartDiv = element.shadowRoot.querySelector("#chart"); + expect(chartDiv.getAttribute("aria-label")).to.equal(title); await expect(element).shadowDom.to.be.accessible(); } }); @@ -256,32 +258,32 @@ describe("chartist-render test", () => { describe("Data handling and processing", () => { it("should process table data correctly", async () => { // Element already has table data from fixture - await new Promise(resolve => setTimeout(resolve, 100)); // Allow data processing - - expect(element.data).to.be.an('array'); + await new Promise((resolve) => setTimeout(resolve, 100)); // Allow data processing + + expect(element.data).to.be.an("array"); expect(element.data.length).to.be.greaterThan(0); expect(element.chartData).to.exist; - expect(element.chartData.labels).to.be.an('array'); - expect(element.chartData.series).to.be.an('array'); + expect(element.chartData.labels).to.be.an("array"); + expect(element.chartData.series).to.be.an("array"); }); it("should handle CSV data loading", async () => { - element.dataSource = 'test.csv'; + element.dataSource = "test.csv"; await element.updateComplete; - + // Wait for fetch to complete - await new Promise(resolve => setTimeout(resolve, 100)); - - expect(element.data).to.be.an('array'); + await new Promise((resolve) => setTimeout(resolve, 100)); + + expect(element.data).to.be.an("array"); }); it("should convert CSV text to array correctly", () => { - const csvText = 'A,B,C\n1,2,3\n4,5,6'; + const csvText = "A,B,C\n1,2,3\n4,5,6"; const result = element._CSVtoArray(csvText); - - expect(result).to.be.an('array'); + + expect(result).to.be.an("array"); expect(result.length).to.equal(3); - expect(result[0]).to.deep.equal(['A', 'B', 'C']); + expect(result[0]).to.deep.equal(["A", "B", "C"]); expect(result[1]).to.deep.equal([1, 2, 3]); expect(result[2]).to.deep.equal([4, 5, 6]); }); @@ -289,21 +291,25 @@ describe("chartist-render test", () => { it("should handle CSV with quoted values", () => { const csvText = '"Label A","Label B","Label C"\n"Value 1",10,20'; const result = element._CSVtoArray(csvText); - - expect(result[0]).to.deep.equal(['Label A', 'Label B', 'Label C']); - expect(result[1]).to.deep.equal(['Value 1', 10, 20]); + + expect(result[0]).to.deep.equal(["Label A", "Label B", "Label C"]); + expect(result[1]).to.deep.equal(["Value 1", 10, 20]); }); it("should update chart data when data changes", async () => { const newData = [ - ['Label 1', 'Label 2', 'Label 3'], - [10, 20, 30] + ["Label 1", "Label 2", "Label 3"], + [10, 20, 30], ]; - + element.data = newData; await element.updateComplete; - - expect(element.chartData.labels).to.deep.equal(['Label 1', 'Label 2', 'Label 3']); + + expect(element.chartData.labels).to.deep.equal([ + "Label 1", + "Label 2", + "Label 3", + ]); expect(element.chartData.series).to.deep.equal([10, 20, 30]); }); }); @@ -311,65 +317,68 @@ describe("chartist-render test", () => { describe("Chart rendering functionality", () => { beforeEach(async () => { // Wait for Chartist to be "loaded" - await new Promise(resolve => setTimeout(resolve, 50)); + await new Promise((resolve) => setTimeout(resolve, 50)); }); it("should create bar chart correctly", async () => { - element.type = 'bar'; + element.type = "bar"; await element.updateComplete; - + const chart = element.makeChart(); expect(chart).to.exist; - expect(chart.type).to.equal('Bar'); + expect(chart.type).to.equal("Bar"); }); it("should create line chart correctly", async () => { - element.type = 'line'; + element.type = "line"; await element.updateComplete; - + const chart = element.makeChart(); expect(chart).to.exist; - expect(chart.type).to.equal('Line'); + expect(chart.type).to.equal("Line"); }); it("should create pie chart correctly", async () => { - element.type = 'pie'; + element.type = "pie"; await element.updateComplete; - + const chart = element.makeChart(); expect(chart).to.exist; - expect(chart.type).to.equal('Pie'); + expect(chart.type).to.equal("Pie"); }); it("should handle chart options", async () => { const customOptions = { showArea: true, low: 0, - high: 100 + high: 100, }; - + element.options = customOptions; - element.type = 'line'; + element.type = "line"; await element.updateComplete; - + const chart = element.makeChart(); expect(chart.options).to.include(customOptions); }); it("should handle responsive options", async () => { const responsiveOptions = [ - ['screen and (max-width: 640px)', { - showLine: false, - axisX: { - labelInterpolationFnc: 'noop' - } - }] + [ + "screen and (max-width: 640px)", + { + showLine: false, + axisX: { + labelInterpolationFnc: "noop", + }, + }, + ], ]; - + element.responsiveOptions = responsiveOptions; - element.type = 'bar'; + element.type = "bar"; await element.updateComplete; - + const chart = element.makeChart(); expect(chart.responsiveOptions).to.deep.equal(responsiveOptions); }); @@ -379,65 +388,65 @@ describe("chartist-render test", () => { it("should support axis title plugin", async () => { element.pluginAxisTitle = { axisX: { - axisTitle: 'X Axis', + axisTitle: "X Axis", offset: { x: 0, y: 50 }, - textAnchor: 'middle' - } + textAnchor: "middle", + }, }; - element.type = 'bar'; + element.type = "bar"; await element.updateComplete; - - expect(element.fullOptions.plugins).to.be.an('array'); - expect(element.fullOptions.plugins[0].type).to.equal('ctAxisTitle'); + + expect(element.fullOptions.plugins).to.be.an("array"); + expect(element.fullOptions.plugins[0].type).to.equal("ctAxisTitle"); }); it("should support point labels plugin for line charts", async () => { element.pluginPointLabels = { labelOffset: { x: 0, y: -10 }, - textAnchor: 'middle' + textAnchor: "middle", }; - element.type = 'line'; + element.type = "line"; await element.updateComplete; - - expect(element.fullOptions.plugins).to.be.an('array'); - expect(element.fullOptions.plugins[0].type).to.equal('ctPointLabels'); + + expect(element.fullOptions.plugins).to.be.an("array"); + expect(element.fullOptions.plugins[0].type).to.equal("ctPointLabels"); }); it("should support fill donut plugin for pie charts", async () => { element.pluginFillDonutItems = [ { - class: 'center-text', - content: 'Total: 100', - position: 'center' - } + class: "center-text", + content: "Total: 100", + position: "center", + }, ]; - element.type = 'pie'; + element.type = "pie"; element.options = { donut: true }; await element.updateComplete; - - expect(element.fullOptions.plugins).to.be.an('array'); - expect(element.fullOptions.plugins[0].type).to.equal('fillDonut'); + + expect(element.fullOptions.plugins).to.be.an("array"); + expect(element.fullOptions.plugins[0].type).to.equal("fillDonut"); }); it("should load plugins correctly", () => { const plugins = element.plugins; - expect(plugins).to.be.an('array'); + expect(plugins).to.be.an("array"); expect(plugins.length).to.equal(3); - expect(plugins[0][0]).to.equal('Chartist.plugins.ctAxisTitle'); - expect(plugins[1][0]).to.equal('Chartist.plugins.CtPointLabels'); - expect(plugins[2][0]).to.equal('Chartist.plugins.fillDonut'); + expect(plugins[0][0]).to.equal("Chartist.plugins.ctAxisTitle"); + expect(plugins[1][0]).to.equal("Chartist.plugins.CtPointLabels"); + expect(plugins[2][0]).to.equal("Chartist.plugins.fillDonut"); }); }); describe("Event handling", () => { it("should dispatch chartist-render-ready event on creation", (done) => { - element.addEventListener('chartist-render-ready', (e) => { + element.addEventListener("chartist-render-ready", (e) => { expect(e.detail).to.equal(element); expect(e.bubbles).to.be.true; expect(e.composed).to.be.true; done(); }); - + // Event is dispatched in constructor, so create new element fixture(html``); }); @@ -445,50 +454,53 @@ describe("chartist-render test", () => { it("should dispatch data change events", async () => { let dataChangedFired = false; let chartDataChangedFired = false; - - element.addEventListener('data-changed', () => { + + element.addEventListener("data-changed", () => { dataChangedFired = true; }); - - element.addEventListener('chart-data-changed', () => { + + element.addEventListener("chart-data-changed", () => { chartDataChangedFired = true; }); - - element.data = [['A', 'B'], [1, 2]]; + + element.data = [ + ["A", "B"], + [1, 2], + ]; await element.updateComplete; - + expect(dataChangedFired).to.be.true; expect(chartDataChangedFired).to.be.true; }); it("should dispatch data-source-changed event", async () => { let eventFired = false; - - element.addEventListener('data-source-changed', () => { + + element.addEventListener("data-source-changed", () => { eventFired = true; }); - - element.dataSource = 'new-data.csv'; + + element.dataSource = "new-data.csv"; await element.updateComplete; - + expect(eventFired).to.be.true; }); it("should dispatch chart render events", (done) => { let renderDataFired = false; let renderCreatedFired = false; - - element.addEventListener('chartist-render-data', () => { + + element.addEventListener("chartist-render-data", () => { renderDataFired = true; }); - - element.addEventListener('chartist-render-created', () => { + + element.addEventListener("chartist-render-created", () => { renderCreatedFired = true; expect(renderDataFired).to.be.true; done(); }); - - element.type = 'bar'; + + element.type = "bar"; element._getChart(); }); }); @@ -496,58 +508,58 @@ describe("chartist-render test", () => { describe("Table rendering and accessibility", () => { it("should render table from data", () => { const testData = [ - ['Product', 'Sales', 'Profit'], - ['A', 100, 20], - ['B', 150, 35] + ["Product", "Sales", "Profit"], + ["A", 100, 20], + ["B", 150, 35], ]; - + element.data = testData; element._renderTable(); - - const table = element.querySelector('table'); + + const table = element.querySelector("table"); expect(table).to.exist; - - const headers = table.querySelectorAll('th'); + + const headers = table.querySelectorAll("th"); expect(headers.length).to.equal(3); - expect(headers[0].textContent).to.equal('Product'); + expect(headers[0].textContent).to.equal("Product"); }); it("should handle table with row headers", () => { const testData = [ - ['', 'Q1', 'Q2', 'Q3'], - ['Product A', 100, 120, 140], - ['Product B', 80, 90, 110] + ["", "Q1", "Q2", "Q3"], + ["Product A", 100, 120, 140], + ["Product B", 80, 90, 110], ]; - + element.data = testData; element._renderTable(); - - const table = element.querySelector('table'); + + const table = element.querySelector("table"); const rowHeaders = table.querySelectorAll('tbody th[scope="row"]'); expect(rowHeaders.length).to.equal(2); }); it("should update data from table changes", async () => { // Add a table to test mutation observer - const table = globalThis.document.createElement('table'); + const table = globalThis.document.createElement("table"); table.innerHTML = ` AB 1020 `; element.appendChild(table); - + element._updateData(); - - expect(element.data).to.be.an('array'); - expect(element.data[0]).to.deep.equal(['A', 'B']); + + expect(element.data).to.be.an("array"); + expect(element.data[0]).to.deep.equal(["A", "B"]); expect(element.data[1]).to.deep.equal([10, 20]); }); }); describe("Accessibility scenarios", () => { it("should remain accessible with different chart types", async () => { - const types = ['bar', 'line', 'pie']; - + const types = ["bar", "line", "pie"]; + for (const type of types) { element.type = type; await element.updateComplete; @@ -558,25 +570,27 @@ describe("chartist-render test", () => { it("should remain accessible when table is shown", async () => { element.showTable = true; await element.updateComplete; - + await expect(element).shadowDom.to.be.accessible(); }); it("should have proper heading structure", () => { - const headingSlot = element.shadowRoot.querySelector('slot[name="heading"]'); + const headingSlot = element.shadowRoot.querySelector( + 'slot[name="heading"]', + ); expect(headingSlot).to.exist; - + // Check for slotted heading const heading = element.querySelector('h3[slot="heading"]'); expect(heading).to.exist; - expect(heading.textContent).to.include('pie chart'); + expect(heading.textContent).to.include("pie chart"); }); it("should maintain accessibility with custom titles", async () => { - element.chartTitle = 'Custom Accessibility Title'; - element.chartDesc = 'This chart shows test data for accessibility'; + element.chartTitle = "Custom Accessibility Title"; + element.chartDesc = "This chart shows test data for accessibility"; await element.updateComplete; - + await expect(element).shadowDom.to.be.accessible(); }); }); @@ -585,76 +599,76 @@ describe("chartist-render test", () => { it("should handle empty data gracefully", async () => { element.data = []; await element.updateComplete; - + expect(element.chartData).to.exist; await expect(element).shadowDom.to.be.accessible(); }); it("should handle invalid chart type", async () => { - element.type = 'invalid-type'; + element.type = "invalid-type"; await element.updateComplete; - + // Should not break the component - expect(element.type).to.equal('invalid-type'); + expect(element.type).to.equal("invalid-type"); await expect(element).shadowDom.to.be.accessible(); }); it("should handle malformed CSV data", () => { - const malformedCSV = 'A,B\n1,2,3\n4'; + const malformedCSV = "A,B\n1,2,3\n4"; const result = element._CSVtoArray(malformedCSV); - - expect(result).to.be.an('array'); + + expect(result).to.be.an("array"); // Should handle gracefully without throwing errors }); it("should handle missing Chartist library gracefully", async () => { const originalChartist = globalThis.Chartist; delete globalThis.Chartist; - - element.type = 'bar'; + + element.type = "bar"; element._getChart(); - + // Should not throw errors expect(element.chart).to.be.undefined; - + globalThis.Chartist = originalChartist; }); it("should handle fetch errors for data source", async () => { - globalThis.fetch = () => Promise.reject(new Error('Network error')); - - element.dataSource = 'nonexistent.csv'; + globalThis.fetch = () => Promise.reject(new Error("Network error")); + + element.dataSource = "nonexistent.csv"; await element.updateComplete; - + // Should handle error gracefully - expect(element.dataSource).to.equal('nonexistent.csv'); + expect(element.dataSource).to.equal("nonexistent.csv"); }); it("should handle undefined options", async () => { element.options = undefined; - element.type = 'bar'; + element.type = "bar"; await element.updateComplete; - + const fullOptions = element.fullOptions; - expect(fullOptions).to.be.an('object'); + expect(fullOptions).to.be.an("object"); }); it("should handle extremely large datasets", async () => { const largeData = []; const labels = []; const series = []; - + for (let i = 0; i < 100; i++) { labels.push(`Label ${i}`); series.push(Math.random() * 100); } - + largeData.push(labels); largeData.push(series); - + element.data = largeData; await element.updateComplete; - + expect(element.chartData.labels.length).to.equal(100); expect(element.chartData.series.length).to.equal(100); }); @@ -662,10 +676,10 @@ describe("chartist-render test", () => { describe("Lifecycle methods", () => { it("should handle constructor properly", () => { - const newElement = new (element.constructor)(); - - expect(newElement.type).to.equal('bar'); - expect(newElement.scale).to.equal('ct-minor-seventh'); + const newElement = new element.constructor(); + + expect(newElement.type).to.equal("bar"); + expect(newElement.scale).to.equal("ct-minor-seventh"); expect(newElement.showTable).to.be.false; expect(newElement.windowControllers).to.exist; }); @@ -673,47 +687,50 @@ describe("chartist-render test", () => { it("should handle disconnectedCallback", () => { element.windowControllers = new AbortController(); element.observer = { - disconnect: () => {} + disconnect: () => {}, }; - + element.disconnectedCallback(); - + expect(element.windowControllers.signal.aborted).to.be.true; }); it("should handle updated lifecycle with property changes", async () => { let eventFired = false; - - element.addEventListener('data-changed', () => { + + element.addEventListener("data-changed", () => { eventFired = true; }); - - element.data = [['New', 'Data'], [1, 2]]; + + element.data = [ + ["New", "Data"], + [1, 2], + ]; await element.updateComplete; - + expect(eventFired).to.be.true; }); }); describe("Utility methods", () => { it("should generate unique IDs", () => { - const id1 = element._getUniqueId('test-'); - const id2 = element._getUniqueId('test-'); - - expect(id1).to.include('test-'); - expect(id2).to.include('test-'); + const id1 = element._getUniqueId("test-"); + const id2 = element._getUniqueId("test-"); + + expect(id1).to.include("test-"); + expect(id2).to.include("test-"); expect(id1).to.not.equal(id2); }); it("should load scripts correctly", () => { let scriptLoaded = false; - - globalThis.addEventListener('es-bridge-testScript-loaded', () => { + + globalThis.addEventListener("es-bridge-testScript-loaded", () => { scriptLoaded = true; }); - - element._loadScripts('testScript', 'test/path.js'); - + + element._loadScripts("testScript", "test/path.js"); + // Script loading should be initiated expect(scriptLoaded).to.be.false; // Will be true after async load }); @@ -721,97 +738,101 @@ describe("chartist-render test", () => { describe("Styling and theming", () => { it("should apply scale classes correctly", async () => { - element.scale = 'ct-perfect-fifth'; + element.scale = "ct-perfect-fifth"; await element.updateComplete; - - const chartDiv = element.shadowRoot.querySelector('#chart'); - expect(chartDiv.className).to.include('ct-perfect-fifth'); + + const chartDiv = element.shadowRoot.querySelector("#chart"); + expect(chartDiv.className).to.include("ct-perfect-fifth"); }); it("should support CSS custom properties", () => { - element.style.setProperty('--chartist-color-1', '#ff0000'); - element.style.setProperty('--chartist-text-color', '#333333'); - + element.style.setProperty("--chartist-color-1", "#ff0000"); + element.style.setProperty("--chartist-text-color", "#333333"); + const computedStyle = globalThis.getComputedStyle(element); // Custom properties should be available for use - expect(element.style.getPropertyValue('--chartist-color-1')).to.equal('#ff0000'); + expect(element.style.getPropertyValue("--chartist-color-1")).to.equal( + "#ff0000", + ); }); it("should handle sr-only class for table accessibility", async () => { // Table should be screen-reader only by default element.showTable = false; await element.updateComplete; - - const tableDiv = element.shadowRoot.querySelector('.table'); - expect(tableDiv.className).to.include('sr-only'); - + + const tableDiv = element.shadowRoot.querySelector(".table"); + expect(tableDiv.className).to.include("sr-only"); + // Table should be visible when showTable is true element.showTable = true; await element.updateComplete; - - expect(tableDiv.className).to.not.include('sr-only'); + + expect(tableDiv.className).to.not.include("sr-only"); }); }); describe("Integration scenarios", () => { it("should handle complete workflow from table to chart", async () => { // Start with table data - const table = element.querySelector('table'); + const table = element.querySelector("table"); expect(table).to.exist; - + // Wait for data processing - await new Promise(resolve => setTimeout(resolve, 100)); - + await new Promise((resolve) => setTimeout(resolve, 100)); + // Should have processed data - expect(element.data).to.be.an('array'); + expect(element.data).to.be.an("array"); expect(element.chartData).to.exist; - + // Should be able to create chart const chart = element.makeChart(); expect(chart).to.exist; }); it("should handle CSV to chart workflow", async () => { - element.dataSource = 'test-data.csv'; + element.dataSource = "test-data.csv"; await element.updateComplete; - + // Wait for fetch and processing - await new Promise(resolve => setTimeout(resolve, 100)); - - expect(element.data).to.be.an('array'); + await new Promise((resolve) => setTimeout(resolve, 100)); + + expect(element.data).to.be.an("array"); expect(element.chartData).to.exist; }); it("should work with all chart types and plugins", async () => { const configs = [ - { - type: 'bar', - plugin: 'pluginAxisTitle', - pluginData: { axisX: { axisTitle: 'X Axis' } } + { + type: "bar", + plugin: "pluginAxisTitle", + pluginData: { axisX: { axisTitle: "X Axis" } }, }, - { - type: 'line', - plugin: 'pluginPointLabels', - pluginData: { labelOffset: { x: 0, y: -10 } } + { + type: "line", + plugin: "pluginPointLabels", + pluginData: { labelOffset: { x: 0, y: -10 } }, }, { - type: 'pie', - plugin: 'pluginFillDonutItems', - pluginData: [{ content: 'Center', position: 'center' }], - options: { donut: true } - } + type: "pie", + plugin: "pluginFillDonutItems", + pluginData: [{ content: "Center", position: "center" }], + options: { donut: true }, + }, ]; - + for (const config of configs) { element.type = config.type; element[config.plugin] = config.pluginData; if (config.options) element.options = config.options; await element.updateComplete; - + const chart = element.makeChart(); expect(chart).to.exist; - expect(chart.type).to.equal(config.type.charAt(0).toUpperCase() + config.type.slice(1)); - + expect(chart.type).to.equal( + config.type.charAt(0).toUpperCase() + config.type.slice(1), + ); + await expect(element).shadowDom.to.be.accessible(); } }); @@ -820,33 +841,33 @@ describe("chartist-render test", () => { describe("Performance considerations", () => { it("should handle rapid property changes efficiently", async () => { const startTime = performance.now(); - + for (let i = 0; i < 10; i++) { - element.type = i % 2 === 0 ? 'bar' : 'line'; - element.scale = i % 2 === 0 ? 'ct-square' : 'ct-octave'; + element.type = i % 2 === 0 ? "bar" : "line"; + element.scale = i % 2 === 0 ? "ct-square" : "ct-octave"; await element.updateComplete; } - + const endTime = performance.now(); const totalTime = endTime - startTime; - + expect(totalTime).to.be.lessThan(1000); }); it("should cleanup observers and controllers properly", () => { const mockObserver = { disconnect: () => {}, - observe: () => {} + observe: () => {}, }; - + element.observer = mockObserver; element.windowControllers = new AbortController(); - + expect(element.observer).to.equal(mockObserver); expect(element.windowControllers.signal.aborted).to.be.false; - + element.disconnectedCallback(); - + expect(element.windowControllers.signal.aborted).to.be.true; }); }); diff --git a/elements/code-editor/test/code-editor.test.js b/elements/code-editor/test/code-editor.test.js index 8c5c2486a4..dab7428ba2 100644 --- a/elements/code-editor/test/code-editor.test.js +++ b/elements/code-editor/test/code-editor.test.js @@ -7,32 +7,32 @@ import "../code-editor.js"; class MockMonacoElement extends HTMLElement { constructor() { super(); - this._value = ''; + this._value = ""; this.ready = false; } - + get value() { return this._value; } - + set value(val) { this._value = val; - this.dispatchEvent(new CustomEvent('value-changed', { detail: val })); + this.dispatchEvent(new CustomEvent("value-changed", { detail: val })); } - + connectedCallback() { setTimeout(() => { this.ready = true; - this.dispatchEvent(new CustomEvent('monaco-element-ready')); + this.dispatchEvent(new CustomEvent("monaco-element-ready")); }, 10); } - + focus() { - this.dispatchEvent(new CustomEvent('code-editor-focus')); + this.dispatchEvent(new CustomEvent("code-editor-focus")); } - + blur() { - this.dispatchEvent(new CustomEvent('code-editor-blur')); + this.dispatchEvent(new CustomEvent("code-editor-blur")); } } @@ -41,11 +41,11 @@ class MockCodePenButton extends HTMLElement { static get properties() { return { data: { type: Object } }; } - + set data(val) { this._data = val; } - + get data() { return this._data; } @@ -56,33 +56,33 @@ describe("code-editor test", () => { beforeEach(async () => { sandbox = sinon.createSandbox(); - + // Register mock elements - if (!globalThis.customElements.get('monaco-element')) { - globalThis.customElements.define('monaco-element', MockMonacoElement); + if (!globalThis.customElements.get("monaco-element")) { + globalThis.customElements.define("monaco-element", MockMonacoElement); } - if (!globalThis.customElements.get('code-pen-button')) { - globalThis.customElements.define('code-pen-button', MockCodePenButton); + if (!globalThis.customElements.get("code-pen-button")) { + globalThis.customElements.define("code-pen-button", MockCodePenButton); } - + // Mock global matchMedia globalThis.matchMedia = sandbox.stub().returns({ matches: false, addEventListener: sandbox.stub(), - removeEventListener: sandbox.stub() + removeEventListener: sandbox.stub(), }); - + element = await fixture(html` - `); - + // Wait for monaco element to be ready - await waitUntil(() => element.ready, 'Monaco element should be ready'); + await waitUntil(() => element.ready, "Monaco element should be ready"); }); afterEach(() => { @@ -96,7 +96,7 @@ describe("code-editor test", () => { it("passes a11y audit with all properties set", async () => { const el = await fixture(html` - { }); it("passes a11y audit with minimal properties", async () => { - const el = await fixture(html` - - `); + const el = await fixture(html` `); await waitUntil(() => el.ready); await expect(el).shadowDom.to.be.accessible(); }); @@ -126,7 +124,7 @@ describe("code-editor test", () => { }); it("passes a11y audit with different themes", async () => { - const themes = ['vs', 'vs-dark', 'auto']; + const themes = ["vs", "vs-dark", "auto"]; for (const theme of themes) { element.theme = theme; await element.updateComplete; @@ -137,176 +135,184 @@ describe("code-editor test", () => { describe("Component Structure", () => { it("renders with correct tag name", () => { - expect(element.tagName.toLowerCase()).to.equal('code-editor'); + expect(element.tagName.toLowerCase()).to.equal("code-editor"); }); it("has proper shadow DOM structure", () => { - const label = element.shadowRoot.querySelector('label'); + const label = element.shadowRoot.querySelector("label"); expect(label).to.exist; - - const monacoElement = element.shadowRoot.querySelector('monaco-element'); + + const monacoElement = element.shadowRoot.querySelector("monaco-element"); expect(monacoElement).to.exist; - - const loadingPre = element.shadowRoot.querySelector('#loading'); + + const loadingPre = element.shadowRoot.querySelector("#loading"); expect(loadingPre).to.exist; }); it("includes label with proper association", () => { - const label = element.shadowRoot.querySelector('label'); - expect(label.getAttribute('for')).to.equal('codeeditor'); - expect(label.textContent).to.equal('Test Editor'); + const label = element.shadowRoot.querySelector("label"); + expect(label.getAttribute("for")).to.equal("codeeditor"); + expect(label.textContent).to.equal("Test Editor"); }); it("includes monaco-element with correct attributes", () => { - const monaco = element.shadowRoot.querySelector('monaco-element'); - expect(monaco.getAttribute('id')).to.equal('codeeditor'); - expect(monaco.getAttribute('language')).to.equal('javascript'); - expect(monaco.getAttribute('theme')).to.equal('vs-dark'); - expect(monaco.getAttribute('font-size')).to.equal('14'); + const monaco = element.shadowRoot.querySelector("monaco-element"); + expect(monaco.getAttribute("id")).to.equal("codeeditor"); + expect(monaco.getAttribute("language")).to.equal("javascript"); + expect(monaco.getAttribute("theme")).to.equal("vs-dark"); + expect(monaco.getAttribute("font-size")).to.equal("14"); }); it("has hidden slot for content", () => { - const slot = element.shadowRoot.querySelector('slot'); + const slot = element.shadowRoot.querySelector("slot"); expect(slot).to.exist; - expect(slot.hasAttribute('hidden')).to.be.true; + expect(slot.hasAttribute("hidden")).to.be.true; }); it("shows loading preview when not ready", async () => { const el = await fixture(html`const x = 1;`); - const loading = el.shadowRoot.querySelector('#loading'); - const monaco = el.shadowRoot.querySelector('monaco-element'); - - expect(loading.hasAttribute('hidden')).to.be.false; - expect(monaco.hasAttribute('data-hidden')).to.be.true; + const loading = el.shadowRoot.querySelector("#loading"); + const monaco = el.shadowRoot.querySelector("monaco-element"); + + expect(loading.hasAttribute("hidden")).to.be.false; + expect(monaco.hasAttribute("data-hidden")).to.be.true; }); }); describe("Property Handling", () => { it("reflects title property to label", async () => { - element.title = 'New Title'; + element.title = "New Title"; await element.updateComplete; - - const label = element.shadowRoot.querySelector('label'); - expect(label.textContent).to.equal('New Title'); - expect(label.hasAttribute('hidden')).to.be.false; + + const label = element.shadowRoot.querySelector("label"); + expect(label.textContent).to.equal("New Title"); + expect(label.hasAttribute("hidden")).to.be.false; }); it("hides label when title is empty", async () => { - element.title = ''; + element.title = ""; await element.updateComplete; - - const label = element.shadowRoot.querySelector('label'); - expect(label.hasAttribute('hidden')).to.be.true; + + const label = element.shadowRoot.querySelector("label"); + expect(label.hasAttribute("hidden")).to.be.true; }); it("handles language property changes", async () => { - element.language = 'python'; + element.language = "python"; await element.updateComplete; - - const monaco = element.shadowRoot.querySelector('monaco-element'); - expect(monaco.getAttribute('language')).to.equal('python'); + + const monaco = element.shadowRoot.querySelector("monaco-element"); + expect(monaco.getAttribute("language")).to.equal("python"); }); it("handles theme property changes", async () => { - element.theme = 'vs'; + element.theme = "vs"; await element.updateComplete; - - const monaco = element.shadowRoot.querySelector('monaco-element'); - expect(monaco.getAttribute('theme')).to.equal('vs'); - expect(element.getAttribute('theme-colors')).to.equal('vs'); + + const monaco = element.shadowRoot.querySelector("monaco-element"); + expect(monaco.getAttribute("theme")).to.equal("vs"); + expect(element.getAttribute("theme-colors")).to.equal("vs"); }); it("handles fontSize property changes", async () => { element.fontSize = 18; await element.updateComplete; - - const monaco = element.shadowRoot.querySelector('monaco-element'); - expect(monaco.getAttribute('font-size')).to.equal('18'); + + const monaco = element.shadowRoot.querySelector("monaco-element"); + expect(monaco.getAttribute("font-size")).to.equal("18"); }); it("handles readOnly property correctly", async () => { element.readOnly = true; await element.updateComplete; - - expect(element.getAttribute('read-only')).to.equal(''); - const monaco = element.shadowRoot.querySelector('monaco-element'); - expect(monaco.hasAttribute('read-only')).to.be.true; + + expect(element.getAttribute("read-only")).to.equal(""); + const monaco = element.shadowRoot.querySelector("monaco-element"); + expect(monaco.hasAttribute("read-only")).to.be.true; }); it("handles wordWrap property correctly", async () => { element.wordWrap = true; await element.updateComplete; - - const monaco = element.shadowRoot.querySelector('monaco-element'); - expect(monaco.hasAttribute('word-wrap')).to.be.true; + + const monaco = element.shadowRoot.querySelector("monaco-element"); + expect(monaco.hasAttribute("word-wrap")).to.be.true; }); it("handles tabSize property correctly", async () => { element.tabSize = 4; await element.updateComplete; - - const monaco = element.shadowRoot.querySelector('monaco-element'); - expect(monaco.getAttribute('tab-size')).to.equal('4'); + + const monaco = element.shadowRoot.querySelector("monaco-element"); + expect(monaco.getAttribute("tab-size")).to.equal("4"); }); it("handles autofocus property correctly", async () => { element.autofocus = true; await element.updateComplete; - - expect(element.hasAttribute('autofocus')).to.be.true; - const monaco = element.shadowRoot.querySelector('monaco-element'); - expect(monaco.hasAttribute('autofocus')).to.be.true; + + expect(element.hasAttribute("autofocus")).to.be.true; + const monaco = element.shadowRoot.querySelector("monaco-element"); + expect(monaco.hasAttribute("autofocus")).to.be.true; }); it("handles hideLineNumbers property correctly", async () => { element.hideLineNumbers = true; await element.updateComplete; - - const monaco = element.shadowRoot.querySelector('monaco-element'); - expect(monaco.hasAttribute('hide-line-numbers')).to.be.true; + + const monaco = element.shadowRoot.querySelector("monaco-element"); + expect(monaco.hasAttribute("hide-line-numbers")).to.be.true; }); it("handles focused property and reflects it", async () => { element.focused = true; await element.updateComplete; - - expect(element.hasAttribute('focused')).to.be.true; + + expect(element.hasAttribute("focused")).to.be.true; }); }); describe("Theme System", () => { it("returns correct theme for vs", () => { - expect(element.getTheme('vs')).to.equal('vs'); - expect(element.getAttribute('theme-colors')).to.equal('vs'); + expect(element.getTheme("vs")).to.equal("vs"); + expect(element.getAttribute("theme-colors")).to.equal("vs"); }); it("returns correct theme for vs-dark", () => { - expect(element.getTheme('vs-dark')).to.equal('vs-dark'); - expect(element.getAttribute('theme-colors')).to.equal('vs-dark'); + expect(element.getTheme("vs-dark")).to.equal("vs-dark"); + expect(element.getAttribute("theme-colors")).to.equal("vs-dark"); }); it("handles auto theme with dark preference", () => { - globalThis.matchMedia.withArgs('(prefers-color-scheme: dark)').returns({ matches: true }); - globalThis.matchMedia.withArgs('(prefers-color-scheme: light)').returns({ matches: false }); - - expect(element.getTheme('auto')).to.equal('vs-dark'); + globalThis.matchMedia + .withArgs("(prefers-color-scheme: dark)") + .returns({ matches: true }); + globalThis.matchMedia + .withArgs("(prefers-color-scheme: light)") + .returns({ matches: false }); + + expect(element.getTheme("auto")).to.equal("vs-dark"); }); it("handles auto theme with light preference", () => { - globalThis.matchMedia.withArgs('(prefers-color-scheme: dark)').returns({ matches: false }); - globalThis.matchMedia.withArgs('(prefers-color-scheme: light)').returns({ matches: true }); - - expect(element.getTheme('auto')).to.equal('vs'); + globalThis.matchMedia + .withArgs("(prefers-color-scheme: dark)") + .returns({ matches: false }); + globalThis.matchMedia + .withArgs("(prefers-color-scheme: light)") + .returns({ matches: true }); + + expect(element.getTheme("auto")).to.equal("vs"); }); it("defaults to vs-dark for auto theme without preference", () => { globalThis.matchMedia.returns({ matches: false }); - - expect(element.getTheme('auto')).to.equal('vs-dark'); + + expect(element.getTheme("auto")).to.equal("vs-dark"); }); it("handles undefined theme", () => { - expect(element.getTheme(undefined)).to.equal('vs-dark'); + expect(element.getTheme(undefined)).to.equal("vs-dark"); }); }); @@ -315,17 +321,17 @@ describe("code-editor test", () => { const testCode = 'console.log("Hello World");'; element.editorValue = testCode; await element.updateComplete; - + expect(element.innerHTML).to.include(testCode); }); it("handles value changes from monaco element", async () => { - const testValue = 'const x = 42;'; - const monaco = element.shadowRoot.querySelector('monaco-element'); - + const testValue = "const x = 42;"; + const monaco = element.shadowRoot.querySelector("monaco-element"); + monaco.value = testValue; await element.updateComplete; - + expect(element.value).to.equal(testValue); }); @@ -335,14 +341,14 @@ describe("code-editor test", () => { `); - - expect(el.placeholder).to.include('const example = true;'); + + expect(el.placeholder).to.include("const example = true;"); }); it("computes placeholder from editorValue", async () => { element.editorValue = 'let test = "value";'; await element.updateComplete; - + expect(element.placeholder).to.include('let test = "value";'); }); @@ -352,9 +358,9 @@ describe("code-editor test", () => { `); - - expect(el.placeholder).to.not.include(''); + + expect(el.placeholder).to.not.include(""); }); it("handles complex content with iframe", async () => { @@ -365,61 +371,61 @@ describe("code-editor test", () => { `); - - expect(el.placeholder).to.not.include('\n \n
    \n `);\n });\n\n it(\"basic will it blend\", async () => {\n expect(element).to.exist;\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n*/\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: visible, title, src, alt" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "csv-render": { - "element": "csv-render", - "component": { - "properties": [ - { - "name": "dataSource", - "type": "String", - "attribute": "data-source", - "config": "type: String,\n attribute: \"data-source\"," - }, - { - "name": "loading", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,", - "defaultValue": "false" - }, - { - "name": "caption", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "summary", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "table", - "type": "Array", - "attribute": null, - "config": "type: Array,", - "defaultValue": "[]" - }, - { - "name": "tableHeadings", - "type": "Array", - "attribute": null, - "config": "type: Array,", - "defaultValue": "[]" - }, - { - "name": "tableData", - "type": "String", - "attribute": "table-data", - "config": "type: String,\n attribute: \"table-data\",", - "defaultValue": "\"\"" - } - ], - "slots": [], - "events": [], - "methods": [ - "if", - "handleResponse", - "CSVtoArray", - "for" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "IntersectionObserverMixin" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../csv-render.js\";\n\ndescribe(\"csv-render test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"csv-render passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"csv-render passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"csv-render can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: dataSource, loading, caption, summary, table, tableHeadings, tableData" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "d-d-d": { - "element": "d-d-d", - "component": { - "properties": [ - { - "name": "dataPulse", - "type": "String", - "attribute": "data-pulse", - "config": "type: String, reflect: true, attribute: \"data-pulse\"", - "defaultValue": "null" - } - ], - "slots": [ - "default" - ], - "events": [], - "methods": [ - "if", - "removePulseEffect", - "togglePulseEffect", - "for" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "DDDSuper", - "DDDSuper" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\nimport \"../d-d-d.js\";\n\ndescribe(\"elementName test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html``);\n });\n\n it(\"basic will it blend\", async () => {\n expect(element).to.exist;\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: dataPulse" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: data-pulse" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "d-d-docs": { - "element": "d-d-docs", - "component": { - "properties": [ - { - "name": "option", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "\"*\"" - }, - { - "name": "options", - "type": "Array", - "attribute": null, - "config": "type: Array", - "defaultValue": "Object.keys(styleGuideTopics)" - } - ], - "slots": [], - "events": [], - "methods": [ - "renderDataAttributes", - "renderHeaderSample", - "for", - "if", - "renderDDDelementsList", - "renderBorders", - "renderBreakpoints", - "renderDefaultColors", - "renderDefaultFunctionalColors", - "renderGradients", - "renderRadius", - "renderShadows", - "renderSpacing", - "renderTypography", - "renderRichText", - "renderCards", - "renderStepsList", - "renderButtons", - "renderPageSections", - "renderInstructionalComponents", - "selectOption" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { html, fixture, expect } from '@open-wc/testing';\nimport \"../d-d-docs.js\";\n\ndescribe(\"DDDocs test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"basic will it blend\", async () => {\n expect(element).to.exist;\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: option, options" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "data-viz": { - "element": "data-viz", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [ - "if", - "showDataFunction", - "hideDataViz", - "showDataViz" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../data-viz.js\";\n/*\ndescribe(\"data-viz test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html` `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"data-viz passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"data-viz passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"data-viz can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "date-card": { - "element": "date-card", - "component": { - "properties": [ - { - "name": "month", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "date", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "day", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "title", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "startTime", - "type": "String", - "attribute": "start-time", - "config": "type: String, attribute: \"start-time\"" - }, - { - "name": "endTime", - "type": "String", - "attribute": "end-time", - "config": "type: String, attribute: \"end-time\"" - }, - { - "name": "location", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "borderSpacing", - "type": "Number", - "attribute": "border-spacing", - "config": "type: Number, attribute: \"border-spacing\"", - "defaultValue": "5" - } - ], - "slots": [], - "events": [], - "methods": [ - "nth", - "if", - "switch" - ], - "hasHaxProperties": true, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../date-card.js\";\n\ndescribe(\"date-card test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html` `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"date-card passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"date-card passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"date-card can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: month, date, day, title, startTime, endTime, location, borderSpacing" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "deduping-fix": { - "element": "deduping-fix", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": false, - "hasAccessibilityTests": false, - "testedProperties": [], - "testedSlots": [], - "testedEvents": [], - "testedMethods": [] - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_TEST_FILE", - "message": "No test file found. Create test/${elementName}.test.js" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "discord-embed": { - "element": "discord-embed", - "component": { - "properties": [ - { - "name": "height", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "500" - }, - { - "name": "width", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "\"100%\"" - }, - { - "name": "source", - "type": "String", - "attribute": null, - "config": "type: String,\n reflect: true,", - "defaultValue": "\"\"" - } - ], - "slots": [], - "events": [], - "methods": [ - "if" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\nimport \"../discord-embed.js\";\n\ndescribe(\"elementName test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html``);\n });\n\n it(\"basic will it blend\", async () => {\n expect(element).to.exist;\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: height, width, source" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "disqus-embed": { - "element": "disqus-embed", - "component": { - "properties": [ - { - "name": "loadingText", - "type": "String", - "attribute": "loading-text", - "config": "type: String, attribute: \"loading-text\"", - "defaultValue": "\"Loading comments..\"" - }, - { - "name": "pageURL", - "type": "String", - "attribute": "page-url", - "config": "type: String,\n attribute: \"page-url\",", - "defaultValue": "null" - }, - { - "name": "pageIdentifier", - "type": "String", - "attribute": "page-identifier", - "config": "type: String,\n attribute: \"page-identifier\",", - "defaultValue": "null" - }, - { - "name": "pageTitle", - "type": "String", - "attribute": "page-title", - "config": "type: String,\n attribute: \"page-title\",", - "defaultValue": "null" - }, - { - "name": "shortName", - "type": "String", - "attribute": "short-name", - "config": "type: String,\n attribute: \"short-name\",", - "defaultValue": "null" - }, - { - "name": "lang", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"en\"" - } - ], - "slots": [ - "default" - ], - "events": [], - "methods": [ - "if", - "while", - "createEmbedScript", - "rebuildConfiguration", - "renderToTarget", - "apiCallback", - "switch", - "function" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\nimport \"../disqus-embed.js\";\n\ndescribe(\"elementName test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html``);\n });\n\n it(\"basic will it blend\", async () => {\n expect(element).to.exist;\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: loadingText, pageURL, pageIdentifier, pageTitle, shortName, lang" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: loading-text, page-url, page-identifier, page-title, short-name" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "dl-behavior": { - "element": "dl-behavior", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [ - "if", - "value", - "downloadFromData", - "downloadFromURI" - ], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../dl-behavior.js\";\n\ndescribe(\"dl-behavior test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"dl-behavior passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"dl-behavior passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"dl-behavior can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "documentation-player": { - "element": "documentation-player", - "component": { - "properties": [ - { - "name": "label", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "\"\"" - }, - { - "name": "haxSchema", - "type": "Array", - "attribute": null, - "config": "type: Array, attribute: false", - "defaultValue": "[]" - }, - { - "name": "imageUrl", - "type": "String", - "attribute": "image-url", - "config": "type: String, attribute: \"image-url\"", - "defaultValue": "\"\"" - }, - { - "name": "url", - "type": "String", - "attribute": "url", - "config": "type: String, attribute: \"url\"", - "defaultValue": "\"\"" - } - ], - "slots": [], - "events": [ - "hax-insert" - ], - "methods": [ - "for", - "if", - "codePenData", - "renderPlayListTemplate", - "renderHAXInjectButton" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\nimport \"../documentation-player.js\";\n\ndescribe(\"elementName test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html``,\n );\n });\n\n it(\"basic will it blend\", async () => {\n expect(element).to.exist;\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: label, haxSchema, imageUrl, url" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: hax-insert" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: image-url, url" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "dynamic-import-registry": { - "element": "dynamic-import-registry", - "component": { - "properties": [], - "slots": [], - "events": [ - "dynamic-import-registry-loaded", - "dynamic-import-registry-failure" - ], - "methods": [ - "if", - "register", - "registerDefinitionEvent", - "getPathToTag" - ], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../dynamic-import-registry.js\";\n\ndescribe(\"dynamic-import-registry test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"dynamic-import-registry passes accessibility test\", async () => {\n const el = await fixture(\n html` `\n );\n await expect(el).to.be.accessible();\n });\n it(\"dynamic-import-registry passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"dynamic-import-registry can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: dynamic-import-registry-loaded, dynamic-import-registry-failure" - } - ], - "needsWork": true, - "priority": "MEDIUM" - }, - "editable-table": { - "element": "editable-table", - "component": { - "properties": [ - { - "name": "editMode", - "type": "Boolean", - "attribute": "edit-mode", - "config": "type: Boolean,\n attribute: \"edit-mode\",\n reflect: true,", - "defaultValue": "false" - } - ], - "slots": [ - "default" - ], - "events": [ - "toggle-edit-mode" - ], - "methods": [ - "haxHooks", - "if", - "sync", - "focus", - "setTimeout", - "toggleEditMode" - ], - "hasHaxProperties": true, - "extendsLitElement": false, - "extendsOtherBehaviors": [ - "editBehaviors" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../editable-table.js\";\n\ndescribe(\"editable-table test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html`\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
    \n Is it a\n sandwich? Food classification chart.\n
    FoodEnclosureContentsOrientation
    Hamburgerone bun, split into twomeat, vegetables, cheese, and/or condimentshorizontal
    Hoagieone bunmeat, vegetables, cheese, and/or condimentsvertical
    Hot Dogone bunmeat, vegetables, cheese, and/or condimentsvertical
    Hot Pockettwo crusts sealed togethermeat, vegetables, cheese, and/or condimentshorizontal
    Pietwo crusts sealed togetherfruit or meat, vegetables, and/or cheesehorizontal
    Tacoone shellmeat, vegetables, cheese, and/or condimentsvertical
    \n `,\n );\n });\n\n it(\"passes the a11y audit\", () => {\n expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"editable-table passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"editable-table passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"editable-table can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: editMode" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: toggle-edit-mode" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "elmsln-loading": { - "element": "elmsln-loading", - "component": { - "properties": [ - { - "name": "dark", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,", - "defaultValue": "false" - }, - { - "name": "color", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "contrast", - "type": "Number", - "attribute": null, - "config": "type: Number," - }, - { - "name": "size", - "type": "String", - "attribute": null, - "config": "type: String,\n reflect: true,", - "defaultValue": "\"medium\"" - } - ], - "slots": [], - "events": [], - "methods": [ - "if" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../elmsln-loading.js\";\n/*\ndescribe(\"elmsln-loading test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html` `\n );\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"elmsln-loading passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"elmsln-loading passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"elmsln-loading can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: dark, color, contrast, size" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "enhanced-text": { - "element": "enhanced-text", - "component": { - "properties": [ - { - "name": "wikipedia", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "vide", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "fixationPoint", - "type": "Number", - "attribute": "fixation-point", - "config": "type: Number,\n attribute: \"fixation-point\",", - "defaultValue": "4" - }, - { - "name": "haxcmsGlossary", - "type": "Boolean", - "attribute": "haxcms-glossary", - "config": "type: Boolean,\n attribute: \"haxcms-glossary\",", - "defaultValue": "false" - }, - { - "name": "haxcmsSiteLocation", - "type": "String", - "attribute": "haxcms-site-location", - "config": "type: String,\n attribute: \"haxcms-site-location\",", - "defaultValue": "\"\"" - }, - { - "name": "haxcmsSite", - "type": "Object", - "attribute": "haxcms-site", - "config": "type: Object,\n attribute: \"haxcms-site\",", - "defaultValue": "null" - }, - { - "name": "haxcmsMarkAll", - "type": "Boolean", - "attribute": "haxcms-mark-all", - "config": "type: Boolean,\n attribute: \"haxcms-mark-all\",", - "defaultValue": "false" - }, - { - "name": "loading", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "auto", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true,", - "defaultValue": "false" - } - ], - "slots": [ - "default" - ], - "events": [], - "methods": [ - "if", - "applyTermFromList", - "for", - "enahncedTextResponse" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\nimport \"../enhanced-text.js\";\n\ndescribe(\"elementName test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html``);\n });\n\n it(\"basic will it blend\", async () => {\n expect(element).to.exist;\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: wikipedia, vide, fixationPoint, haxcmsGlossary, haxcmsSiteLocation, haxcmsSite, haxcmsMarkAll, loading, auto" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: fixation-point, haxcms-glossary, haxcms-site-location, haxcms-site, haxcms-mark-all" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "es-global-bridge": { - "element": "es-global-bridge", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [ - "if" - ], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": false, - "hasAccessibilityTests": false, - "testedProperties": [], - "testedSlots": [], - "testedEvents": [], - "testedMethods": [] - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_TEST_FILE", - "message": "No test file found. Create test/${elementName}.test.js" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "event-badge": { - "element": "event-badge", - "component": { - "properties": [ - { - "name": "title", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "\"haxor\"" - }, - { - "name": "image", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "\"https://avatars1.githubusercontent.com/u/329735?s=400&v=4\"" - }, - { - "name": "name", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "\"bto.pro\"" - }, - { - "name": "position", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "\"1337 dev\"" - }, - { - "name": "logo", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "null" - }, - { - "name": "organization", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "\"Penn State\"" - }, - { - "name": "tvcolor", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "\"light-blue\"" - }, - { - "name": "knobcolor", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "\"purple\"" - }, - { - "name": "sepia", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "blackwhite", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true,", - "defaultValue": "false" - } - ], - "slots": [], - "events": [], - "methods": [], - "hasHaxProperties": true, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../event-badge.js\";\n\ndescribe(\"event-badge test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html` `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: title, image, name, position, logo, organization, tvcolor, knobcolor, sepia, blackwhite" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "example-hax-element": { - "element": "example-hax-element", - "component": { - "properties": [ - { - "name": "title", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "\"\"" - } - ], - "slots": [ - "default" - ], - "events": [], - "methods": [], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "DDDSuper" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { html, fixture, expect } from '@open-wc/testing';\nimport \"../example-hax-element.js\";\n\ndescribe(\"ExampleHaxElement test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"basic will it blend\", async () => {\n expect(element).to.exist;\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: title" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "example-haxcms-theme": { - "element": "example-haxcms-theme", - "component": { - "properties": [ - { - "name": "activeId", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "null" - }, - { - "name": "_items", - "type": "Array", - "attribute": null, - "config": "type: Array", - "defaultValue": "[]" - } - ], - "slots": [], - "events": [], - "methods": [ - "HAXCMSGlobalStyleSheetContent" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { html, fixture, expect } from '@open-wc/testing';\nimport \"../example-haxcms-theme.js\";\n\ndescribe(\"ExampleHaxcmsTheme test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"basic will it blend\", async () => {\n expect(element).to.exist;\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: activeId, _items" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "figure-label": { - "element": "figure-label", - "component": { - "properties": [ - { - "name": "title", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "description", - "type": "String", - "attribute": null, - "config": "type: String," - } - ], - "slots": [], - "events": [], - "methods": [], - "hasHaxProperties": true, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../figure-label.js\";\n\ndescribe(\"figure-label test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"figure-label passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"figure-label passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"figure-label can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: title, description" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "file-system-broker": { - "element": "file-system-broker", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [ - "typeToAccept", - "switch", - "if" - ], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../file-system-broker.js\";\n\ndescribe(\"file-system-broker test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"file-system-broker passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"file-system-broker passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"file-system-broker can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "fill-in-the-blanks": { - "element": "fill-in-the-blanks", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [ - "renderDirections", - "isCorrect", - "for", - "if", - "resetAnswer", - "guessCount", - "rebuildWordList", - "renderInteraction", - "shuffleArray", - "refreshEvent", - "renderFillInBlankField" - ], - "hasHaxProperties": true, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": false, - "hasAccessibilityTests": false, - "testedProperties": [], - "testedSlots": [], - "testedEvents": [], - "testedMethods": [] - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_TEST_FILE", - "message": "No test file found. Create test/${elementName}.test.js" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "flash-card": { - "element": "flash-card", - "component": { - "properties": [ - { - "name": "inverted", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean" - }, - { - "name": "imgSource", - "type": "String", - "attribute": "img-source", - "config": "type: String, attribute: \"img-source\", reflect: true", - "defaultValue": "\"\"" - }, - { - "name": "imgKeyword", - "type": "String", - "attribute": "img-keyword", - "config": "type: String, attribute: \"img-keyword\"", - "defaultValue": "\"\"" - }, - { - "name": "status", - "type": "String", - "attribute": null, - "config": "type: String, reflect: true" - } - ], - "slots": [], - "events": [], - "methods": [ - "statusChanged", - "if" - ], - "hasHaxProperties": true, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\nimport \"../flash-card.js\";\n\ndescribe(\"elementName test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html``);\n });\n\n it(\"basic will it blend\", async () => {\n expect(element).to.exist;\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: inverted, imgSource, imgKeyword, status" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: img-source, img-keyword" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "fluid-type": { - "element": "fluid-type", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [ - "if" - ], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../fluid-type.js\";\n\ndescribe(\"fluid-type test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"fluid-type passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"fluid-type passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"fluid-type can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "full-width-image": { - "element": "full-width-image", - "component": { - "properties": [ - { - "name": "source", - "type": "String", - "attribute": null, - "config": "type: String,\n reflect: true," - }, - { - "name": "caption", - "type": "String", - "attribute": null, - "config": "type: String,\n reflect: true," - } - ], - "slots": [ - "default" - ], - "events": [], - "methods": [ - "if" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../full-width-image.js\";\n\ndescribe(\"full-width-image test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"full-width-image passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"full-width-image passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"full-width-image can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: source, caption" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "fullscreen-behaviors": { - "element": "fullscreen-behaviors", - "component": { - "properties": [ - { - "name": "fullscreen", - "type": "Boolean", - "attribute": "fullscreen", - "config": "type: Boolean, attribute: \"fullscreen\", reflect: true", - "defaultValue": "false" - }, - { - "name": "fullscreenEnabled", - "type": "Boolean", - "attribute": "fullscreen-enabled", - "config": "type: Boolean,\n attribute: \"fullscreen-enabled\",\n reflect: true,", - "defaultValue": "globalThis.document.fullscreenEnabled" - } - ], - "slots": [ - "default" - ], - "events": [], - "methods": [ - "toggleFullscreen" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "FullscreenBehaviors" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../fullscreen-behaviors.js\";\n\ndescribe(\"fullscreen-behaviors test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"fullscreen-behaviors passes accessibility test\", async () => {\n const el = await fixture(\n html` `\n );\n await expect(el).to.be.accessible();\n });\n it(\"fullscreen-behaviors passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"fullscreen-behaviors can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: fullscreen, fullscreenEnabled" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "future-terminal-text": { - "element": "future-terminal-text", - "component": { - "properties": [], - "slots": [ - "default" - ], - "events": [], - "methods": [], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [ - "SimpleColorsSuper" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\nimport \"../future-terminal-text.js\";\n\ndescribe(\"elementName test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html``,\n );\n });\n\n it(\"basic will it blend\", async () => {\n expect(element).to.exist;\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [ - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ], - "needsWork": true, - "priority": "MEDIUM" - }, - "git-corner": { - "element": "git-corner", - "component": { - "properties": [ - { - "name": "source", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "null" - }, - { - "name": "alt", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "null" - }, - { - "name": "corner", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true," - }, - { - "name": "size", - "type": "String", - "attribute": null, - "config": "type: String,\n reflect: true," - } - ], - "slots": [], - "events": [], - "methods": [], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../git-corner.js\";\n\ndescribe(\"git-corner test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"git-corner passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"git-corner passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"git-corner can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: source, alt, corner, size" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "github-preview": { - "element": "github-preview", - "component": { - "properties": [ - { - "name": "repo", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "org", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "__description", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "repoLang", - "type": "String", - "attribute": "repo-lang", - "config": "type: String,\n attribute: \"repo-lang\",\n reflect: true," - }, - { - "name": "__stars", - "type": "Number", - "attribute": null, - "config": "type: Number," - }, - { - "name": "__forks", - "type": "Number", - "attribute": null, - "config": "type: Number," - }, - { - "name": "__assetAvailable", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean," - }, - { - "name": "extended", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "readmeExtended", - "type": "Boolean", - "attribute": "readme-extended", - "config": "type: Boolean,\n attribute: \"readme-extended\",\n reflect: true," - }, - { - "name": "headers", - "type": "Object", - "attribute": null, - "config": "type: Object," - }, - { - "name": "viewMoreText", - "type": "String", - "attribute": "view-more-text", - "config": "type: String,\n attribute: \"view-more-text\",", - "defaultValue": "\"View More\"" - }, - { - "name": "notFoundText", - "type": "String", - "attribute": "not-found-text", - "config": "type: String,\n attribute: \"not-found-text\",", - "defaultValue": "\"Asset not found\"" - }, - { - "name": "__readmeText", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "branch", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"master\"" - }, - { - "name": "url", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"https://github.com\"" - }, - { - "name": "apiUrl", - "type": "String", - "attribute": "api-url", - "config": "type: String,\n attribute: \"api-url\",", - "defaultValue": "\"https://api.github.com\"" - }, - { - "name": "rawUrl", - "type": "String", - "attribute": "raw-url", - "config": "type: String,\n attribute: \"raw-url\",", - "defaultValue": "\"https://raw.githubusercontent.com\"" - }, - { - "name": "readMe", - "type": "String", - "attribute": "read-me", - "config": "type: String,\n attribute: \"read-me\",", - "defaultValue": "\"README.md\"" - } - ], - "slots": [], - "events": [ - "hax-register-app" - ], - "methods": [ - "if", - "fetchGithubData", - "readmeViewMoreHandler", - "handleResponse", - "haxHooks", - "haxgizmoRegistration", - "haxactiveElementChanged", - "haxeditModeChanged" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "IntersectionObserverMixin" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../github-preview.js\";\n\ndescribe(\"github-preview test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"github-preview passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"github-preview passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"github-preview can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: repo, org, __description, repoLang, __stars, __forks, __assetAvailable, extended, readmeExtended, headers, viewMoreText, notFoundText, __readmeText, branch, url, apiUrl, rawUrl, readMe" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: hax-register-app" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "glossy-portfolio-theme": { - "element": "glossy-portfolio-theme", - "component": { - "properties": [ - { - "name": "title", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "\"\"" - }, - { - "name": "siteDescription", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "relatedItem", - "type": "Object", - "attribute": null, - "config": "type: Object" - }, - { - "name": "isHome", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean", - "defaultValue": "false" - }, - { - "name": "items", - "type": "Object", - "attribute": null, - "config": "type: Object" - } - ], - "slots": [], - "events": [], - "methods": [ - "if", - "for" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "DDDSuper" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { html, fixture, expect } from '@open-wc/testing';\nimport \"../glossy-portfolio-theme.js\";\n\ndescribe(\"GlossyPortfolioTheme test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"basic will it blend\", async () => {\n expect(element).to.exist;\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: title, siteDescription, relatedItem, isHome, items" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "grade-book": { - "element": "grade-book", - "component": { - "properties": [ - { - "name": "displayMode", - "type": "Number", - "attribute": null, - "config": "type: Number" - }, - { - "name": "settings", - "type": "Object", - "attribute": null, - "config": "type: Object" - }, - { - "name": "disabled", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean, reflect: true" - }, - { - "name": "loading", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean, reflect: true" - }, - { - "name": "ready", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean, reflect: true" - }, - { - "name": "activeStudent", - "type": "Number", - "attribute": "active-student", - "config": "type: Number, attribute: \"active-student\"" - }, - { - "name": "activeAssignment", - "type": "Number", - "attribute": "active-assignment", - "config": "type: Number, attribute: \"active-assignment\"" - }, - { - "name": "totalScore", - "type": "Number", - "attribute": null, - "config": "type: Number" - }, - { - "name": "scoreLock", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean" - }, - { - "name": "source", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "\"googledocs\"" - }, - { - "name": "sourceData", - "type": "String", - "attribute": "source-data", - "config": "type: String, attribute: \"source-data\"" - }, - { - "name": "activeSubmission", - "type": "String", - "attribute": null, - "config": "type: String, attribute: false" - }, - { - "name": "database", - "type": "Object", - "attribute": null, - "config": "type: Object, attribute: false" - }, - { - "name": "activeRubric", - "type": "Object", - "attribute": null, - "config": "type: Object, attribute: false" - }, - { - "name": "assessmentView", - "type": "Object", - "attribute": null, - "config": "type: Object, attribute: false" - }, - { - "name": "activeGrading", - "type": "Object", - "attribute": null, - "config": "type: Object, attribute: false" - }, - { - "name": "activeStudentSubmissions", - "type": "Array", - "attribute": null, - "config": "type: Array" - } - ], - "slots": [ - "app-name" - ], - "events": [ - "simple-tag-drop", - "simple-tag-dragstart" - ], - "methods": [ - "if", - "for", - "resetAssessmentView", - "getStudentSubmissions", - "getAssignmentByShortName", - "getCurrentScore", - "getActiveRubric", - "switch", - "importStateCleanup", - "transformTable", - "maintainScrollPosition", - "processassignmentsData", - "processtagsData", - "processrubricsData", - "processrosterData", - "processsettingsData", - "renderSubmission", - "studentLetterGradeHistoryClick", - "activateOption", - "mouseHighlight", - "mouseLeave", - "settingChanged", - "handleGridScaling", - "checkTabHeight", - "studentreportClick", - "openWindow", - "renderSubmissionInWindow", - "selectSource", - "loadFromSource", - "loadFromExistingSource", - "loadFromFilesystem", - "rubricCriteriaPointsChange", - "updateTotalScore", - "totalScoreChangedEvent", - "toggleLock", - "updateStudentReport", - "getCriteriaScore", - "getCriteriaFeedback", - "qualitativeFeedbackUpdate", - "keyDown", - "pickColor", - "while", - "setDragTransfer" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "UIRenderPieces" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../grade-book.js\";\n\ndescribe(\"grade-book test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html` \n `,\n );\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"grade-book passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"grade-book passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"grade-book can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: displayMode, settings, disabled, loading, ready, activeStudent, activeAssignment, totalScore, scoreLock, source, sourceData, activeSubmission, database, activeRubric, assessmentView, activeGrading, activeStudentSubmissions" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: app-name" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: simple-tag-drop, simple-tag-dragstart" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "grid-plate": { - "element": "grid-plate", - "component": { - "properties": [ - { - "name": "itemPadding", - "type": "Number", - "attribute": "item-padding", - "config": "type: Number,\n reflect: true,\n attribute: \"item-padding\"," - }, - { - "name": "itemMargin", - "type": "Number", - "attribute": "item-margin", - "config": "type: Number,\n reflect: true,\n attribute: \"item-margin\"," - }, - { - "name": "breakpointSm", - "type": "Number", - "attribute": "breakpoint-sm", - "config": "type: Number,\n attribute: \"breakpoint-sm\"," - }, - { - "name": "breakpointMd", - "type": "Number", - "attribute": "breakpoint-md", - "config": "type: Number,\n attribute: \"breakpoint-md\"," - }, - { - "name": "breakpointLg", - "type": "Number", - "attribute": "breakpoint-lg", - "config": "type: Number,\n attribute: \"breakpoint-lg\"," - }, - { - "name": "breakpointXl", - "type": "Number", - "attribute": "breakpoint-xl", - "config": "type: Number,\n attribute: \"breakpoint-xl\"," - }, - { - "name": "columns", - "type": "Number", - "attribute": null, - "config": "type: Number,\n reflect: true," - }, - { - "name": "dataHaxRay", - "type": "String", - "attribute": "data-hax-ray", - "config": "type: String,\n attribute: \"data-hax-ray\",\n reflect: true," - }, - { - "name": "disableResponsive", - "type": "Boolean", - "attribute": "disable-responsive", - "config": "type: Boolean,\n reflect: true,\n attribute: \"disable-responsive\"," - }, - { - "name": "layout", - "type": "String", - "attribute": null, - "config": "type: String,\n reflect: true," - } - ], - "slots": [ - "col-${num}" - ], - "events": [ - "responsive-element", - "disable-responsive-changed", - "resize" - ], - "methods": [ - "for", - "switch", - "if", - "resize", - "haxactiveElementChanged" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../grid-plate.js\";\n\ndescribe(\"grid-plate test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"grid-plate passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"grid-plate passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"grid-plate can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: itemPadding, itemMargin, breakpointSm, breakpointMd, breakpointLg, breakpointXl, columns, dataHaxRay, disableResponsive, layout" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: col-${num}" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: responsive-element, disable-responsive-changed, resize" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "h-a-x": { - "element": "h-a-x", - "component": { - "properties": [], - "slots": [], - "events": [ - "hax-save-body-value" - ], - "methods": [ - "if", - "cancelEvent", - "storeReady", - "importSlotToHaxBody", - "for", - "appStoreReady", - "applyHAX", - "attributeChangedCallback" - ], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../h-a-x.js\";\ndescribe(\"h-a-x test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html` \n

    This is h-a-x

    \n
      \n
    • You'll love this because...
    • \n
    • You'll love this because...
    • \n
    \n

    This is h-a-x

    \n

    This is h-a-x

    \n `,\n );\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"h-a-x passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"h-a-x passes accessibility negation\", async () => {\n const el = await fixture(html``);\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"h-a-x can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: hax-save-body-value" - } - ], - "needsWork": true, - "priority": "MEDIUM" - }, - "h5p-element": { - "element": "h5p-element", - "component": { - "properties": [ - { - "name": "source", - "type": "String", - "attribute": null, - "config": "name: \"source\",\n type: String," - } - ], - "slots": [ - "default" - ], - "events": [], - "methods": [ - "setTimeout", - "createRenderRoot", - "if", - "generateUUID", - "for", - "h5pReadyCallback", - "getJSONPromise", - "libraryPath", - "findMainLibrary", - "findAllDependencies", - "add", - "sort", - "clear" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../h5p-element.js\";\n\ndescribe(\"h5p-element test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"h5p-element passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"h5p-element passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"h5p-element can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: source" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "hal-9000": { - "element": "hal-9000", - "component": { - "properties": [ - { - "name": "toast", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "commands", - "type": "Object", - "attribute": null, - "config": "name: \"commands\",\n type: Object," - }, - { - "name": "respondsTo", - "type": "String", - "attribute": "responds-to", - "config": "name: \"respondsTo\",\n type: String,\n attribute: \"responds-to\"," - }, - { - "name": "debug", - "type": "Boolean", - "attribute": null, - "config": "name: \"debug\",\n type: Boolean," - }, - { - "name": "auto", - "type": "Boolean", - "attribute": null, - "config": "name: \"auto\",\n type: Boolean,\n reflect: true," - }, - { - "name": "enabled", - "type": "Boolean", - "attribute": null, - "config": "name: \"enabled\",\n type: Boolean,\n reflect: true," - }, - { - "name": "pitch", - "type": "Number", - "attribute": null, - "config": "name: \"pitch\",\n type: Number,\n reflect: true," - }, - { - "name": "rate", - "type": "Number", - "attribute": null, - "config": "name: \"rate\",\n type: Number,\n reflect: true," - }, - { - "name": "language", - "type": "String", - "attribute": null, - "config": "name: \"language\",\n type: String,\n reflect: true," - } - ], - "slots": [], - "events": [ - "super-daemon-toast-hide", - "super-daemon-toast-show" - ], - "methods": [ - "for", - "if", - "addCommands", - "speak", - "setToast" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../hal-9000.js\";\n\ndescribe(\"hal-9000 test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html` `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"hal-9000 passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"hal-9000 passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"hal-9000 can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: toast, commands, respondsTo, debug, auto, enabled, pitch, rate, language" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: super-daemon-toast-hide, super-daemon-toast-show" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "hax-body": { - "element": "hax-body", - "component": { - "properties": [ - { - "name": "_useristyping", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,", - "defaultValue": "false" - }, - { - "name": "haxMover", - "type": "Boolean", - "attribute": "hax-mover", - "config": "type: Boolean,\n attribute: \"hax-mover\",\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "editMode", - "type": "Boolean", - "attribute": "edit-mode", - "config": "type: Boolean,\n reflect: true,\n attribute: \"edit-mode\",", - "defaultValue": "false" - }, - { - "name": "elementAlign", - "type": "String", - "attribute": "element-align", - "config": "type: String,\n reflect: true,\n attribute: \"element-align\"," - }, - { - "name": "trayDetail", - "type": "String", - "attribute": "tray-detail", - "config": "type: String,\n reflect: true,\n attribute: \"tray-detail\"," - }, - { - "name": "trayStatus", - "type": "String", - "attribute": "tray-status", - "config": "type: String,\n reflect: true,\n attribute: \"tray-status\"," - }, - { - "name": "activeNode", - "type": "Object", - "attribute": null, - "config": "type: Object,", - "defaultValue": "null" - }, - { - "name": "canMoveElement", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean," - }, - { - "name": "viewSourceToggle", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true,", - "defaultValue": "false" - } - ], - "slots": [ - "default" - ], - "events": [ - "hax-register-body", - "place-holder-file-drop", - "hax-drop-focus-event" - ], - "methods": [ - "if", - "dragEndBody", - "scrollerFixclickEvent", - "blurEvent", - "dragEnterBody", - "revealMenuIfHidden", - "calcClasses", - "HAXBODYStyleSheetContent", - "switch", - "keyboardShortCutProcess", - "setActiveNode", - "elementMidViewport", - "replacePlaceholder", - "getAllSlotConfig", - "getParentGrid", - "getSlotConfig", - "for", - "haxClearBody", - "haxInsert", - "hideContextMenus", - "positionContextMenus", - "haxMoveGridPlate", - "haxReplaceNode", - "haxChangeTagName", - "haxDeleteNode", - "importContent", - "while", - "sortGridSlots", - "scrollHere", - "undo", - "redo", - "function", - "undoManagerStackLogic", - "dropEvent", - "dragEnter", - "handleMousemove", - "dragLeave", - "toggleElementEditMode", - "unsetElementEditMode", - "setElementEditMode", - "unsetSlotEditMode", - "setSlotEditMode" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "I18NMixin" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../hax-body.js\";\n/*\ndescribe(\"hax-body test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html` `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n*/\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"hax-body passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"hax-body passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"hax-body can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: _useristyping, haxMover, editMode, elementAlign, trayDetail, trayStatus, activeNode, canMoveElement, viewSourceToggle" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: hax-register-body, place-holder-file-drop, hax-drop-focus-event" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "hax-body-behaviors": { - "element": "hax-body-behaviors", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../hax-body-behaviors.js\";\n\ndescribe(\"hax-body-behaviors test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"hax-body-behaviors passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"hax-body-behaviors passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"hax-body-behaviors can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "hax-bookmarklet": { - "element": "hax-bookmarklet", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../hax-bookmarklet.js\";\n\ndescribe(\"hax-bookmarklet test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"hax-bookmarklet passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"hax-bookmarklet passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"hax-bookmarklet can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "hax-cloud": { - "element": "hax-cloud", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [ - "createRenderRoot", - "if", - "loadLocalHax" - ], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\nimport \"../hax-cloud.js\";\n\ndescribe(\"elementName test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html``);\n });\n\n it(\"basic will it blend\", async () => {\n expect(element).to.exist;\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "hax-iconset": { - "element": "hax-iconset", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../hax-iconset.js\";\n\ndescribe(\"hax-iconset test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"hax-iconset passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"hax-iconset passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"hax-iconset can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "hax-logo": { - "element": "hax-logo", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [ - "if" - ], - "hasHaxProperties": true, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../hax-logo.js\";\n\ndescribe(\"hax-logo test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html` `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"hax-logo passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"hax-logo passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"hax-logo can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "haxcms-elements": { - "element": "haxcms-elements", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "// local development and mobx\nimport { fixture, expect, html } from \"@open-wc/testing\";\nimport \"@haxtheweb/haxcms-elements/lib/core/haxcms-site-builder.js\";\ndescribe(\"haxcms-elements test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html``,\n );\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"haxcms-elements passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"haxcms-elements passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"haxcms-elements can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "haxor-slevin": { - "element": "haxor-slevin", - "component": { - "properties": [ - { - "name": "color", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "selectedPage", - "type": "Number", - "attribute": "selected-page", - "config": "type: Number,\n reflect: true,\n attribute: \"selected-page\"," - }, - { - "name": "activeManifestIndexCounter", - "type": "Number", - "attribute": null, - "config": "type: Number," - }, - { - "name": "activeItem", - "type": "Object", - "attribute": null, - "config": "type: Object," - }, - { - "name": "stateClass", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "__mainPosts", - "type": "Array", - "attribute": null, - "config": "type: Array,", - "defaultValue": "[]" - }, - { - "name": "__followUpPosts", - "type": "Array", - "attribute": null, - "config": "type: Array,", - "defaultValue": "[]" - } - ], - "slots": [], - "events": [ - "resize" - ], - "methods": [ - "if", - "siteModalClick", - "for" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "HAXCMSThemeParts" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../haxor-slevin.js\";\n/*\ndescribe(\"haxor-slevin test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html` `\n );\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n*/\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"haxor-slevin passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"haxor-slevin passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"haxor-slevin can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: color, selectedPage, activeManifestIndexCounter, activeItem, stateClass, __mainPosts, __followUpPosts" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: resize" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "hex-picker": { - "element": "hex-picker", - "component": { - "properties": [ - { - "name": "value", - "type": "String", - "attribute": null, - "config": "type: String,\n reflect: true,", - "defaultValue": "\"#000000FF\"" - }, - { - "name": "disabled", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "largeDisplay", - "type": "Boolean", - "attribute": "large-display", - "config": "type: Boolean,\n reflect: true,\n attribute: \"large-display\"," - } - ], - "slots": [], - "events": [ - "value-changed" - ], - "methods": [ - "if", - "renderFieldSet" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../hex-picker.js\";\n\ndescribe(\"hex-picker test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"hex-picker passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"hex-picker passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"hex-picker can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: value, disabled, largeDisplay" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: value-changed" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "hexagon-loader": { - "element": "hexagon-loader", - "component": { - "properties": [ - { - "name": "color", - "type": "String", - "attribute": null, - "config": "name: \"color\",\n type: String,\n reflect: true," - }, - { - "name": "size", - "type": "String", - "attribute": null, - "config": "name: \"size\",\n type: String,\n reflect: true," - }, - { - "name": "loading", - "type": "Boolean", - "attribute": null, - "config": "name: \"loading\",\n type: Boolean,\n reflect: true," - }, - { - "name": "items", - "type": "Array", - "attribute": null, - "config": "name: \"items\",\n type: Array,", - "defaultValue": "[]" - }, - { - "name": "itemCount", - "type": "Number", - "attribute": "item-count", - "config": "name: \"itemCount\",\n type: Number,\n reflect: true,\n attribute: \"item-count\",", - "defaultValue": "37" - } - ], - "slots": [], - "events": [], - "methods": [ - "if", - "for" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../hexagon-loader.js\";\n\ndescribe(\"hexagon-loader test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"hexagon-loader passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"hexagon-loader passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"hexagon-loader can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: color, size, loading, items, itemCount" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "html-block": { - "element": "html-block", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [ - "if", - "attributeChangedCallback" - ], - "hasHaxProperties": true, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../html-block.js\";\n\ndescribe(\"html-block test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"html-block passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"html-block passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"html-block can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "i18n-manager": { - "element": "i18n-manager", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [ - "if", - "changeLanguageEvent", - "registerLocalizationEvent", - "detailNormalize", - "registerLocalization", - "for", - "attributeChangedCallback" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../i18n-manager.js\";\n\ndescribe(\"i18n-manager test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"i18n-manager passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"i18n-manager passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"i18n-manager can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "iframe-loader": { - "element": "iframe-loader", - "component": { - "properties": [ - { - "name": "loading", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean", - "defaultValue": "true" - }, - { - "name": "height", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "500" - }, - { - "name": "width", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "\"100%\"" - }, - { - "name": "isPDF", - "type": "Boolean", - "attribute": "is-pdf", - "config": "type: Boolean,\n reflect: true,\n attribute: \"is-pdf\",", - "defaultValue": "false" - }, - { - "name": "disabled", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "source", - "type": "String", - "attribute": null, - "config": "type: String,\n reflect: true,", - "defaultValue": "this.__iframe.getAttribute(\"src\")" - } - ], - "slots": [ - "default" - ], - "events": [], - "methods": [ - "if", - "iframeLoadingCallback", - "haxHooks", - "haxactiveElementChanged", - "haxeditModeChanged" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../iframe-loader.js\";\n\ndescribe(\"iframe-loader test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html` \n \n `,\n );\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"iframe-loader passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"iframe-loader passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"iframe-loader can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: loading, height, width, isPDF, disabled, source" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "image-compare-slider": { - "element": "image-compare-slider", - "component": { - "properties": [ - { - "name": "bottomAlt", - "type": "String", - "attribute": "bottom-alt", - "config": "type: String,\n attribute: \"bottom-alt\",", - "defaultValue": "\"\"" - }, - { - "name": "bottomDescriptionId", - "type": "String", - "attribute": "bottom-description-id", - "config": "type: String,\n attribute: \"bottom-description-id\"," - }, - { - "name": "bottomSrc", - "type": "String", - "attribute": "bottom-src", - "config": "type: String,\n attribute: \"bottom-src\"," - }, - { - "name": "opacity", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,", - "defaultValue": "false" - }, - { - "name": "position", - "type": "Number", - "attribute": null, - "config": "type: Number,", - "defaultValue": "50" - }, - { - "name": "title", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "topAlt", - "type": "String", - "attribute": "top-alt", - "config": "type: String,\n attribute: \"top-alt\",", - "defaultValue": "\"\"" - }, - { - "name": "topDescriptionId", - "type": "String", - "attribute": "top-description-id", - "config": "type: String,\n attribute: \"top-description-id\"," - }, - { - "name": "topSrc", - "type": "String", - "attribute": "top-src", - "config": "type: String,\n attribute: \"top-src\"," - } - ], - "slots": [], - "events": [], - "methods": [ - "if" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "I18NMixin" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": true, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\nimport \"../image-compare-slider.js\";\ndescribe(\"Image comparison\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html` \n

    Default Compare Mode

    \n
    \n The slider will fade away the top image\n (Matterhorn on a cloudy day without snow)\n to reveal the bottom image\n (Matterhorn on a clear day with snow).\n
    \n `,\n );\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: bottomAlt, bottomDescriptionId, bottomSrc, opacity, position, title, topAlt, topDescriptionId, topSrc" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: bottom-alt, bottom-description-id, bottom-src, top-alt, top-description-id, top-src" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "image-inspector": { - "element": "image-inspector", - "component": { - "properties": [ - { - "name": "noLeft", - "type": "Boolean", - "attribute": "no-left", - "config": "type: Boolean,\n attribute: \"no-left\",", - "defaultValue": "false" - }, - { - "name": "degrees", - "type": "Number", - "attribute": null, - "config": "type: Number,\n reflect: true,", - "defaultValue": "0" - }, - { - "name": "src", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"\"" - }, - { - "name": "hoverClass", - "type": "String", - "attribute": "hover-class", - "config": "type: String,\n attribute: \"hover-class\"," - } - ], - "slots": [ - "toolbar", - "default" - ], - "events": [], - "methods": [ - "if", - "rotateRight", - "mirrorImage", - "zoomIn", - "zoomOut" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../image-inspector.js\";\n\ndescribe(\"image-inspector test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html``,\n );\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"image-inspector passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"image-inspector passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"image-inspector can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: noLeft, degrees, src, hoverClass" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: toolbar, default" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "img-pan-zoom": { - "element": "img-pan-zoom", - "component": { - "properties": [ - { - "name": "src", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "sources", - "type": "Array", - "attribute": null, - "config": "type: Array," - }, - { - "name": "page", - "type": "Number", - "attribute": "page", - "config": "type: Number,\n attribute: \"page\",", - "defaultValue": "0" - }, - { - "name": "describedBy", - "type": "String", - "attribute": "described-by", - "config": "type: String,\n attribute: \"described-by\"," - }, - { - "name": "dzi", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,", - "defaultValue": "false" - }, - { - "name": "fadeIn", - "type": "Boolean", - "attribute": "fade-in", - "config": "type: Boolean,\n attribute: \"fade-in\",", - "defaultValue": "true" - }, - { - "name": "fullscreenToggled", - "type": "Boolean", - "attribute": "fullscreen-toggled", - "config": "type: Boolean,\n attribute: \"fullscreen-toggled\",\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "flipToggled", - "type": "Boolean", - "attribute": "flip-toggled", - "config": "type: Boolean,\n attribute: \"flip-toggled\",\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "loading", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,", - "defaultValue": "false" - }, - { - "name": "hideSpinner", - "type": "Boolean", - "attribute": "hide-spinner", - "config": "type: Boolean,\n attribute: \"hide-spinner\",", - "defaultValue": "false" - }, - { - "name": "loaded", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean," - }, - { - "name": "showNavigationControl", - "type": "Boolean", - "attribute": "show-navigation-control", - "config": "type: Boolean,\n attribute: \"show-navigation-control\",", - "defaultValue": "false" - }, - { - "name": "showNavigator", - "type": "Boolean", - "attribute": "show-navigator", - "config": "type: Boolean,\n attribute: \"show-navigator\",", - "defaultValue": "false" - }, - { - "name": "zoomPerClick", - "type": "Number", - "attribute": "zoom-per-click", - "config": "type: Number,\n attribute: \"zoom-per-click\",", - "defaultValue": "2.0" - }, - { - "name": "zoomPerScroll", - "type": "Number", - "attribute": "zoom-per-scroll", - "config": "type: Number,\n attribute: \"zoom-per-scroll\",", - "defaultValue": "1.2" - }, - { - "name": "animationTime", - "type": "Number", - "attribute": "animation-time", - "config": "type: Number,\n attribute: \"animation-time\",", - "defaultValue": "1.2" - }, - { - "name": "navPrevNextWrap", - "type": "Boolean", - "attribute": "nav-prev-next-wrap", - "config": "type: Boolean,\n attribute: \"nav-prev-next-wrap\",", - "defaultValue": "false" - }, - { - "name": "showRotationControl", - "type": "Boolean", - "attribute": "show-rotation-control", - "config": "type: Boolean,\n attribute: \"show-rotation-control\",", - "defaultValue": "false" - }, - { - "name": "minZoomImageRatio", - "type": "Number", - "attribute": "min-zoom-image-ratio", - "config": "type: Number,\n attribute: \"min-zoom-image-ratio\",", - "defaultValue": "1" - }, - { - "name": "maxZoomPixelRatio", - "type": "Number", - "attribute": "max-zoom-pixel-ratio", - "config": "type: Number,\n attribute: \"max-zoom-pixel-ratio\",", - "defaultValue": "1.1" - }, - { - "name": "constrainDuringPan", - "type": "Boolean", - "attribute": "constrain-during-pan", - "config": "type: Boolean,\n attribute: \"constrain-during-pan\",", - "defaultValue": "false" - }, - { - "name": "visibilityRatio", - "type": "Number", - "attribute": "visibility-ratio", - "config": "type: Number,\n attribute: \"visibility-ratio\",", - "defaultValue": "1" - }, - { - "name": "navigatorAutoFade", - "type": "Boolean", - "attribute": "navigator-auto-fade", - "config": "type: Boolean,\n attribute: \"navigator-auto-fade\",\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "navigatorPosition", - "type": "String", - "attribute": "navigator-position", - "config": "type: String,\n attribute: \"navigator-position\",\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "navigatorTop", - "type": "String", - "attribute": "navigator-top", - "config": "type: String, attribute: \"navigator-top\", reflect: true" - }, - { - "name": "navigatorBottom", - "type": "String", - "attribute": "navigator-bottom", - "config": "type: String,\n attribute: \"navigator-bottom\",\n reflect: true," - }, - { - "name": "navigatorLeft", - "type": "String", - "attribute": "navigator-left", - "config": "type: String,\n attribute: \"navigator-left\",\n reflect: true," - }, - { - "name": "navigatorRight", - "type": "String", - "attribute": "navigator-right", - "config": "type: String,\n attribute: \"navigator-right\",\n reflect: true," - }, - { - "name": "navigatorHeight", - "type": "String", - "attribute": "navigator-height", - "config": "type: String,\n attribute: \"navigator-height\",\n reflect: true," - }, - { - "name": "navigatorWidth", - "type": "String", - "attribute": "navigator-width", - "config": "type: String,\n attribute: \"navigator-width\",\n reflect: true," - }, - { - "name": "navigatorToggled", - "type": "Boolean", - "attribute": "navigator-toggled", - "config": "type: Boolean,\n attribute: \"navigator-toggled\",\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "sequenceMode", - "type": "Boolean", - "attribute": "sequence-mode", - "config": "type: Boolean, attribute: \"sequence-mode\"", - "defaultValue": "false" - }, - { - "name": "preserveViewport", - "type": "Boolean", - "attribute": "preserve-viewport", - "config": "type: Boolean, attribute: \"preserve-viewport\"", - "defaultValue": "false" - }, - { - "name": "showReferenceStrip", - "type": "Boolean", - "attribute": "show-reference-strip", - "config": "type: Boolean, attribute: \"show-reference-strip\"", - "defaultValue": "false" - }, - { - "name": "referenceStripScroll", - "type": "String", - "attribute": "reference-strip-scroll", - "config": "type: String,\n attribute: \"reference-strip-scroll\",", - "defaultValue": "\"horizontal\"" - }, - { - "name": "previousButton", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "nextButton", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "homeButton", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "zoomInButton", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "zoomOutButton", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "fullScreenButton", - "type": "String", - "attribute": null, - "config": "type: String" - } - ], - "slots": [], - "events": [ - "loading-changed", - "loaded-changed", - "zoom", - "page", - "pan", - "update-viewport", - "viewport-changed" - ], - "methods": [ - "if", - "destroy", - "rotateTo", - "rotate", - "pan", - "zoomIn", - "zoomOut", - "toggleFullscreen", - "toggleFlip", - "resetZoom", - "loadedChangedEvent", - "loadingChangedEvent" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../img-pan-zoom.js\";\n\ndescribe(\"img-pan-zoom test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"img-pan-zoom passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"img-pan-zoom passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"img-pan-zoom can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: src, sources, page, describedBy, dzi, fadeIn, fullscreenToggled, flipToggled, loading, hideSpinner, loaded, showNavigationControl, showNavigator, zoomPerClick, zoomPerScroll, animationTime, navPrevNextWrap, showRotationControl, minZoomImageRatio, maxZoomPixelRatio, constrainDuringPan, visibilityRatio, navigatorAutoFade, navigatorPosition, navigatorTop, navigatorBottom, navigatorLeft, navigatorRight, navigatorHeight, navigatorWidth, navigatorToggled, sequenceMode, preserveViewport, showReferenceStrip, referenceStripScroll, previousButton, nextButton, homeButton, zoomInButton, zoomOutButton, fullScreenButton" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: loading-changed, loaded-changed, zoom, page, pan, update-viewport, viewport-changed" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "img-view-modal": { - "element": "img-view-modal", - "component": { - "properties": [ - { - "name": "title", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "modal", - "type": "Object", - "attribute": null, - "config": "type: Object", - "defaultValue": "globalThis.SimpleModal.requestAvailability()" - } - ], - "slots": [ - "default" - ], - "events": [ - "modal-button-click" - ], - "methods": [ - "modalOpen", - "if" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../img-view-modal.js\";\n\ndescribe(\"img-view-modal test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"img-view-modal passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"img-view-modal passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"img-view-modal can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: title, modal" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: modal-button-click" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "inline-audio": { - "element": "inline-audio", - "component": { - "properties": [ - { - "name": "source", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "icon", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "aria", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "title", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "playing", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean, reflect: true", - "defaultValue": "false" - }, - { - "name": "shiny", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean, reflect: true", - "defaultValue": "false" - } - ], - "slots": [ - "default" - ], - "events": [ - "playing-changed" - ], - "methods": [ - "handleProgress", - "if", - "handlePlaythrough", - "audioController", - "load", - "play", - "pause", - "haxHooks", - "haxactiveElementChanged", - "haxeditModeChanged" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "I18NMixin" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\nimport \"../inline-audio.js\";\n\ndescribe(\"elementName test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html`

    \n Richard Stallman once sang the\n Open Source song.\n The King of Burgers made a decree. The decree came in the form of a\n song. Not just any song, but a legendary song that bellowed to the\n world. This song was of\n whoppers, toppers, boppers, and boopers.\n The seven seas were aghast with the tune of\n ?\n over the wind. Did you know that the critically acclaimed MMORPG Final\n Fantasy XIV has a free trial, and includes the entirety of A Realm\n Reborn AND the award-winning Heavensward expansion up to level 60 with\n no restrictions on playtime? Sign up, and enjoy Eorzea today!\n

    `,\n );\n });\n\n it(\"basic will it blend\", async () => {\n expect(element).to.exist;\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: source, icon, aria, title, playing, shiny" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: playing-changed" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "intersection-element": { - "element": "intersection-element", - "component": { - "error": "Main JS file not found: /home/bto108a/Documents/git/haxtheweb/webcomponents/elements/intersection-element/intersection-element.js", - "properties": [], - "slots": [], - "events": [], - "methods": [] - }, - "tests": { - "exists": false, - "hasAccessibilityTests": false, - "testedProperties": [], - "testedSlots": [], - "testedEvents": [], - "testedMethods": [] - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_TEST_FILE", - "message": "No test file found. Create test/${elementName}.test.js" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "journey-theme": { - "element": "journey-theme", - "component": { - "properties": [ - { - "name": "_items", - "type": "Array", - "attribute": null, - "config": "type: Array", - "defaultValue": "[]" - }, - { - "name": "activeItem", - "type": "Object", - "attribute": null, - "config": "type: Object" - }, - { - "name": "ancestorItem", - "type": "Object", - "attribute": null, - "config": "type: Object" - }, - { - "name": "location", - "type": "Object", - "attribute": null, - "config": "type: Object", - "defaultValue": "null" - }, - { - "name": "basePath", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "dataPrimary", - "type": "String", - "attribute": "data-primary", - "config": "type: String, reflect: true, attribute: \"data-primary\"", - "defaultValue": "2" - }, - { - "name": "siteTheme", - "type": "String", - "attribute": "site-theme", - "config": "type: String, reflect: true, attribute: \"site-theme\"", - "defaultValue": "UserScaffoldInstance.readMemory(\"HAXCMSSiteTheme\") || \"\"" - }, - { - "name": "licenseName", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "licenseLink", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "licenseImage", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "lastUpdated", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "copyrightYear", - "type": "Number", - "attribute": null, - "config": "type: Number" - }, - { - "name": "pageCurrent", - "type": "Number", - "attribute": null, - "config": "type: Number" - }, - { - "name": "pageTotal", - "type": "Number", - "attribute": null, - "config": "type: Number" - } - ], - "slots": [], - "events": [], - "methods": [ - "if", - "getItemChildren", - "switch", - "HAXSiteRenderXTagsItems", - "HAXCMSGlobalStyleSheetContent", - "for", - "toggleSiteTheme" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { html, fixture, expect } from '@open-wc/testing';\nimport \"../journey-theme.js\";\n\ndescribe(\"JourneyTheme test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"basic will it blend\", async () => {\n expect(element).to.exist;\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: _items, activeItem, ancestorItem, location, basePath, dataPrimary, siteTheme, licenseName, licenseLink, licenseImage, lastUpdated, copyrightYear, pageCurrent, pageTotal" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: data-primary, site-theme" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "json-outline-schema": { - "element": "json-outline-schema", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [ - "if", - "for", - "clone", - "newItem", - "addItem", - "validateItem", - "removeItem", - "updateItem", - "save", - "generateUUID", - "attributeChangedCallback", - "updateMetadata", - "getItemValues", - "getItemSchema", - "switch", - "itemsToNodes", - "treeToNodes", - "unflattenItems", - "scrubElementJOSData", - "nodesToItems", - "getChildOutline", - "while" - ], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../json-outline-schema.js\";\n\ndescribe(\"json-outline-schema test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"json-outline-schema passes accessibility test\", async () => {\n const el = await fixture(\n html` `\n );\n await expect(el).to.be.accessible();\n });\n it(\"json-outline-schema passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"json-outline-schema can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "jwt-login": { - "element": "jwt-login", - "component": { - "properties": [ - { - "name": "auto", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,", - "defaultValue": "false" - }, - { - "name": "refreshUrl", - "type": "String", - "attribute": "refresh-url", - "config": "type: String,\n attribute: \"refresh-url\"," - }, - { - "name": "redirectUrl", - "type": "String", - "attribute": "redirect-url", - "config": "type: String,\n attribute: \"redirect-url\"," - }, - { - "name": "logoutUrl", - "type": "String", - "attribute": "logout-url", - "config": "type: String,\n attribute: \"logout-url\"," - }, - { - "name": "url", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "method", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"GET\"" - }, - { - "name": "body", - "type": "Object", - "attribute": null, - "config": "type: Object," - }, - { - "name": "key", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "jwt", - "type": "String", - "attribute": null, - "config": "type: String," - } - ], - "slots": [], - "events": [ - "jwt-login-refresh-error", - "jwt-changed", - "jwt-logged-in", - "jwt-token", - "jwt-login-login-failed" - ], - "methods": [ - "lastErrorChanged", - "if", - "requestRefreshToken", - "generateRequest", - "toggleLogin", - "loginRequest", - "logoutRequest", - "isDifferentDomain", - "loginResponse", - "switch" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../jwt-login.js\";\n\ndescribe(\"jwt-login test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html` `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"jwt-login passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"jwt-login passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"jwt-login can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: auto, refreshUrl, redirectUrl, logoutUrl, url, method, body, key, jwt" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: jwt-login-refresh-error, jwt-changed, jwt-logged-in, jwt-token, jwt-login-login-failed" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "la-tex": { - "element": "la-tex", - "component": { - "properties": [ - { - "name": "hydrated", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean, reflect: true", - "defaultValue": "false" - }, - { - "name": "initialText", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "this.innerText" - } - ], - "slots": [], - "events": [], - "methods": [ - "hydrateLaTeX", - "if", - "haxHooks", - "haxactiveElementChanged", - "haxeditModeChanged" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\nimport \"../la-tex.js\";\n\ndescribe(\"elementName test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html``);\n });\n\n it(\"basic will it blend\", async () => {\n expect(element).to.exist;\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: hydrated, initialText" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "lazy-image-helpers": { - "element": "lazy-image-helpers", - "component": { - "properties": [ - { - "name": "imageLoaded", - "type": "Boolean", - "attribute": "image-loaded", - "config": "type: Boolean,\n reflect: true,\n attribute: \"image-loaded\",", - "defaultValue": "false" - } - ], - "slots": [], - "events": [], - "methods": [ - "if", - "renderSVGLoader" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "IntersectionObserverMixin", - "LoadingHelper" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../lazy-image-helpers.js\";\n\ndescribe(\"lazy-image-helpers test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"lazy-image-helpers passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"lazy-image-helpers passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"lazy-image-helpers can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: imageLoaded" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "lazy-import-discover": { - "element": "lazy-import-discover", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [ - "if", - "attributeChangedCallback" - ], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../lazy-import-discover.js\";\n/*\ndescribe(\"lazy-import-discover test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html` `\n );\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n*/\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"lazy-import-discover passes accessibility test\", async () => {\n const el = await fixture(\n html` `\n );\n await expect(el).to.be.accessible();\n });\n it(\"lazy-import-discover passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"lazy-import-discover can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "learn-two-theme": { - "element": "learn-two-theme", - "component": { - "properties": [ - { - "name": "opened", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true," - } - ], - "slots": [ - "default" - ], - "events": [], - "methods": [ - "if", - "siteModalClick", - "toggleDrawer" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "LTIResizingMixin" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../learn-two-theme.js\";\n/*\ndescribe(\"learn-two-theme test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html` `\n );\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"learn-two-theme passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"learn-two-theme passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"learn-two-theme can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: opened" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "lesson-overview": { - "element": "lesson-overview", - "component": { - "properties": [], - "slots": [ - "prefix", - "default" - ], - "events": [], - "methods": [ - "if", - "updateSmartHighlightElements", - "switch" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "I18NMixin" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\nimport \"../lesson-overview.js\";\n\ndescribe(\"elementName test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html``);\n });\n\n it(\"basic will it blend\", async () => {\n expect(element).to.exist;\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [ - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: prefix, default" - } - ], - "needsWork": true, - "priority": "MEDIUM" - }, - "license-element": { - "element": "license-element", - "component": { - "properties": [ - { - "name": "title", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "creator", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"(author)\"" - }, - { - "name": "source", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "null" - }, - { - "name": "licenseName", - "type": "String", - "attribute": "license-name", - "config": "type: String,\n attribute: \"license-name\"," - }, - { - "name": "licenseImage", - "type": "String", - "attribute": "license-image", - "config": "type: String,\n attribute: \"license-image\"," - }, - { - "name": "licenseLink", - "type": "String", - "attribute": "license-link", - "config": "type: String,\n attribute: \"license-link\"," - }, - { - "name": "license", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "moreLabel", - "type": "String", - "attribute": "more-label", - "config": "type: String,\n attribute: \"more-label\",", - "defaultValue": "\"on the licensing details page\"" - }, - { - "name": "moreLink", - "type": "String", - "attribute": "more-link", - "config": "type: String,\n attribute: \"more-link\"," - }, - { - "name": "hasMore", - "type": "Boolean", - "attribute": "has-more", - "config": "type: Boolean,\n attribute: \"has-more\"," - } - ], - "slots": [], - "events": [], - "methods": [ - "if", - "for" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "SchemaBehaviors" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../license-element.js\";\n\ndescribe(\"license-element test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"license-element passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"license-element passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"license-element can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: title, creator, source, licenseName, licenseImage, licenseLink, license, moreLabel, moreLink, hasMore" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "lorem-data": { - "element": "lorem-data", - "component": { - "properties": [ - { - "name": "schemas", - "type": "Object", - "attribute": null, - "config": "type: Object," - } - ], - "slots": [], - "events": [], - "methods": [ - "saveAll", - "getJson", - "saveDataUrl", - "filterQuery", - "dateFormat", - "draw", - "randomArray", - "randomAspect", - "randomBool", - "randomColor", - "randomHex", - "randomIcon", - "randomPlaceImg", - "randomPicsum", - "randomKitten", - "randomFlickr", - "randomImage", - "randomImageData", - "randomProfileImage", - "randomLink", - "randomNumber", - "randomObject", - "randomOption", - "randomParagraph", - "randomSentence", - "randomType", - "switch", - "randomWeightedOption", - "for", - "randomWord", - "shuffle", - "sortDates", - "titleCase" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "LoremDataBehaviors" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../lorem-data.js\";\n\ndescribe(\"lorem-data test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"lorem-data passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"lorem-data passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"lorem-data can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: schemas" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "lrn-gitgraph": { - "element": "lrn-gitgraph", - "component": { - "properties": [ - { - "name": "commits", - "type": "Array", - "attribute": null, - "config": "type: Array,", - "defaultValue": "[]" - }, - { - "name": "template", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"blackarrow\"" - }, - { - "name": "orientation", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"horizontal\"" - }, - { - "name": "mode", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"\"" - }, - { - "name": "reverseArrow", - "type": "Boolean", - "attribute": "reverse-arrow", - "config": "type: Boolean,\n attribute: \"reverse-arrow\",", - "defaultValue": "false" - }, - { - "name": "config", - "type": "Object", - "attribute": null, - "config": "type: Object," - } - ], - "slots": [], - "events": [], - "methods": [ - "if" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../lrn-gitgraph.js\";\n\ndescribe(\"lrn-gitgraph test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"lrn-gitgraph passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"lrn-gitgraph passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"lrn-gitgraph can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: commits, template, orientation, mode, reverseArrow, config" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "lrn-math": { - "element": "lrn-math", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [ - "AuthorInit", - "typeset", - "haxHooks", - "haxactiveElementChanged", - "if", - "haxeditModeChanged", - "updateMath", - "attributeChangedCallback", - "switch", - "refresh" - ], - "hasHaxProperties": true, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../lrn-math.js\";\n/*\ndescribe(\"lrn-math test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html` `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"lrn-math passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"lrn-math passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"lrn-math can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "lrn-table": { - "element": "lrn-table", - "component": { - "properties": [ - { - "name": "title", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "csvFile", - "type": "String", - "attribute": "csv-file", - "config": "type: String,\n attribute: \"csv-file\"," - }, - { - "name": "description", - "type": "String", - "attribute": null, - "config": "type: String," - } - ], - "slots": [ - "default" - ], - "events": [], - "methods": [], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "SchemaBehaviors" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../lrn-table.js\";\n\ndescribe(\"lrn-table test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html` `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"lrn-table passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"lrn-table passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"lrn-table can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: title, csvFile, description" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "lrn-vocab": { - "element": "lrn-vocab", - "component": { - "properties": [ - { - "name": "term", - "type": "String", - "attribute": null, - "config": "type: String,\n reflect: true," - } - ], - "slots": [], - "events": [], - "methods": [ - "haxHooks", - "haxactiveElementChanged", - "if", - "haxeditModeChanged", - "openDialog", - "for" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "SchemaBehaviors" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../lrn-vocab.js\";\n\ndescribe(\"lrn-vocab test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html` \n like whales when attacking prey from underneath.`,\n );\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"lrn-vocab passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"lrn-vocab passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"lrn-vocab can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: term" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "lrndesign-chart": { - "element": "lrndesign-chart", - "component": { - "properties": [ - { - "name": "accentColor", - "type": "String", - "attribute": "accent-color", - "config": "type: String,\n attribute: \"accent-color\",\n reflect: true," - }, - { - "name": "dark", - "type": "Boolean", - "attribute": "dark", - "config": "type: Boolean,\n attribute: \"dark\",\n reflect: true," - }, - { - "name": "height", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "reverseData", - "type": "Boolean", - "attribute": "reverse-data", - "config": "type: Boolean,\n attribute: \"reverse-data\"," - }, - { - "name": "width", - "type": "String", - "attribute": null, - "config": "type: String," - } - ], - "slots": [], - "events": [], - "methods": [ - "setProperties", - "setBarLineProperties" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "ChartistRenderSuper" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../lrndesign-chart.js\";\n\ndescribe(\"lrndesign-chart test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"lrndesign-chart passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"lrndesign-chart passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"lrndesign-chart can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: accentColor, dark, height, reverseData, width" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "lrndesign-imagemap": { - "element": "lrndesign-imagemap", - "component": { - "properties": [ - { - "name": "label", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "src", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "hotspotDetails", - "type": "Array", - "attribute": "hotspot-details", - "config": "type: Array,\n attribute: \"hotspot-details\"," - }, - { - "name": "subtopicOf", - "type": "String", - "attribute": "subtopic-of", - "config": "type: String,\n reflect: true,\n attribute: \"subtopic-of\"," - }, - { - "name": "parent", - "type": "String", - "attribute": "parent", - "config": "type: String,\n reflect: true,\n attribute: \"parent\"," - }, - { - "name": "__activeHotspot", - "type": "Object", - "attribute": null, - "config": "type: Object," - } - ], - "slots": [ - "heading" - ], - "events": [], - "methods": [ - "if", - "openHotspot", - "closeHotspot", - "resetHotspots", - "for" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../lrndesign-imagemap.js\";\n/*\ndescribe(\"lrndesign-imagemap test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html` `\n );\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"lrndesign-imagemap passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"lrndesign-imagemap passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"lrndesign-imagemap can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: label, src, hotspotDetails, subtopicOf, parent, __activeHotspot" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: heading" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "lrndesign-timeline": { - "element": "lrndesign-timeline", - "component": { - "properties": [ - { - "name": "events", - "type": "Array", - "attribute": null, - "config": "type: Array,", - "defaultValue": "[]" - }, - { - "name": "timelineSize", - "type": "String", - "attribute": "timeline-size", - "config": "type: String,\n reflect: true,\n attribute: \"timeline-size\",\n value: \"xs\",\n /**\n * title of timeline\n */\n timelineTitle: {\n type: String,\n reflect: true,\n attribute: \"timeline-title\",", - "defaultValue": "\"xs\"" - }, - { - "name": "title", - "type": "String", - "attribute": "title", - "config": "type: String,\n attribute: \"title\"," - } - ], - "slots": [ - "default" - ], - "events": [ - "responsive-element" - ], - "methods": [ - "if", - "updateTimeline" - ], - "hasHaxProperties": true, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../lrndesign-timeline.js\";\n/*\ndescribe(\"lrndesign-timeline test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html` \n

    This is lrndesign-timeline

    \n
    \n \n

    \"1856 - Construction of Old Main

    \n

    \n Construction of Old Main (the &quot;College Building&quot;)\n begun; supervised by William G. Waring, who was appointed\n superintendent to open the school and plan farm, orchards and\n nursery.\n

    \n
    \n
    \n \n

    \"1856 - Construction of Old Main

    \n

    \n Construction of Old Main (the &quot;College Building&quot;)\n begun; supervised by William G. Waring, who was appointed\n superintendent to open the school and plan farm, orchards and\n nursery.\n

    \n
    \n
    `\n );\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n*/\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"lrndesign-timeline passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"lrndesign-timeline passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"lrndesign-timeline can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: events, timelineSize, title" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: responsive-element" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "lrs-elements": { - "element": "lrs-elements", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "// local development and mobx\nwindow.process = window.process || {\n env: {\n NODE_ENV: \"development\",\n },\n};\nimport { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../lrs-elements.js\";\n\ndescribe(\"lrs-elements test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"lrs-elements passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"lrs-elements passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"lrs-elements can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "lunr-search": { - "element": "lunr-search", - "component": { - "properties": [ - { - "name": "dataSource", - "type": "String", - "attribute": "data-source", - "config": "type: String,\n attribute: \"data-source\",", - "defaultValue": "null" - }, - { - "name": "__auto", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,", - "defaultValue": "false" - }, - { - "name": "data", - "type": "Array", - "attribute": null, - "config": "type: Array," - }, - { - "name": "method", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"GET\"" - }, - { - "name": "search", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "results", - "type": "Array", - "attribute": null, - "config": "type: Array," - }, - { - "name": "noStopWords", - "type": "Boolean", - "attribute": "no-stop-words", - "config": "type: Boolean,\n attribute: \"no-stop-words\",", - "defaultValue": "false" - }, - { - "name": "fields", - "type": "Array", - "attribute": null, - "config": "type: Array,", - "defaultValue": "[]" - }, - { - "name": "indexNoStopWords", - "type": "Object", - "attribute": null, - "config": "type: Object," - }, - { - "name": "index", - "type": "Object", - "attribute": null, - "config": "type: Object," - }, - { - "name": "__lunrLoaded", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean," - }, - { - "name": "limit", - "type": "Number", - "attribute": null, - "config": "type: Number,", - "defaultValue": "500" - }, - { - "name": "minScore", - "type": "Number", - "attribute": null, - "config": "type: Number,", - "defaultValue": "0" - }, - { - "name": "log", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,", - "defaultValue": "false" - }, - { - "name": "demo", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true," - } - ], - "slots": [], - "events": [], - "methods": [ - "if", - "searched", - "for" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../lunr-search.js\";\n\ndescribe(\"lunr-search test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html``,\n );\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"lunr-search passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"lunr-search passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"lunr-search can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: dataSource, __auto, data, method, search, results, noStopWords, fields, indexNoStopWords, index, __lunrLoaded, limit, minScore, log, demo" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "map-menu": { - "element": "map-menu", - "component": { - "properties": [ - { - "name": "disabled", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "editControls", - "type": "Boolean", - "attribute": "edit-controls", - "config": "type: Boolean,\n attribute: \"edit-controls\",", - "defaultValue": "false" - }, - { - "name": "isFlex", - "type": "Boolean", - "attribute": "is-flex", - "config": "type: Boolean,\n attribute: \"is-flex\",", - "defaultValue": "false" - }, - { - "name": "isHorizontal", - "type": "Boolean", - "attribute": "is-horizontal", - "config": "type: Boolean,\n attribute: \"is-horizontal\",\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "maxDepth", - "type": "Number", - "attribute": "max-depth", - "config": "type: Number,\n attribute: \"max-depth\",", - "defaultValue": "5" - }, - { - "name": "title", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"Content outline\"" - }, - { - "name": "data", - "type": "Array", - "attribute": null, - "config": "type: Array,", - "defaultValue": "null" - }, - { - "name": "manifest", - "type": "Object", - "attribute": null, - "config": "type: Object," - }, - { - "name": "items", - "type": "Array", - "attribute": null, - "config": "type: Array,", - "defaultValue": "[]" - }, - { - "name": "selected", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "activeItem", - "type": "Object", - "attribute": null, - "config": "type: Object," - }, - { - "name": "autoScroll", - "type": "Boolean", - "attribute": "auto-scroll", - "config": "type: Boolean,\n attribute: \"auto-scroll\",", - "defaultValue": "false" - }, - { - "name": "activeIndicator", - "type": "Boolean", - "attribute": "active-indicator", - "config": "type: Boolean,\n reflect: true,\n attribute: \"active-indicator\",", - "defaultValue": "false" - } - ], - "slots": [], - "events": [ - "selected", - "map-menu-item-hidden-check" - ], - "methods": [ - "if", - "refreshActiveChildren", - "switch" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../map-menu.js\";\n\ndescribe(\"map-menu test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html` `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"map-menu passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"map-menu passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"map-menu can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: disabled, editControls, isFlex, isHorizontal, maxDepth, title, data, manifest, items, selected, activeItem, autoScroll, activeIndicator" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: selected, map-menu-item-hidden-check" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "mark-the-words": { - "element": "mark-the-words", - "component": { - "properties": [ - { - "name": "wordList", - "type": "Array", - "attribute": null, - "config": "type: Array", - "defaultValue": "[]" - }, - { - "name": "statement", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "\"\"" - }, - { - "name": "missedAnswers", - "type": "Array", - "attribute": null, - "config": "type: Array" - }, - { - "name": "numberCorrect", - "type": "Number", - "attribute": null, - "config": "type: Number", - "defaultValue": "0" - }, - { - "name": "numberGuessed", - "type": "Number", - "attribute": null, - "config": "type: Number", - "defaultValue": "0" - } - ], - "slots": [], - "events": [], - "methods": [ - "getGuess", - "rebuildWordList", - "for", - "selectWord", - "isCorrect", - "if", - "resetAnswer", - "guessCount", - "renderInteraction", - "renderDirections", - "renderFeedback" - ], - "hasHaxProperties": true, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../mark-the-words.js\";\n\ndescribe(\"mark-the-words test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html` \n This is mark-the-words\n `,\n );\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"mark-the-words passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"mark-the-words passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"mark-the-words can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: wordList, statement, missedAnswers, numberCorrect, numberGuessed" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "matching-question": { - "element": "matching-question", - "component": { - "properties": [ - { - "name": "dragging", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean, reflect: true" - }, - { - "name": "dragEnter", - "type": "Boolean", - "attribute": "drag-enter", - "config": "type: Boolean, reflect: true, attribute: \"drag-enter\"" - }, - { - "name": "matchTarget", - "type": "Boolean", - "attribute": "match-target", - "config": "type: Boolean, reflect: true, attribute: \"match-target\"" - }, - { - "name": "matchAnswers", - "type": "Array", - "attribute": null, - "config": "type: Array" - }, - { - "name": "__activeOption", - "type": "Object", - "attribute": null, - "config": "type: Object" - } - ], - "slots": [], - "events": [ - "simple-toast-hide" - ], - "methods": [ - "processInput", - "if", - "for", - "cleanAnswerData", - "cleanAnswerDataBeforeSend", - "resetAnswer", - "isCorrect", - "renderInteraction", - "renderOption", - "handleDrag", - "handleDragEnd", - "dragTargetOver", - "dragTargetLeave", - "handleDrop", - "renderDirections", - "focusActive", - "handleTagClick", - "selectTargetChange" - ], - "hasHaxProperties": true, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": false, - "hasAccessibilityTests": false, - "testedProperties": [], - "testedSlots": [], - "testedEvents": [], - "testedMethods": [] - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_TEST_FILE", - "message": "No test file found. Create test/${elementName}.test.js" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "md-block": { - "element": "md-block", - "component": { - "properties": [ - { - "name": "source", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"\"" - }, - { - "name": "markdown", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"\"" - } - ], - "slots": [], - "events": [], - "methods": [ - "if" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../md-block.js\";\n\ndescribe(\"md-block test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html` `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"md-block passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"md-block passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"md-block can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: source, markdown" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "media-behaviors": { - "element": "media-behaviors", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [ - "if", - "cleanVideoSource", - "getVideoType", - "for" - ], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../media-behaviors.js\";\n\ndescribe(\"media-behaviors test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"media-behaviors passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"media-behaviors passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"media-behaviors can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "media-image": { - "element": "media-image", - "component": { - "properties": [ - { - "name": "link", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "null" - }, - { - "name": "asMd", - "type": "Boolean", - "attribute": "as-md", - "config": "type: Boolean,\n attribute: \"as-md\",", - "defaultValue": "false" - }, - { - "name": "__figureLabel", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean," - }, - { - "name": "modalTitle", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"\"" - }, - { - "name": "disableZoom", - "type": "Boolean", - "attribute": "disable-zoom", - "config": "type: Boolean,\n attribute: \"disable-zoom\",\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "_hasCaption", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean," - }, - { - "name": "source", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"\"" - }, - { - "name": "citation", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"\"" - }, - { - "name": "caption", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"\"" - }, - { - "name": "alt", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"\"" - }, - { - "name": "size", - "type": "String", - "attribute": null, - "config": "type: String,\n reflect: true,", - "defaultValue": "\"wide\"" - }, - { - "name": "round", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,", - "defaultValue": "false" - }, - { - "name": "card", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "box", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "offset", - "type": "String", - "attribute": null, - "config": "type: String,\n reflect: true,", - "defaultValue": "\"none\"" - }, - { - "name": "figureLabelTitle", - "type": "String", - "attribute": "figure-label-title", - "config": "type: String,\n attribute: \"figure-label-title\",", - "defaultValue": "\"\"" - }, - { - "name": "figureLabelDescription", - "type": "String", - "attribute": "figure-label-description", - "config": "type: String,\n attribute: \"figure-label-description\",", - "defaultValue": "\"\"" - } - ], - "slots": [], - "events": [], - "methods": [ - "if", - "haxHooks", - "haxeditModeChanged", - "haxactiveElementChanged" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "SimpleModalHandler" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": true, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../media-image.js\";\n\ndescribe(\"media-image test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html`\n
    This is my citation.
    \n
    \n Curabitur aliquet quam id dui posuere blandit. Praesent sapien massa,\n convallis a pellentesque nec, egestas non nisi. Vestibulum ante ipsum\n primis in faucibus orci luctus et ultrices posuere cubilia Curae;\n Donec velit neque, auctor sit amet aliquam vel, ullamcorper sit amet\n ligula. Cras ultricies ligula sed magna dictum porta. Proin eget\n tortor risus. Praesent sapien massa, convallis a pellentesque nec,\n egestas non nisi. Donec sollicitudin molestie malesuada. Mauris\n blandit aliquet elit, eget tincidunt nibh pulvinar a. Vestibulum ac\n diam sit amet quam vehicula elementum sed sit amet dui. Vivamus\n suscipit tortor eget felis porttitor volutpat.\n
    \n `,\n );\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"media-image passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"media-image passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"media-image can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: link, asMd, __figureLabel, modalTitle, disableZoom, _hasCaption, source, citation, caption, alt, size, round, card, box, offset, figureLabelTitle, figureLabelDescription" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "media-quote": { - "element": "media-quote", - "component": { - "properties": [ - { - "name": "src", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"\"" - }, - { - "name": "alt", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"\"" - }, - { - "name": "hasFilter", - "type": "Boolean", - "attribute": "filter", - "config": "type: Boolean,\n attribute: \"filter\",", - "defaultValue": "false" - }, - { - "name": "quote", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"\"" - }, - { - "name": "author", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"\"" - }, - { - "name": "authorDetail", - "type": "String", - "attribute": "author-detail", - "config": "type: String,\n attribute: \"author-detail\",", - "defaultValue": "\"\"" - }, - { - "name": "caption", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"\"" - } - ], - "slots": [ - "quote", - "author", - "author-detail", - "caption" - ], - "events": [], - "methods": [ - "if" - ], - "hasHaxProperties": true, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": false, - "hasAccessibilityTests": false, - "testedProperties": [], - "testedSlots": [], - "testedEvents": [], - "testedMethods": [] - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_TEST_FILE", - "message": "No test file found. Create test/${elementName}.test.js" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "meme-maker": { - "element": "meme-maker", - "component": { - "properties": [ - { - "name": "alt", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"\"" - }, - { - "name": "crossorigin", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,", - "defaultValue": "false" - }, - { - "name": "describedBy", - "type": "String", - "attribute": "described-by", - "config": "type: String,\n attribute: \"described-by\"," - }, - { - "name": "imageUrl", - "type": "String", - "attribute": "image-url", - "config": "type: String,\n attribute: \"image-url\",\n reflect: true," - }, - { - "name": "topText", - "type": "String", - "attribute": "top-text", - "config": "type: String,\n attribute: \"top-text\",\n reflect: true," - }, - { - "name": "bottomText", - "type": "String", - "attribute": "bottom-text", - "config": "type: String,\n attribute: \"bottom-text\",\n reflect: true," - } - ], - "slots": [], - "events": [ - "i18n-manager-register-element" - ], - "methods": [ - "haxHooks", - "haxgizmoRegistration", - "haxprogressiveEnhancement" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../meme-maker.js\";\n\ndescribe(\"meme-maker test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"meme-maker passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"meme-maker passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"meme-maker can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: alt, crossorigin, describedBy, imageUrl, topText, bottomText" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: i18n-manager-register-element" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "merit-badge": { - "element": "merit-badge", - "component": { - "properties": [ - { - "name": "badgeDate", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "badgeImage", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "badgeTitle", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "badgeDetails", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "hyperLink", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "badgeSkills", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "skillsOpened", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean" - }, - { - "name": "detailsOpened", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean" - }, - { - "name": "badgeUnlocked", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean", - "defaultValue": "false" - }, - { - "name": "badgeColor", - "type": "String", - "attribute": null, - "config": "type: String" - } - ], - "slots": [], - "events": [], - "methods": [ - "unlockButtonClicked" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\nimport \"../merit-badge.js\";\n\ndescribe(\"elementName test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html``);\n });\n\n it(\"basic will it blend\", async () => {\n expect(element).to.exist;\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: badgeDate, badgeImage, badgeTitle, badgeDetails, hyperLink, badgeSkills, skillsOpened, detailsOpened, badgeUnlocked, badgeColor" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "micro-frontend-registry": { - "element": "micro-frontend-registry", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [ - "add", - "define", - "if", - "has", - "switch", - "url", - "for" - ], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [ - "MicroFrontendRegCapabilities", - "MicroFrontendRegCapabilities" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\nimport \"../micro-frontend-registry.js\";\n\ndescribe(\"elementName test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html``,\n );\n });\n\n it(\"basic will it blend\", async () => {\n expect(element).to.exist;\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "moar-sarcasm": { - "element": "moar-sarcasm", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [ - "if", - "processText", - "for", - "attributeChangedCallback", - "switch" - ], - "hasHaxProperties": true, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../moar-sarcasm.js\";\n\ndescribe(\"moar-sarcasm test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"moar-sarcasm passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"moar-sarcasm passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"moar-sarcasm can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "moment-element": { - "element": "moment-element", - "component": { - "properties": [ - { - "name": "datetime", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "new Date()" - }, - { - "name": "inputFormat", - "type": "String", - "attribute": "input-format", - "config": "type: String,\n attribute: \"input-format\",", - "defaultValue": "\"\"" - }, - { - "name": "outputFormat", - "type": "String", - "attribute": "output-format", - "config": "type: String,\n attribute: \"output-format\",", - "defaultValue": "\"\"" - }, - { - "name": "from", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"\"" - }, - { - "name": "to", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"\"" - }, - { - "name": "output", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "libraryLoaded", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean," - } - ], - "slots": [], - "events": [], - "methods": [ - "if" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../moment-element.js\";\n\ndescribe(\"moment-element test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"moment-element passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"moment-element passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"moment-element can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: datetime, inputFormat, outputFormat, from, to, output, libraryLoaded" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "multiple-choice": { - "element": "multiple-choice", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [ - "renderDirections", - "haxinlineContextMenu", - "haxClickInlineAdd", - "haxClickInlineRemove", - "if" - ], - "hasHaxProperties": true, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": true, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../multiple-choice.js\";\n\ndescribe(\"multiple-choice test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html`\n \n \n \n \n \n

    Yay! Let's jump in the money pit.

    \n

    You're despicable. What a quack!

    \n `,\n );\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"multiple-choice passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"multiple-choice passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"multiple-choice can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "music-player": { - "element": "music-player", - "component": { - "properties": [ - { - "name": "source", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "visualizer", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"staff\"" - }, - { - "name": "noWaterfall", - "type": "Boolean", - "attribute": "no-waterfall", - "config": "type: Boolean,\n attribute: \"no-waterfall\",\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "noVisual", - "type": "Boolean", - "attribute": "no-visual", - "config": "type: Boolean,\n attribute: \"no-visual\",\n reflect: true,", - "defaultValue": "false" - } - ], - "slots": [], - "events": [], - "methods": [], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../music-player.js\";\n\ndescribe(\"music-player test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html` `,\n );\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"music-player passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"music-player passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"music-player can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: source, visualizer, noWaterfall, noVisual" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "mutation-observer-import-mixin": { - "element": "mutation-observer-import-mixin", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [ - "MutationObserverImportMixin" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../mutation-observer-import-mixin.js\";\n\ndescribe(\"mutation-observer-import-mixin test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"mutation-observer-import-mixin passes accessibility test\", async () => {\n const el = await fixture(\n html` `\n );\n await expect(el).to.be.accessible();\n });\n it(\"mutation-observer-import-mixin passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"mutation-observer-import-mixin can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "oer-schema": { - "element": "oer-schema", - "component": { - "properties": [ - { - "name": "text", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"\"" - }, - { - "name": "oerProperty", - "type": "String", - "attribute": "oer-property", - "config": "type: String,\n attribute: \"oer-property\",", - "defaultValue": "\"name\"" - }, - { - "name": "typeof", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"Resource\"" - }, - { - "name": "relatedResource", - "type": "String", - "attribute": "related-resource", - "config": "type: String,\n attribute: \"related-resource\"," - } - ], - "slots": [ - "default" - ], - "events": [], - "methods": [ - "if" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "SchemaBehaviors" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../oer-schema.js\";\n\ndescribe(\"oer-schema test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"oer-schema passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"oer-schema passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"oer-schema can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: text, oerProperty, typeof, relatedResource" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "outline-designer": { - "element": "outline-designer", - "component": { - "properties": [ - { - "name": "haxGizmos", - "type": "Array", - "attribute": null, - "config": "type: Array", - "defaultValue": "[]" - }, - { - "name": "hideDelete", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean", - "defaultValue": "false" - }, - { - "name": "activeItemForActions", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "null" - }, - { - "name": "storeTools", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean", - "defaultValue": "false" - }, - { - "name": "eventData", - "type": "Object", - "attribute": null, - "config": "type: Object" - }, - { - "name": "items", - "type": "Array", - "attribute": null, - "config": "type: Array", - "defaultValue": "[]" - }, - { - "name": "appReady", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean", - "defaultValue": "false" - }, - { - "name": "activePreview", - "type": "Object", - "attribute": null, - "config": "type: Object" - }, - { - "name": "activePreviewIndex", - "type": "Number", - "attribute": null, - "config": "type: Number" - }, - { - "name": "hideContentOps", - "type": "Boolean", - "attribute": "hide-content-ops", - "config": "type: Boolean,\n reflect: true,\n attribute: \"hide-content-ops\",", - "defaultValue": "false" - }, - { - "name": "fidelity", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "\"medium\"" - }, - { - "name": "liveRegionText", - "type": "String", - "attribute": null, - "config": "type: String" - } - ], - "slots": [], - "events": [ - "simple-modal-hide" - ], - "methods": [ - "if", - "resetPopOver", - "getSiteItems", - "while", - "hasDeletedItems", - "toggleDelete", - "renderActiveContentItem", - "for", - "setActiveItemForActions", - "renderItem", - "hasContents", - "renderItemContents", - "itemContentsOperations", - "prependNodeToContent", - "renderNodeAsItem", - "switch", - "setActivePreview", - "modifyContentAction", - "pageBreakHere", - "collapseAll", - "expandAll", - "getItemParents", - "getItemParentsCollapsed", - "isCollapsed", - "hasChildren", - "collapseExpand", - "toggleContent", - "editTitle", - "monitorTitle", - "monitorHeading", - "monitorEsc", - "blurTitle", - "handleLabelKeydown", - "handleTreeItemKeydown", - "focusNextItem", - "focusPreviousItem", - "focusFirstChild", - "focusParent", - "focusFirstItem", - "focusLastItem", - "focusItem", - "announceNavigation", - "announceStateChange", - "announceAction", - "scrollIntoViewIfNeeded", - "addItemToTop", - "isLocked", - "addNewItem", - "recurseCopyChildren", - "recurseAction", - "itemOp" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "I18NMixin" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../outline-designer.js\";\n\ndescribe(\"outline-designer test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"outline-designer passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"outline-designer passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"outline-designer can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: haxGizmos, hideDelete, activeItemForActions, storeTools, eventData, items, appReady, activePreview, activePreviewIndex, hideContentOps, fidelity, liveRegionText" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: simple-modal-hide" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "outline-player": { - "element": "outline-player", - "component": { - "properties": [ - { - "name": "opened", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true," - }, - { - "name": "closed", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "activeId", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "narrow", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true," - } - ], - "slots": [ - "title", - "default" - ], - "events": [ - "closed-changed", - "resize" - ], - "methods": [ - "siteModalClick", - "if", - "for" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "LTIResizingMixin" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "// local development and mobx\nwindow.process = window.process || {\n env: {\n NODE_ENV: \"development\",\n },\n};\nimport { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../outline-player.js\";\n/*\ndescribe(\"outline-player test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html` `\n );\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"outline-player passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"outline-player passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"outline-player can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: opened, closed, activeId, narrow" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: title, default" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: closed-changed, resize" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "page-break": { - "element": "page-break", - "component": { - "properties": [ - { - "name": "iconType", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "noderefs", - "type": "Array", - "attribute": null, - "config": "type: Array,\n attribute: false," - }, - { - "name": "relatedItems", - "type": "String", - "attribute": "related-items", - "config": "type: String,\n attribute: \"related-items\",", - "defaultValue": "null" - }, - { - "name": "icon", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "null" - }, - { - "name": "accentColor", - "type": "String", - "attribute": "accent-color", - "config": "type: String, attribute: \"accent-color\"", - "defaultValue": "null" - }, - { - "name": "entityType", - "type": "String", - "attribute": "entity-type", - "config": "type: String, attribute: \"entity-type\"", - "defaultValue": "\"page\"" - }, - { - "name": "description", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "order", - "type": "Number", - "attribute": null, - "config": "type: Number" - }, - { - "name": "hideInMenu", - "type": "Boolean", - "attribute": "hide-in-menu", - "config": "type: Boolean, reflect: true, attribute: \"hide-in-menu\"" - }, - { - "name": "tags", - "type": "String", - "attribute": null, - "config": "type: String, reflect: true" - }, - { - "name": "developerTheme", - "type": "String", - "attribute": "developer-theme", - "config": "type: String, attribute: \"developer-theme\"" - }, - { - "name": "title", - "type": "String", - "attribute": null, - "config": "type: String, reflect: true" - }, - { - "name": "slug", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "image", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "parent", - "type": "String", - "attribute": null, - "config": "type: String, reflect: true" - }, - { - "name": "published", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean, reflect: true" - }, - { - "name": "locked", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean, reflect: true" - }, - { - "name": "depth", - "type": "Number", - "attribute": null, - "config": "type: Number, reflect: true" - }, - { - "name": "itemId", - "type": "String", - "attribute": "item-id", - "config": "type: String, attribute: \"item-id\", reflect: true" - }, - { - "name": "breakType", - "type": "String", - "attribute": "break-type", - "config": "type: String, attribute: \"break-type\"" - }, - { - "name": "status", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "\"\"" - }, - { - "name": "pageType", - "type": "String", - "attribute": "page-type", - "config": "type: String, attribute: \"page-type\"" - }, - { - "name": "_haxState", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean" - } - ], - "slots": [], - "events": [ - "page-break-registration", - "page-break-change", - "hax-refresh-tray-form" - ], - "methods": [ - "if", - "setupTargetData", - "for", - "haxHooks", - "while", - "haxsetupActiveElementForm", - "haxactiveElementChanged", - "haxeditModeChanged", - "haxinlineContextMenu", - "haxClickLockInPage", - "haxClickInlineLock", - "haxClickInlinePublished" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "IntersectionObserverMixin" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../page-break.js\";\n\ndescribe(\"page-break test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"page-break passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"page-break passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"page-break can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: iconType, noderefs, relatedItems, icon, accentColor, entityType, description, order, hideInMenu, tags, developerTheme, title, slug, image, parent, published, locked, depth, itemId, breakType, status, pageType, _haxState" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: page-break-registration, page-break-change, hax-refresh-tray-form" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "page-contents-menu": { - "element": "page-contents-menu", - "component": { - "properties": [ - { - "name": "contentContainer", - "type": "Object", - "attribute": null, - "config": "type: Object," - }, - { - "name": "relationship", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "null" - }, - { - "name": "items", - "type": "Array", - "attribute": null, - "config": "type: Array," - }, - { - "name": "position", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "mobile", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true," - }, - { - "name": "label", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "hideSettings", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean," - }, - { - "name": "hideIfEmpty", - "type": "Boolean", - "attribute": "hide-if-empty", - "config": "type: Boolean,\n attribute: \"hide-if-empty\",\n reflect: true," - }, - { - "name": "isEmpty", - "type": "Boolean", - "attribute": "is-empty", - "config": "type: Boolean,\n attribute: \"is-empty\",\n reflect: true," - } - ], - "slots": [], - "events": [], - "methods": [ - "keyToggle", - "keyScroll", - "if", - "toggleSettings", - "scrollToObject", - "renderItem", - "updateMenu", - "for", - "scrollFinished" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../page-contents-menu.js\";\n\ndescribe(\"page-contents-menu test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html`
    \n \n

    This is a menu position to a heading

    \n

    Stuff and things

    \n

    Something else

    \n

    Stuff and things

    \n

    Something 2

    \n

    Stuff and things

    \n

    \n Stuff and thingsStuff and thingsStuff and thingsStuff and thingsStuff\n and thingsStuff and thingsStuff and thingsStuff and things Stuff and\n thingsStuff and thingsStuff and thingsStuff and thingsStuff and things\n Stuff and thingsStuff and thingsStuff and thingsStuff and things Stuff\n and thingsStuff and thingsStuff and things\n

    \n \n

    Stuff and things

    \n

    Stuff and things

    \n

    Something deeper

    \n

    Stuff and things

    \n

    Stuff and things

    \n

    Stuff and things

    \n

    Something else 2

    \n
    `,\n );\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"page-contents-menu passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"page-contents-menu passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"page-contents-menu can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: contentContainer, relationship, items, position, mobile, label, hideSettings, hideIfEmpty, isEmpty" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "page-flag": { - "element": "page-flag", - "component": { - "properties": [ - { - "name": "label", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"note\"" - }, - { - "name": "opened", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "show", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true,", - "defaultValue": "false" - } - ], - "slots": [ - "default" - ], - "events": [], - "methods": [ - "if", - "toggleOpen", - "handleEdit", - "handleDelete", - "handleReply", - "haxeditModeChanged", - "haxHooks", - "haxinlineContextMenu", - "haxResolveThread", - "userDataUpdated" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": true, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\nimport \"../page-flag.js\";\n\ndescribe(\"page-flag test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html` \n
    \n \n
    \n

    Basic page-flag demo

    \n \n This is a comment\n This is a comment\n This is a comment\n \n

    Here's a bunch of content

    \n

    Here's a bunch of content

    \n

    Here's a bunch of content

    \n

    Here's a bunch of content

    \n

    Here's a bunch of content

    \n

    Here's a bunch of content

    \n

    Here's a bunch of content

    \n \n This is a comment\n This is a comment\n This is a comment\n \n

    Here's a bunch of content

    \n
    \n
    \n

    Basic page-flag demo

    \n \n This is a comment\n This is a comment\n This is a comment\n \n

    Here's a bunch of content

    \n

    Here's a bunch of content

    \n

    Here's a bunch of content

    \n \n This is a comment\n This is a comment\n This is a comment\n \n

    Here's a bunch of content

    \n

    Here's a bunch of content

    \n

    Here's a bunch of content

    \n

    Here's a bunch of content

    \n \n This is a comment\n This is a comment\n This is a comment\n \n

    Here's a bunch of content

    \n
    \n
    \n
    `,\n );\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"page-flag passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"page-flag passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"page-flag can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: label, opened, show" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "page-scroll-position": { - "element": "page-scroll-position", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [ - "attachedCallback" - ], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../page-scroll-position.js\";\n\ndescribe(\"page-scroll-position test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"page-scroll-position passes accessibility test\", async () => {\n const el = await fixture(\n html` `\n );\n await expect(el).to.be.accessible();\n });\n it(\"page-scroll-position passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"page-scroll-position can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "page-section": { - "element": "page-section", - "component": { - "properties": [ - { - "name": "anchor", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "null" - }, - { - "name": "scrollerLabel", - "type": "String", - "attribute": "scroller-label", - "config": "type: String, attribute: \"scroller-label\"", - "defaultValue": "\"Scroll to reveal content\"" - }, - { - "name": "filter", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean, reflect: true", - "defaultValue": "false" - }, - { - "name": "fold", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean, reflect: true", - "defaultValue": "false" - }, - { - "name": "full", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean, reflect: true", - "defaultValue": "false" - }, - { - "name": "scroller", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean, reflect: true", - "defaultValue": "false" - }, - { - "name": "bg", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "null" - }, - { - "name": "image", - "type": "String", - "attribute": null, - "config": "type: String, reflect: true", - "defaultValue": "null" - }, - { - "name": "preset", - "type": "String", - "attribute": null, - "config": "type: String, reflect: true", - "defaultValue": "null" - } - ], - "slots": [ - "default", - "entice", - "buttons" - ], - "events": [], - "methods": [ - "if", - "cleanAnchor", - "videoPlay", - "videoPause", - "switch", - "bgStyle", - "scrollToNextTarget" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\nimport \"../page-section.js\";\n\ndescribe(\"elementName test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html``);\n });\n\n it(\"basic will it blend\", async () => {\n expect(element).to.exist;\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: anchor, scrollerLabel, filter, fold, full, scroller, bg, image, preset" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default, entice, buttons" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: scroller-label" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "paper-input-flagged": { - "element": "paper-input-flagged", - "component": { - "properties": [ - { - "name": "label", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"\"" - }, - { - "name": "disabled", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,", - "defaultValue": "false" - }, - { - "name": "icon", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "maxlength", - "type": "Number", - "attribute": null, - "config": "type: Number," - }, - { - "name": "minlength", - "type": "Number", - "attribute": null, - "config": "type: Number," - }, - { - "name": "status", - "type": "String", - "attribute": null, - "config": "type: String,\n reflect: true," - }, - { - "name": "value", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"\"" - }, - { - "name": "flaggedInput", - "type": "Array", - "attribute": "flagged-input", - "config": "type: Array,\n attribute: \"flagged-input\"," - }, - { - "name": "inputSuccess", - "type": "Object", - "attribute": "input-success", - "config": "type: Object,\n attribute: \"input-success\"," - }, - { - "name": "__activeMessage", - "type": "String", - "attribute": null, - "config": "type: String," - } - ], - "slots": [], - "events": [], - "methods": [ - "if", - "valueEvent", - "testStatus", - "for", - "switch" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../paper-input-flagged.js\";\n\ndescribe(\"paper-input-flagged test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html` `,\n );\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"paper-input-flagged passes accessibility test\", async () => {\n const el = await fixture(\n html` `\n );\n await expect(el).to.be.accessible();\n });\n it(\"paper-input-flagged passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"paper-input-flagged can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: label, disabled, icon, maxlength, minlength, status, value, flaggedInput, inputSuccess, __activeMessage" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "paper-stepper": { - "element": "paper-stepper", - "component": { - "properties": [ - { - "name": "selected", - "type": "Number", - "attribute": null, - "config": "type: Number,\n notify: true,\n value: 0," - }, - { - "name": "progressBar", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n value: false," - }, - { - "name": "backLabel", - "type": "String", - "attribute": null, - "config": "type: String,\n value: \"Back\"," - }, - { - "name": "nextLabel", - "type": "String", - "attribute": null, - "config": "type: String,\n value: \"Next\"," - }, - { - "name": "disablePrevious", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n value: false," - }, - { - "name": "disableNext", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n value: false," - }, - { - "name": "noButtons", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n value: false," - } - ], - "slots": [], - "events": [], - "methods": [], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../paper-stepper.js\";\n\ndescribe(\"paper-stepper test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"paper-stepper passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"paper-stepper passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"paper-stepper can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: selected, progressBar, backLabel, nextLabel, disablePrevious, disableNext, noButtons" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "parallax-image": { - "element": "parallax-image", - "component": { - "properties": [ - { - "name": "imageBg", - "type": "String", - "attribute": "image-bg", - "config": "type: String,\n attribute: \"image-bg\",\n reflect: true,", - "defaultValue": "\"\"" - }, - { - "name": "describedBy", - "type": "String", - "attribute": "described-by", - "config": "type: String,\n attribute: \"described-by\"," - } - ], - "slots": [ - "parallax_heading" - ], - "events": [], - "methods": [ - "if", - "scrollBy" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "SchemaBehaviors" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../parallax-image.js\";\n\ndescribe(\"parallax-image test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"parallax-image passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"parallax-image passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"parallax-image can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: imageBg, describedBy" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: parallax_heading" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "pdf-browser-viewer": { - "element": "pdf-browser-viewer", - "component": { - "properties": [ - { - "name": "file", - "type": "String", - "attribute": null, - "config": "type: String,\n value: undefined,\n reflectToAttribute: true," - }, - { - "name": "notSupportedMessage", - "type": "String", - "attribute": null, - "config": "type: String,\n value:\n \"It appears your Web browser is not configured to display PDF files. No worries, just\"," - }, - { - "name": "notSupportedLinkMessage", - "type": "String", - "attribute": null, - "config": "type: String,\n value: \"click here to download the PDF file.\"," - }, - { - "name": "height", - "type": "String", - "attribute": null, - "config": "type: String,\n value: \"400px\"," - }, - { - "name": "width", - "type": "String", - "attribute": null, - "config": "type: String,\n value: \"100%\"," - }, - { - "name": "card", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n value: false," - }, - { - "name": "downloadLabel", - "type": "String", - "attribute": null, - "config": "type: String,\n value: \"Download\"," - }, - { - "name": "elevation", - "type": "String", - "attribute": null, - "config": "type: String,\n value: \"1\"," - } - ], - "slots": [], - "events": [], - "methods": [ - "clear" - ], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../pdf-browser-viewer.js\";\n\ndescribe(\"pdf-browser-viewer test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"pdf-browser-viewer passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"pdf-browser-viewer passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"pdf-browser-viewer can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: file, notSupportedMessage, notSupportedLinkMessage, height, width, card, downloadLabel, elevation" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "person-testimonial": { - "element": "person-testimonial", - "component": { - "properties": [ - { - "name": "describedBy", - "type": "String", - "attribute": "described-by", - "config": "type: String,\n attribute: \"described-by\"," - }, - { - "name": "image", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "name", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "position", - "type": "String", - "attribute": null, - "config": "type: String," - } - ], - "slots": [], - "events": [], - "methods": [], - "hasHaxProperties": true, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../person-testimonial.js\";\n\ndescribe(\"person-testimonial test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"person-testimonial passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"person-testimonial passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"person-testimonial can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: describedBy, image, name, position" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "place-holder": { - "element": "place-holder", - "component": { - "properties": [ - { - "name": "iconFromType", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"editor:format-align-left\"" - }, - { - "name": "text", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"\"" - }, - { - "name": "directions", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"Drag and drop file to replace\"" - }, - { - "name": "calcText", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "type", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"text\"" - }, - { - "name": "dragOver", - "type": "Boolean", - "attribute": "drag-over", - "config": "type: Boolean,\n reflect: true,\n attribute: \"drag-over\",", - "defaultValue": "false" - } - ], - "slots": [], - "events": [ - "place-holder-replace", - "place-holder-file-drop" - ], - "methods": [ - "if", - "fireReplaceEvent", - "switch" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../place-holder.js\";\n\ndescribe(\"place-holder test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: iconFromType, text, directions, calcText, type, dragOver" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: place-holder-replace, place-holder-file-drop" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: drag-over" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "play-list": { - "element": "play-list", - "component": { - "properties": [ - { - "name": "items", - "type": "Array", - "attribute": null, - "config": "type: Array", - "defaultValue": "[]" - }, - { - "name": "loop", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean, reflect: true", - "defaultValue": "false" - }, - { - "name": "edit", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean, reflect: true", - "defaultValue": "false" - }, - { - "name": "navigation", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean, reflect: true", - "defaultValue": "false" - }, - { - "name": "pagination", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean, reflect: true", - "defaultValue": "false" - }, - { - "name": "aspectRatio", - "type": "String", - "attribute": "aspect-ratio", - "config": "type: String, reflect: true, attribute: \"aspect-ratio\"", - "defaultValue": "\"16:9\"" - }, - { - "name": "orientation", - "type": "String", - "attribute": null, - "config": "type: String, reflect: true", - "defaultValue": "\"horizontal\"" - }, - { - "name": "slide", - "type": "Number", - "attribute": null, - "config": "type: Number, reflect: true", - "defaultValue": "0" - } - ], - "slots": [ - "default" - ], - "events": [], - "methods": [ - "if", - "renderHAXItem", - "slideIndexChanged", - "haxHooks", - "haxClickSlideIndex", - "haxinlineContextMenu", - "haxToggleEdit" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\nimport \"../play-list.js\";\n\ndescribe(\"elementName test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html``);\n });\n\n it(\"basic will it blend\", async () => {\n expect(element).to.exist;\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: items, loop, edit, navigation, pagination, aspectRatio, orientation, slide" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: aspect-ratio" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "polaris-theme": { - "element": "polaris-theme", - "component": { - "properties": [ - { - "name": "searchTerm", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "siteDescription", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "imageLink", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "image", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "imageAlt", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "pageTimestamp", - "type": "Number", - "attribute": null, - "config": "type: Number," - } - ], - "slots": [], - "events": [], - "methods": [ - "if", - "appStoreReady", - "siteModalClick", - "for" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "HAXCMSOperationButtons" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\nimport \"../polaris-theme.js\";\n\ndescribe(\"elementName test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html``);\n });\n\n it(\"basic will it blend\", async () => {\n expect(element).to.exist;\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: searchTerm, siteDescription, imageLink, image, imageAlt, pageTimestamp" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "portal-launcher": { - "element": "portal-launcher", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [ - "normalizeEventPath", - "if", - "click" - ], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../portal-launcher.js\";\n\ndescribe(\"portal-launcher test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"portal-launcher passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"portal-launcher passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"portal-launcher can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "post-card": { - "element": "post-card", - "component": { - "properties": [ - { - "name": "t", - "type": "Object", - "attribute": null, - "config": "type: Object" - }, - { - "name": "to", - "type": "String", - "attribute": null, - "config": "type: String, reflect: true" - }, - { - "name": "from", - "type": "String", - "attribute": null, - "config": "type: String, reflect: true" - }, - { - "name": "message", - "type": "String", - "attribute": null, - "config": "type: String, reflect: true" - }, - { - "name": "photoSrc", - "type": "String", - "attribute": "photo-src", - "config": "type: String, attribute: \"photo-src\", reflect: true" - }, - { - "name": "stampSrc", - "type": "String", - "attribute": "stamp-src", - "config": "type: String, attribute: \"stamp-src\", reflect: true" - }, - { - "name": "postMarkLocations", - "type": "String", - "attribute": "post-mark-locations", - "config": "type: String,\n reflect: true,\n attribute: \"post-mark-locations\"," - } - ], - "slots": [ - "to", - "from", - "message" - ], - "events": [ - "i18n-manager-register-element" - ], - "methods": [], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": true, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { html } from \"lit\";\nimport { fixture, expect } from \"@open-wc/testing\";\n\nimport \"../post-card.js\";\n\ndescribe(\"PostCard\", () => {\n let element;\n\n beforeEach(async () => {\n element = await fixture(\n html``,\n );\n });\n\n it(\"renders an h3\", () => {\n const h3 = element.shadowRoot.querySelector(\"h3\");\n expect(h3).to.exist;\n });\n\n it(\"renders a post-card-photo\", () => {\n const pcp = element.shadowRoot.querySelector(\"post-card-photo\");\n expect(pcp).to.exist;\n });\n\n it(\"renders a post-card-stamp\", () => {\n const pcs = element.shadowRoot.querySelector(\"post-card-stamp\");\n expect(pcs).to.exist;\n });\n\n it(\"renders a correct To address\", () => {\n const to = element.shadowRoot.querySelector('slot[name=\"to\"]');\n expect(to).to.exist;\n expect(to.textContent).to.equal(\"Future\");\n });\n\n it(\"renders a correct from address\", () => {\n const from = element.shadowRoot.querySelector('slot[name=\"from\"]');\n expect(from).to.exist;\n expect(from.textContent).to.equal(\"Past\");\n });\n\n it(\"renders a correct message\", () => {\n const mess = element.shadowRoot.querySelector('slot[name=\"message\"]');\n expect(mess).to.exist;\n expect(mess.textContent).to.equal(\"To make a baby....\");\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\ndescribe(\"PostCardPostmark\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html``,\n );\n });\n\n it(\"renders a location\", async () => {\n const loco = element.shadowRoot.querySelector(\"p\");\n expect(loco).to.exist;\n // expect(loco.textContent).to.equal('Europe')\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: t, to, from, message, photoSrc, stampSrc, postMarkLocations" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: i18n-manager-register-element" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: photo-src, stamp-src, post-mark-locations" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "pouch-db": { - "element": "pouch-db", - "component": { - "properties": [], - "slots": [], - "events": [ - "pouch-db-show-data" - ], - "methods": [ - "if", - "userEngagmentFunction", - "switch", - "function", - "getDataFunction", - "processxAPI", - "processItems" - ], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../pouch-db.js\";\n\ndescribe(\"pouch-db test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html` `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"pouch-db passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"pouch-db passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"pouch-db can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: pouch-db-show-data" - } - ], - "needsWork": true, - "priority": "MEDIUM" - }, - "product-card": { - "element": "product-card", - "component": { - "properties": [ - { - "name": "disabled", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "heading", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "subheading", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "icon", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "hasDemo", - "type": "Boolean", - "attribute": "has-demo", - "config": "type: Boolean,\n attribute: \"has-demo\"," - } - ], - "slots": [], - "events": [ - "product-card-demo-show" - ], - "methods": [], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../product-card.js\";\n\ndescribe(\"product-card test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"product-card passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"product-card passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"product-card can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: disabled, heading, subheading, icon, hasDemo" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: product-card-demo-show" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "product-glance": { - "element": "product-glance", - "component": { - "properties": [ - { - "name": "title", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "subtitle", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "icon", - "type": "String", - "attribute": null, - "config": "type: String" - } - ], - "slots": [], - "events": [], - "methods": [ - "if" - ], - "hasHaxProperties": true, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../product-glance.js\";\n\ndescribe(\"product-glance test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"product-glance passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"product-glance passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"product-glance can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: title, subtitle, icon" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "product-offering": { - "element": "product-offering", - "component": { - "properties": [ - { - "name": "alt", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "\"\"" - }, - { - "name": "source", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "icon", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "title", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "_titleOne", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "_titleTwo", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "description", - "type": "String", - "attribute": null, - "config": "type: String" - } - ], - "slots": [ - "description" - ], - "events": [], - "methods": [ - "if" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "IntersectionObserverMixin" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../product-offering.js\";\n\ndescribe(\"product-offering test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"product-offering passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"product-offering passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"product-offering can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: alt, source, icon, title, _titleOne, _titleTwo, description" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: description" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "progress-donut": { - "element": "progress-donut", - "component": { - "properties": [ - { - "name": "animation", - "type": "Number", - "attribute": "animation", - "config": "type: Number,\n attribute: \"animation\",", - "defaultValue": "-1" - }, - { - "name": "animationDelay", - "type": "Number", - "attribute": "animation-delay", - "config": "type: Number,\n attribute: \"animation-delay\",", - "defaultValue": "0" - }, - { - "name": "complete", - "type": "Array", - "attribute": null, - "config": "type: Array,", - "defaultValue": "[]" - }, - { - "name": "desc", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"\"" - }, - { - "name": "imageSrc", - "type": "String", - "attribute": "image-src", - "config": "attribute: \"image-src\",\n type: String,\n reflect: true,", - "defaultValue": "\"\"" - }, - { - "name": "imageAlt", - "type": "String", - "attribute": "image-alt", - "config": "attribute: \"image-alt\",\n type: String,\n reflect: true,", - "defaultValue": "\"\"" - } - ], - "slots": [], - "events": [], - "methods": [ - "addAnimation", - "if" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../progress-donut.js\";\n\ndescribe(\"progress-donut test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html`\n `,\n );\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"progress-donut passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"progress-donut passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"progress-donut can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: animation, animationDelay, complete, desc, imageSrc, imageAlt" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "promise-progress": { - "element": "promise-progress", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "SimpleColorsSuper" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\nimport \"../promise-progress.js\";\n\ndescribe(\"elementName test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html``);\n });\n\n it(\"basic will it blend\", async () => {\n expect(element).to.exist;\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "q-r": { - "element": "q-r", - "component": { - "properties": [ - { - "name": "data", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "title", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "modulesize", - "type": "Number", - "attribute": null, - "config": "type: Number,", - "defaultValue": "4" - }, - { - "name": "margin", - "type": "Number", - "attribute": null, - "config": "type: Number,", - "defaultValue": "2" - }, - { - "name": "format", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"png\"" - } - ], - "slots": [], - "events": [], - "methods": [], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../q-r.js\";\n\ndescribe(\"q-r test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html` `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"q-r passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"q-r passes accessibility negation\", async () => {\n const el = await fixture(html``);\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"q-r can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: data, title, modulesize, margin, format" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "radio-behaviors": { - "element": "radio-behaviors", - "component": { - "properties": [ - { - "name": "itemData", - "type": "Array", - "attribute": null, - "config": "type: Array," - }, - { - "name": "selection", - "type": "String", - "attribute": "selection", - "config": "type: String,\n attribute: \"selection\"," - } - ], - "slots": [], - "events": [ - "selection-changed" - ], - "methods": [ - "selectItem", - "if" - ], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../radio-behaviors.js\";\n\ndescribe(\"radio-behaviors test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"radio-behaviors passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"radio-behaviors passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"radio-behaviors can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: itemData, selection" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: selection-changed" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "relative-heading": { - "element": "relative-heading", - "component": { - "properties": [ - { - "name": "closeIcon", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "closeLabel", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "copyMessage", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "disableLink", - "type": "Boolean", - "attribute": "disable-link", - "config": "type: Boolean,\n attribute: \"disable-link\",", - "defaultValue": "false" - }, - { - "name": "linkAlignRight", - "type": "Boolean", - "attribute": "link-align-right", - "config": "type: Boolean,\n attribute: \"link-align-right\",\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "linkIcon", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"link\"" - }, - { - "name": "linkLabel", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"Get link\"" - } - ], - "slots": [], - "events": [], - "methods": [], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../relative-heading.js\";\n\ndescribe(\"relative-heading test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html`\n

    Lorem ipsum dolor

    \n
    \n

    Lorem ipsum dolor sit amet, consectetur adipiscing elit.

    \n\n \n

    Praesent ultrices

    \n
    \n

    \n Mauris aliquam lorem justo. Praesent ultrices lorem nec est iaculis\n viverra dignissim eu neque. Nullam vitae nisl diam.\n

    \n\n \n

    Suspendisse

    \n
    \n

    \n Suspendisse potenti. Nulla venenatis porta felis id feugiat. Vivamus\n vehicula molestie sapien hendrerit ultricies.\n

    \n\n \n

    Sapien sit amet

    \n
    \n

    \n Quisque volutpat eu sapien sit amet interdum. Proin venenatis tellus\n eu nisi congue aliquet.\n

    \n\n \n
    Sollicitudin
    \n
    \n

    \n Nullam at velit sollicitudin, porta mi quis, lacinia velit. Praesent\n quis mauris sem.\n

    \n\n \n
    In et volutpat
    \n
    \n

    \n In et volutpat nisi. Suspendisse vel nibh eu magna posuere\n sollicitudin. Praesent ac ex varius, facilisis urna et, cursus tellus.\n

    `,\n );\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"relative-heading passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"relative-heading passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"relative-heading can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: closeIcon, closeLabel, copyMessage, disableLink, linkAlignRight, linkIcon, linkLabel" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "replace-tag": { - "element": "replace-tag", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [ - "if", - "performanceBasedReplacement", - "handleIntersectionCallback", - "for", - "runReplacement" - ], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [ - "ReplaceTagSuper" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../replace-tag.js\";\n\ndescribe(\"replace-tag test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html`will replace `,\n );\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"replace-tag passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"replace-tag passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"replace-tag can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "responsive-grid": { - "element": "responsive-grid", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../responsive-grid.js\";\n\ndescribe(\"responsive-grid test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"responsive-grid passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"responsive-grid passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"responsive-grid can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "responsive-utility": { - "element": "responsive-utility", - "component": { - "properties": [], - "slots": [ - "default" - ], - "events": [], - "methods": [ - "responiveElementEvent", - "deleteResponiveElementEvent", - "if" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../responsive-utility.js\";\n\ndescribe(\"responsive-utility test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"responsive-utility passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"responsive-utility passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"responsive-utility can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ], - "needsWork": true, - "priority": "MEDIUM" - }, - "retro-card": { - "element": "retro-card", - "component": { - "properties": [ - { - "name": "title", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "subtitle", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "tags", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "mediaSource", - "type": "String", - "attribute": "media-source", - "config": "type: String,\n attribute: \"media-source\"," - }, - { - "name": "url", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "hoverSource", - "type": "String", - "attribute": "hover-source", - "config": "type: String,\n attribute: \"hover-source\"," - }, - { - "name": "hoverState", - "type": "Boolean", - "attribute": "hover-state", - "config": "type: Boolean,\n attribute: \"hover-state\",\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "__cardTags", - "type": "Array", - "attribute": null, - "config": "type: Array,", - "defaultValue": "[]" - }, - { - "name": "nosource", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,", - "defaultValue": "false" - }, - { - "name": "__source", - "type": "String", - "attribute": null, - "config": "type: String," - } - ], - "slots": [], - "events": [], - "methods": [ - "switch", - "if", - "haxHooks", - "haxactiveElementChanged", - "haxeditModeChanged" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../retro-card.js\";\n\ndescribe(\"retro-card test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"retro-card passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"retro-card passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"retro-card can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: title, subtitle, tags, mediaSource, url, hoverSource, hoverState, __cardTags, nosource, __source" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "rich-text-editor": { - "element": "rich-text-editor", - "component": { - "properties": [ - { - "name": "id", - "type": "String", - "attribute": "id", - "config": "name: \"id\",\n type: String,\n reflect: true,\n attribute: \"id\",", - "defaultValue": "\"\"" - }, - { - "name": "contenteditable", - "type": "String", - "attribute": "contenteditable", - "config": "name: \"contenteditable\",\n type: String,\n reflect: true,\n attribute: \"contenteditable\"," - }, - { - "name": "disabled", - "type": "Boolean", - "attribute": "disabled", - "config": "name: \"disabled\",\n type: Boolean,\n attribute: \"disabled\",\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "disableHover", - "type": "Boolean", - "attribute": "disable-hover", - "config": "name: \"disableHover\",\n type: Boolean,\n attribute: \"disable-hover\"," - }, - { - "name": "placeholder", - "type": "String", - "attribute": "aria-placeholder", - "config": "name: \"placeholder\",\n type: String,\n reflect: false,\n attribute: \"aria-placeholder\",", - "defaultValue": "\"Click to edit\"" - }, - { - "name": "toolbarId", - "type": "String", - "attribute": "toolbar-id", - "config": "name: \"toolbarId\",\n type: String,\n reflect: true,\n attribute: \"toolbar-id\",", - "defaultValue": "\"\"" - }, - { - "name": "range", - "type": "Object", - "attribute": "range", - "config": "name: \"range\",\n type: Object,\n attribute: \"range\",", - "defaultValue": "undefined" - }, - { - "name": "rawhtml", - "type": "String", - "attribute": "rawhtml", - "config": "type: String,\n attribute: \"rawhtml\"," - }, - { - "name": "type", - "type": "String", - "attribute": "type", - "config": "name: \"type\",\n type: String,\n reflect: true,\n attribute: \"type\",", - "defaultValue": "\"rich-text-editor-toolbar\"" - }, - { - "name": "viewSource", - "type": "Boolean", - "attribute": "view-source", - "config": "type: Boolean,\n attribute: \"view-source\",\n reflect: true," - }, - { - "name": "__codeEditorValue", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "__needsUpdate", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean," - }, - { - "name": "__focused", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,", - "defaultValue": "false" - }, - { - "name": "__hovered", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,", - "defaultValue": "false" - } - ], - "slots": [ - "default" - ], - "events": [ - "focus", - "contenteditable-change" - ], - "methods": [ - "if", - "focus", - "makeSticky" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "RichTextEditorBehaviors" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../rich-text-editor.js\";\n\ndescribe(\"rich-text-editor test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n

    \n I'm the easiest way to implement editable rich\n text.\n

    \n
    \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"rich-text-editor passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"rich-text-editor passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"rich-text-editor can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: id, contenteditable, disabled, disableHover, placeholder, toolbarId, range, rawhtml, type, viewSource, __codeEditorValue, __needsUpdate, __focused, __hovered" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: focus, contenteditable-change" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "rpg-character": { - "element": "rpg-character", - "component": { - "properties": [ - { - "name": "literalseed", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean", - "defaultValue": "false" - }, - { - "name": "accessories", - "type": "Number", - "attribute": null, - "config": "type: Number", - "defaultValue": "0" - }, - { - "name": "height", - "type": "Number", - "attribute": null, - "config": "type: Number", - "defaultValue": "142" - }, - { - "name": "width", - "type": "Number", - "attribute": null, - "config": "type: Number", - "defaultValue": "113" - }, - { - "name": "base", - "type": "Number", - "attribute": null, - "config": "type: Number", - "defaultValue": "0" - }, - { - "name": "face", - "type": "Number", - "attribute": null, - "config": "type: Number", - "defaultValue": "0" - }, - { - "name": "faceItem", - "type": "Number", - "attribute": null, - "config": "type: Number", - "defaultValue": "0" - }, - { - "name": "hair", - "type": "Number", - "attribute": null, - "config": "type: Number", - "defaultValue": "0" - }, - { - "name": "pants", - "type": "Number", - "attribute": null, - "config": "type: Number", - "defaultValue": "0" - }, - { - "name": "shirt", - "type": "Number", - "attribute": null, - "config": "type: Number", - "defaultValue": "0" - }, - { - "name": "skin", - "type": "Number", - "attribute": null, - "config": "type: Number", - "defaultValue": "0" - }, - { - "name": "hatColor", - "type": "Number", - "attribute": null, - "config": "type: Number", - "defaultValue": "0" - }, - { - "name": "hat", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "\"none\"" - }, - { - "name": "walking", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean, reflect: true", - "defaultValue": "false" - }, - { - "name": "leg", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "\"\"" - }, - { - "name": "seed", - "type": "String", - "attribute": null, - "config": "type: String, reflect: true", - "defaultValue": "null" - }, - { - "name": "speed", - "type": "Number", - "attribute": null, - "config": "type: Number", - "defaultValue": "500" - }, - { - "name": "circle", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean, reflect: true", - "defaultValue": "false" - }, - { - "name": "fire", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean, reflect: true", - "defaultValue": "false" - }, - { - "name": "demo", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean", - "defaultValue": "false" - }, - { - "name": "reduceMotion", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean", - "defaultValue": "globalThis.matchMedia(\n \"(prefers-reduced-motion: reduce)\",\n ).matches" - } - ], - "slots": [], - "events": [], - "methods": [ - "if", - "randomColor", - "renderPiece", - "switch", - "for" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\nimport \"../rpg-character.js\";\n\ndescribe(\"elementName test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html``);\n });\n\n it(\"basic will it blend\", async () => {\n expect(element).to.exist;\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: literalseed, accessories, height, width, base, face, faceItem, hair, pants, shirt, skin, hatColor, hat, walking, leg, seed, speed, circle, fire, demo, reduceMotion" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "runkit-embed": { - "element": "runkit-embed", - "component": { - "properties": [ - { - "name": "nodeVersion", - "type": "String", - "attribute": "node-version", - "config": "type: String, attribute: \"node-version\"" - }, - { - "name": "mode", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "loading", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean", - "defaultValue": "false" - }, - { - "name": "source", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "dataHaxActive", - "type": "String", - "attribute": "data-hax-active", - "config": "type: String,\n reflect: true,\n attribute: \"data-hax-active\"," - } - ], - "slots": [ - "default" - ], - "events": [], - "methods": [ - "if", - "buildRunKit", - "haxHooks", - "haxeditModeChanged" - ], - "hasHaxProperties": true, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": false, - "hasAccessibilityTests": false, - "testedProperties": [], - "testedSlots": [], - "testedEvents": [], - "testedMethods": [] - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_TEST_FILE", - "message": "No test file found. Create test/${elementName}.test.js" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "schema-behaviors": { - "element": "schema-behaviors", - "component": { - "properties": [ - { - "name": "schemaMap", - "type": "Object", - "attribute": null, - "config": "type: Object,\n readOnly: true,\n observer: \"_schemaMapChanged\"," - } - ], - "slots": [], - "events": [], - "methods": [ - "if", - "for" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../schema-behaviors.js\";\n\ndescribe(\"schema-behaviors test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"schema-behaviors passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"schema-behaviors passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"schema-behaviors can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: schemaMap" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "scroll-button": { - "element": "scroll-button", - "component": { - "properties": [ - { - "name": "target", - "type": "Object", - "attribute": null, - "config": "type: Object," - }, - { - "name": "icon", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"icons:expand-less\"" - }, - { - "name": "label", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "_label", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "position", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "t", - "type": "Object", - "attribute": null, - "config": "type: Object," - } - ], - "slots": [], - "events": [ - "i18n-manager-register-element" - ], - "methods": [ - "if", - "scrollEvent" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../scroll-button.js\";\n\ndescribe(\"scroll-button test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"scroll-button passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"scroll-button passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"scroll-button can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: target, icon, label, _label, position, t" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: i18n-manager-register-element" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "secure-request": { - "element": "secure-request", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [ - "setCookies", - "generateUrl", - "if", - "getEndPoint", - "getCsrfToken", - "for" - ], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../secure-request.js\";\n\ndescribe(\"secure-request test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"secure-request passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"secure-request passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"secure-request can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "self-check": { - "element": "self-check", - "component": { - "properties": [ - { - "name": "title", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"Self-Check\"" - }, - { - "name": "question", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"\"" - }, - { - "name": "image", - "type": "String", - "attribute": null, - "config": "type: String,\n reflect: true,", - "defaultValue": "\"\"" - }, - { - "name": "alt", - "type": "String", - "attribute": null, - "config": "type: String,\n reflect: true,", - "defaultValue": "\"\"" - }, - { - "name": "describedBy", - "type": "String", - "attribute": "described-by", - "config": "type: String,\n attribute: \"described-by\"," - }, - { - "name": "link", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "correct", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true,", - "defaultValue": "false" - } - ], - "slots": [], - "events": [], - "methods": [ - "if", - "haxHooks", - "haxactiveElementChanged", - "openAnswer" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "I18NMixin" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": true, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../self-check.js\";\n\ndescribe(\"self-check test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html`\n How large can the average great white shark grow to be?\n The Great White shark can grow to be 15 ft to more than 20 ft in length\n and weigh 2.5 tons or more.\n `,\n );\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"self-check passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"self-check passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"self-check can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: title, question, image, alt, describedBy, link, correct" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "shadow-style": { - "element": "shadow-style", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [ - "if", - "for" - ], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../shadow-style.js\";\n\ndescribe(\"shadow-style test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"shadow-style passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"shadow-style passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"shadow-style can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "simple-autocomplete": { - "element": "simple-autocomplete", - "component": { - "properties": [ - { - "name": "opened", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "hideInput", - "type": "Boolean", - "attribute": "hide-input", - "config": "type: Boolean,\n attribute: \"hide-input\",", - "defaultValue": "false" - }, - { - "name": "selectionPosition", - "type": "Boolean", - "attribute": "selection-position", - "config": "type: Boolean,\n attribute: \"selection-position\",", - "defaultValue": "false" - }, - { - "name": "value", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"\"" - }, - { - "name": "itemLimit", - "type": "Number", - "attribute": "item-limit", - "config": "type: Number,\n attribute: \"item-limit\",", - "defaultValue": "6" - } - ], - "slots": [], - "events": [], - "methods": [ - "setValue", - "if", - "processInput", - "inputChanged", - "a11yListKeys", - "switch", - "hardStopEvent", - "a11yInputKeys", - "getSelection", - "getRange", - "resetFocusOnInput", - "itemSelect", - "for" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "SimpleFilterMixin" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../simple-autocomplete.js\";\n\ndescribe(\"simple-autocomplete test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"simple-autocomplete passes accessibility test\", async () => {\n const el = await fixture(\n html` `\n );\n await expect(el).to.be.accessible();\n });\n it(\"simple-autocomplete passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"simple-autocomplete can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: opened, hideInput, selectionPosition, value, itemLimit" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "simple-blog": { - "element": "simple-blog", - "component": { - "properties": [ - { - "name": "selectedPage", - "type": "Number", - "attribute": "selected-page", - "config": "type: Number,\n reflect: true,\n attribute: \"selected-page\",", - "defaultValue": "0" - } - ], - "slots": [ - "default" - ], - "events": [ - "resize" - ], - "methods": [ - "if", - "for" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "SimpleColorsSuper" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "// local development and mobx\nwindow.process = window.process || {\n env: {\n NODE_ENV: \"development\",\n },\n};\nimport { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../simple-blog.js\";\n\ndescribe(\"simple-blog test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html` `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"simple-blog passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"simple-blog passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"simple-blog can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: selectedPage" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: resize" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "simple-colors": { - "element": "simple-colors", - "component": { - "properties": [ - { - "name": "accentColor", - "type": "String", - "attribute": "accent-color", - "config": "attribute: \"accent-color\",\n type: String,\n reflect: true,", - "defaultValue": "\"grey\"" - }, - { - "name": "dark", - "type": "Boolean", - "attribute": null, - "config": "name: \"dark\",\n type: Boolean,\n reflect: true,", - "defaultValue": "false" - } - ], - "slots": [ - "default" - ], - "events": [], - "methods": [ - "if", - "invertShade", - "getColorInfo", - "makeVariable", - "getContrastingColors", - "getContrastingShades", - "isContrastCompliant" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "SimpleColorsSuper" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../simple-colors.js\";\n\ndescribe(\"simple-colors test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"simple-colors passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"simple-colors passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"simple-colors can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: accentColor, dark" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "simple-colors-shared-styles": { - "element": "simple-colors-shared-styles", - "component": { - "properties": [ - { - "name": "colors", - "type": "Object", - "attribute": "colors", - "config": "attribute: \"colors\",\n type: Object," - }, - { - "name": "contrasts", - "type": "Object", - "attribute": "contrasts", - "config": "attribute: \"contrasts\",\n type: Object," - } - ], - "slots": [], - "events": [], - "methods": [ - "getColorInfo", - "makeVariable", - "getContrastingShades", - "getContrastingColors", - "isContrastCompliant", - "indexToShade", - "shadeToIndex", - "if" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../simple-colors-shared-styles.js\";\n\ndescribe(\"simple-colors-shared-styles test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"simple-colors-shared-styles passes accessibility test\", async () => {\n const el = await fixture(\n html` `\n );\n await expect(el).to.be.accessible();\n });\n it(\"simple-colors-shared-styles passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"simple-colors-shared-styles can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: colors, contrasts" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "simple-cta": { - "element": "simple-cta", - "component": { - "properties": [ - { - "name": "link", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "null" - }, - { - "name": "label", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "null" - }, - { - "name": "icon", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"icons:chevron-right\"" - }, - { - "name": "editMode", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean," - }, - { - "name": "hideIcon", - "type": "Boolean", - "attribute": "hide-icon", - "config": "type: Boolean,\n attribute: \"hide-icon\",", - "defaultValue": "false" - }, - { - "name": "large", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true,", - "defaultValue": "null" - }, - { - "name": "light", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true,", - "defaultValue": "null" - }, - { - "name": "hotline", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true,", - "defaultValue": "null" - }, - { - "name": "saturate", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true,", - "defaultValue": "null" - }, - { - "name": "disabled", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true,", - "defaultValue": "false" - } - ], - "slots": [ - "default" - ], - "events": [], - "methods": [ - "haxHooks", - "haxeditModeChanged", - "if", - "haxactiveElementChanged" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "DDDPulseEffectSuper" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../simple-cta.js\";\n\ndescribe(\"simple-cta test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"simple-cta passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"simple-cta passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"simple-cta can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: link, label, icon, editMode, hideIcon, large, light, hotline, saturate, disabled" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "simple-datetime": { - "element": "simple-datetime", - "component": { - "properties": [ - { - "name": "timestamp", - "type": "Number", - "attribute": null, - "config": "type: Number," - }, - { - "name": "format", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"M jS, Y\"" - }, - { - "name": "date", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "unix", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,", - "defaultValue": "false" - } - ], - "slots": [], - "events": [], - "methods": [ - "formatDate", - "if" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../simple-datetime.js\";\n\ndescribe(\"simple-datetime test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html``,\n );\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"simple-datetime passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"simple-datetime passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"simple-datetime can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: timestamp, format, date, unix" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "simple-emoji": { - "element": "simple-emoji", - "component": { - "properties": [], - "slots": [ - "default" - ], - "events": [], - "methods": [ - "if" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../simple-emoji.js\";\n\ndescribe(\"simple-emoji test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"simple-emoji passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"simple-emoji passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"simple-emoji can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ], - "needsWork": true, - "priority": "MEDIUM" - }, - "simple-fields": { - "element": "simple-fields", - "component": { - "properties": [ - { - "name": "disableResponsive", - "type": "Boolean", - "attribute": "disable-responsive", - "config": "type: Boolean,\n reflect: true,\n attribute: \"disable-responsive\"," - }, - { - "name": "fields", - "type": "Array", - "attribute": null, - "config": "type: Array," - }, - { - "name": "schematizer", - "type": "Object", - "attribute": "schematizer", - "config": "type: Object,\n attribute: \"schematizer\"," - }, - { - "name": "label", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "__activeTabs", - "type": "Object", - "attribute": "active-path", - "config": "type: Object,\n attribute: \"active-path\"," - }, - { - "name": "codeTheme", - "type": "String", - "attribute": "code-theme", - "config": "type: String,\n attribute: \"code-theme\"," - } - ], - "slots": [ - "default" - ], - "events": [ - "active-tabs-changed" - ], - "methods": [ - "if", - "setActiveTab", - "setActivePath", - "fieldsToSchema" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../simple-fields.js\";\n\ndescribe(\"simple-fields test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"simple-fields passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"simple-fields passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"simple-fields can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: disableResponsive, fields, schematizer, label, __activeTabs, codeTheme" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: active-tabs-changed" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "simple-filter": { - "element": "simple-filter", - "component": { - "properties": [ - { - "name": "items", - "type": "Array", - "attribute": null, - "config": "type: Array," - }, - { - "name": "like", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "where", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "caseSensitive", - "type": "Boolean", - "attribute": "case-sensitive", - "config": "type: Boolean,\n attribute: \"case-sensitive\",\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "multiMatch", - "type": "Boolean", - "attribute": "multi-match", - "config": "type: Boolean,\n attribute: \"multi-match\",", - "defaultValue": "false" - }, - { - "name": "filtered", - "type": "Array", - "attribute": null, - "config": "type: Array,", - "defaultValue": "[]" - } - ], - "slots": [], - "events": [ - "filter", - "filtered-changed" - ], - "methods": [ - "resetList", - "update", - "if", - "filter", - "escapeRegExp" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "SimpleFilterMixin" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../simple-filter.js\";\n\ndescribe(\"simple-filter test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"simple-filter passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"simple-filter passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"simple-filter can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: items, like, where, caseSensitive, multiMatch, filtered" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: filter, filtered-changed" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "simple-icon": { - "element": "simple-icon", - "component": { - "properties": [ - { - "name": "contrast", - "type": "Number", - "attribute": "contrast", - "config": "type: Number,\n attribute: \"contrast\",\n reflect: true,", - "defaultValue": "0" - } - ], - "slots": [], - "events": [], - "methods": [], - "hasHaxProperties": true, - "extendsLitElement": false, - "extendsOtherBehaviors": [ - "SimpleIconBehaviors" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../simple-icon.js\";\n\ndescribe(\"simple-icon test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"simple-icon passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"simple-icon passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"simple-icon can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: contrast" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "simple-icon-picker": { - "element": "simple-icon-picker", - "component": { - "properties": [ - { - "name": "allowNull", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,", - "defaultValue": "true" - }, - { - "name": "icons", - "type": "Array", - "attribute": null, - "config": "type: Array,", - "defaultValue": "[]" - }, - { - "name": "includeSets", - "type": "Array", - "attribute": "include-sets", - "config": "type: Array,\n attribute: \"include-sets\"," - }, - { - "name": "excludeSets", - "type": "Array", - "attribute": "exclude-sets", - "config": "type: Array,\n attribute: \"exclude-sets\"," - }, - { - "name": "exclude", - "type": "Array", - "attribute": "exclude", - "config": "type: Array,\n attribute: \"exclude\"," - }, - { - "name": "value", - "type": "String", - "attribute": null, - "config": "type: String,\n reflect: true,", - "defaultValue": "null" - }, - { - "name": "optionsPerRow", - "type": "Number", - "attribute": null, - "config": "type: Number,", - "defaultValue": "6" - }, - { - "name": "__iconList", - "type": "Array", - "attribute": null, - "config": "type: Array," - } - ], - "slots": [], - "events": [ - "value-changed" - ], - "methods": [ - "if", - "for" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../simple-icon-picker.js\";\n\ndescribe(\"simple-icon-picker test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"simple-icon-picker passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"simple-icon-picker passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"simple-icon-picker can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: allowNull, icons, includeSets, excludeSets, exclude, value, optionsPerRow, __iconList" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: value-changed" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "simple-img": { - "element": "simple-img", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [ - "if", - "updateconvertedurl", - "attributeChangedCallback" - ], - "hasHaxProperties": true, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\nimport \"../simple-img.js\";\n\ndescribe(\"elementName test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html``);\n });\n\n it(\"basic will it blend\", async () => {\n expect(element).to.exist;\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "simple-login": { - "element": "simple-login", - "component": { - "properties": [ - { - "name": "username", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"\"" - }, - { - "name": "password", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"\"" - }, - { - "name": "loading", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,", - "defaultValue": "false" - }, - { - "name": "userInputLabel", - "type": "String", - "attribute": "user-input-label", - "config": "type: String,\n attribute: \"user-input-label\",", - "defaultValue": "\"User name\"" - }, - { - "name": "userInputErrMsg", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"User name required\"" - }, - { - "name": "passwordInputLabel", - "type": "String", - "attribute": "password-input-label", - "config": "type: String,\n attribute: \"password-input-label\",", - "defaultValue": "\"Password\"" - }, - { - "name": "passwordInputErrMsg", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"Password required\"" - }, - { - "name": "loginBtnText", - "type": "String", - "attribute": "login-btn-text", - "config": "type: String,\n attribute: \"login-btn-text\",", - "defaultValue": "\"Login\"" - } - ], - "slots": [], - "events": [ - "simple-login-login" - ], - "methods": [ - "if" - ], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../simple-login.js\";\n\ndescribe(\"simple-login test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"simple-login passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"simple-login passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"simple-login can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: username, password, loading, userInputLabel, userInputErrMsg, passwordInputLabel, passwordInputErrMsg, loginBtnText" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: simple-login-login" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "simple-modal": { - "element": "simple-modal", - "component": { - "properties": [ - { - "name": "title", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"\"" - }, - { - "name": "opened", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "closeLabel", - "type": "String", - "attribute": "close-label", - "config": "attribute: \"close-label\",\n type: String,", - "defaultValue": "\"Close\"" - }, - { - "name": "closeIcon", - "type": "String", - "attribute": "close-icon", - "config": "type: String,\n attribute: \"close-icon\",", - "defaultValue": "\"close\"" - }, - { - "name": "invokedBy", - "type": "Object", - "attribute": null, - "config": "type: Object," - }, - { - "name": "modal", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,", - "defaultValue": "false" - }, - { - "name": "mode", - "type": "String", - "attribute": null, - "config": "type: String,\n reflect: true," - } - ], - "slots": [], - "events": [ - "simple-toast-hide" - ], - "methods": [ - "if", - "showEvent", - "show", - "for", - "close", - "open", - "while" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../simple-modal.js\";\n\ndescribe(\"simple-modal test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"simple-modal passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"simple-modal passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"simple-modal can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: title, opened, closeLabel, closeIcon, invokedBy, modal, mode" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: simple-toast-hide" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "simple-picker": { - "element": "simple-picker", - "component": { - "properties": [ - { - "name": "allowNull", - "type": "Boolean", - "attribute": "allow-null", - "config": "type: Boolean,\n reflect: true,\n attribute: \"allow-null\",", - "defaultValue": "false" - }, - { - "name": "alignRight", - "type": "Boolean", - "attribute": "align-right", - "config": "type: Boolean,\n reflect: true,\n attribute: \"align-right\",", - "defaultValue": "false" - }, - { - "name": "ariaLabelledby", - "type": "String", - "attribute": "aria-labelledby", - "config": "type: String,\n attribute: \"aria-labelledby\",", - "defaultValue": "null" - }, - { - "name": "blockLabel", - "type": "Boolean", - "attribute": "block-label", - "config": "type: Boolean,\n reflect: true,\n attribute: \"block-label\",", - "defaultValue": "false" - }, - { - "name": "disabled", - "type": "Boolean", - "attribute": "disabled", - "config": "type: Boolean,\n reflect: true,\n attribute: \"disabled\",", - "defaultValue": "false" - }, - { - "name": "expanded", - "type": "Boolean", - "attribute": "expanded", - "config": "type: Boolean,\n reflect: true,\n attribute: \"expanded\",", - "defaultValue": "false" - }, - { - "name": "hideOptionLabels", - "type": "Boolean", - "attribute": "hide-option-labels", - "config": "type: Boolean,\n reflect: true,\n attribute: \"hide-option-labels\",", - "defaultValue": "false" - }, - { - "name": "hideNullOption", - "type": "Boolean", - "attribute": "hide-null-option", - "config": "type: Boolean,\n reflect: true,\n attribute: \"hide-null-option\"," - }, - { - "name": "hideSample", - "type": "Boolean", - "attribute": "hide-sample", - "config": "type: Boolean,\n reflect: true,\n attribute: \"hide-sample\",", - "defaultValue": "false" - }, - { - "name": "justify", - "type": "Boolean", - "attribute": "justify", - "config": "type: Boolean,\n reflect: true,\n attribute: \"justify\"," - }, - { - "name": "label", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "null" - }, - { - "name": "options", - "type": "Array", - "attribute": null, - "config": "type: Array,", - "defaultValue": "[]" - }, - { - "name": "titleAsHtml", - "type": "Boolean", - "attribute": "title-as-html", - "config": "type: Boolean,\n attribute: \"title-as-html\",", - "defaultValue": "false" - }, - { - "name": "value", - "type": "String", - "attribute": null, - "config": "type: String,\n reflect: true,", - "defaultValue": "null" - }, - { - "name": "__activeDesc", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"option-0-0\"" - }, - { - "name": "__options", - "type": "Array", - "attribute": null, - "config": "type: Array," - }, - { - "name": "__selectedOption", - "type": "Object", - "attribute": null, - "config": "type: Object," - }, - { - "name": "__ready", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,", - "defaultValue": "false" - } - ], - "slots": [], - "events": [ - "changed", - "click", - "mousedown", - "keydown", - "option-focus", - "value-changed", - "change", - "expand", - "collapse" - ], - "methods": [ - "if", - "for", - "renderItem", - "setOptions" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "SimplePickerBehaviors" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../lib/simple-emoji-picker.js\";\n\ndescribe(\"simple-picker test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"simple-picker passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"simple-picker passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"simple-picker can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: allowNull, alignRight, ariaLabelledby, blockLabel, disabled, expanded, hideOptionLabels, hideNullOption, hideSample, justify, label, options, titleAsHtml, value, __activeDesc, __options, __selectedOption, __ready" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: changed, click, mousedown, keydown, option-focus, value-changed, change, expand, collapse" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "simple-popover": { - "element": "simple-popover", - "component": { - "properties": [], - "slots": [ - "default" - ], - "events": [], - "methods": [ - "if" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../simple-popover.js\";\n/*\ndescribe(\"simple-popover test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html` `\n );\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"simple-popover passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"simple-popover passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"simple-popover can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ], - "needsWork": true, - "priority": "MEDIUM" - }, - "simple-progress": { - "element": "simple-progress", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [ - "if", - "attributeChangedCallback" - ], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../simple-progress.js\";\n\ndescribe(\"simple-progress test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"simple-progress passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"simple-progress passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"simple-progress can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "simple-range-input": { - "element": "simple-range-input", - "component": { - "properties": [ - { - "name": "dragging", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean, reflect: true", - "defaultValue": "false" - }, - { - "name": "immediateValue", - "type": "Number", - "attribute": "immediate-value", - "config": "type: Number, attribute: \"immediate-value\"", - "defaultValue": "0" - }, - { - "name": "value", - "type": "Number", - "attribute": null, - "config": "type: Number, reflect: true", - "defaultValue": "0" - }, - { - "name": "min", - "type": "Number", - "attribute": null, - "config": "type: Number", - "defaultValue": "0" - }, - { - "name": "step", - "type": "Number", - "attribute": null, - "config": "type: Number", - "defaultValue": "1" - }, - { - "name": "max", - "type": "Number", - "attribute": null, - "config": "type: Number", - "defaultValue": "100" - }, - { - "name": "label", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "\"Range input\"" - }, - { - "name": "disabled", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean, reflect: true", - "defaultValue": "false" - } - ], - "slots": [], - "events": [ - "immediate-value-changed", - "value-changed" - ], - "methods": [ - "if" - ], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\nimport \"../simple-range-input.js\";\ndescribe(\"Image comparison\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: dragging, immediateValue, value, min, step, max, label, disabled" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: immediate-value-changed, value-changed" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: immediate-value" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "simple-search": { - "element": "simple-search", - "component": { - "properties": [ - { - "name": "alwaysFloatLabel", - "type": "Boolean", - "attribute": "always-float-label", - "config": "attribute: \"always-float-label\",\n type: Boolean,", - "defaultValue": "false" - }, - { - "name": "caseSensitive", - "type": "Boolean", - "attribute": "case-sensitive", - "config": "attribute: \"case-sensitive\",\n type: Boolean,", - "defaultValue": "null" - }, - { - "name": "controls", - "type": "String", - "attribute": "controls", - "config": "attribute: \"controls\",\n type: String,", - "defaultValue": "null" - }, - { - "name": "inline", - "type": "Boolean", - "attribute": "inline", - "config": "attribute: \"inline\",\n type: Boolean," - }, - { - "name": "nextButtonIcon", - "type": "String", - "attribute": "next-button-icon", - "config": "attribute: \"next-button-icon\",\n type: String,", - "defaultValue": "\"arrow-forward\"" - }, - { - "name": "nextButtonLabel", - "type": "String", - "attribute": "next-button-label", - "config": "attribute: \"next-button-label\",\n type: String,", - "defaultValue": "\"next result\"" - }, - { - "name": "noLabelFloat", - "type": "Boolean", - "attribute": "no-label-float", - "config": "attribute: \"no-label-float\",\n type: Boolean,", - "defaultValue": "false" - }, - { - "name": "prevButtonIcon", - "type": "String", - "attribute": "prev-button-icon", - "config": "attribute: \"prev-button-icon\",\n type: String,", - "defaultValue": "\"arrow-back\"" - }, - { - "name": "prevButtonLabel", - "type": "String", - "attribute": "prev-button-label", - "config": "attribute: \"prev-button-label\",\n type: String,", - "defaultValue": "\"previous result\"" - }, - { - "name": "resultCount", - "type": "Number", - "attribute": "result-count", - "config": "attribute: \"result-count\",\n type: Number,", - "defaultValue": "0" - }, - { - "name": "resultPointer", - "type": "Number", - "attribute": "result-pointer", - "config": "attribute: \"result-pointer\",\n type: Number,", - "defaultValue": "0" - }, - { - "name": "selector", - "type": "String", - "attribute": "selector", - "config": "attribute: \"selector\",\n type: String,", - "defaultValue": "null" - }, - { - "name": "searchInputIcon", - "type": "String", - "attribute": "search-input-icon", - "config": "attribute: \"search-input-icon\",\n type: String,", - "defaultValue": "\"search\"" - }, - { - "name": "searchInputLabel", - "type": "String", - "attribute": "search-input-label", - "config": "attribute: \"search-input-label\",\n type: String,", - "defaultValue": "\"search\"" - }, - { - "name": "searchTerms", - "type": "Array", - "attribute": "search-terms", - "config": "attribute: \"search-terms\",\n type: Array,", - "defaultValue": "[]" - }, - { - "name": "target", - "type": "Object", - "attribute": null, - "config": "type: Object,", - "defaultValue": "null" - }, - { - "name": "__hideNext", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,", - "defaultValue": "true" - }, - { - "name": "__hidePrev", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,", - "defaultValue": "true" - } - ], - "slots": [], - "events": [ - "simple-search", - "goto-result" - ], - "methods": [ - "if", - "for", - "findMatches" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../simple-search.js\";\n\ndescribe(\"simple-search test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"simple-search passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"simple-search passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"simple-search can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: alwaysFloatLabel, caseSensitive, controls, inline, nextButtonIcon, nextButtonLabel, noLabelFloat, prevButtonIcon, prevButtonLabel, resultCount, resultPointer, selector, searchInputIcon, searchInputLabel, searchTerms, target, __hideNext, __hidePrev" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: simple-search, goto-result" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "simple-toast": { - "element": "simple-toast", - "component": { - "properties": [ - { - "name": "opened", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true," - }, - { - "name": "text", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "classStyle", - "type": "String", - "attribute": "class-style", - "config": "type: String,\n attribute: \"class-style\"," - }, - { - "name": "closeText", - "type": "String", - "attribute": "close-text", - "config": "type: String,\n attribute: \"close-text\"," - }, - { - "name": "duration", - "type": "Number", - "attribute": null, - "config": "type: Number," - }, - { - "name": "eventCallback", - "type": "String", - "attribute": "event-callback", - "config": "type: String,\n attribute: \"event-callback\"," - }, - { - "name": "closeButton", - "type": "Boolean", - "attribute": "close-button", - "config": "type: Boolean,\n reflect: true,\n attribute: \"close-button\"," - } - ], - "slots": [ - "default" - ], - "events": [], - "methods": [ - "if", - "hideSimpleToast", - "openedChanged", - "setDefaultToast", - "while", - "showSimpleToast", - "show", - "hide" - ], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../simple-toast.js\";\n\ndescribe(\"simple-toast test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"simple-toast passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"simple-toast passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"simple-toast can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: opened, text, classStyle, closeText, duration, eventCallback, closeButton" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "simple-toolbar": { - "element": "simple-toolbar", - "component": { - "properties": [ - { - "name": "alwaysExpanded", - "type": "Boolean", - "attribute": "always-expanded", - "config": "name: \"alwaysExpanded\",\n type: Boolean,\n attribute: \"always-expanded\",\n reflect: true," - }, - { - "name": "ariaControls", - "type": "String", - "attribute": "aria-controls", - "config": "name: \"ariaControls\",\n type: String,\n attribute: \"aria-controls\",\n reflect: true," - }, - { - "name": "ariaLabel", - "type": "String", - "attribute": "aria-label", - "config": "name: \"ariaLabel\",\n type: String,\n attribute: \"aria-label\",\n reflect: true," - }, - { - "name": "collapsed", - "type": "Boolean", - "attribute": "collapsed", - "config": "name: \"collapsed\",\n type: Boolean,\n attribute: \"collapsed\",\n reflect: true,", - "defaultValue": "true" - }, - { - "name": "config", - "type": "Array", - "attribute": "config", - "config": "name: \"config\",\n type: Array,\n attribute: \"config\",", - "defaultValue": "[]" - }, - { - "name": "id", - "type": "String", - "attribute": "id", - "config": "name: \"id\",\n type: String,\n attribute: \"id\",\n reflect: true," - }, - { - "name": "moreShortcuts", - "type": "Object", - "attribute": "more-shortcuts", - "config": "name: \"moreShortcuts\",\n attribute: \"more-shortcuts\",\n type: Object," - }, - { - "name": "shortcutKeys", - "type": "Object", - "attribute": "shortcut-keys", - "config": "name: \"shortcutKeys\",\n attribute: \"shortcut-keys\",\n type: Object," - }, - { - "name": "sticky", - "type": "Boolean", - "attribute": "sticky", - "config": "name: \"sticky\",\n type: Boolean,\n attribute: \"sticky\",\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "__buttons", - "type": "Array", - "attribute": null, - "config": "name: \"__buttons\",\n type: Array,", - "defaultValue": "[]" - }, - { - "name": "collapseDisabled", - "type": "Boolean", - "attribute": "collapse-disabled", - "config": "type: Boolean,\n attribute: \"collapse-disabled\",\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "__focused", - "type": "Boolean", - "attribute": null, - "config": "name: \"__focused\",\n type: Boolean,", - "defaultValue": "false" - }, - { - "name": "__hovered", - "type": "Boolean", - "attribute": null, - "config": "name: \"__hovered\",\n type: Boolean,", - "defaultValue": "false" - } - ], - "slots": [], - "events": [ - "shortcut-key-pressed" - ], - "methods": [ - "if", - "addButton", - "addButtonGroup", - "clearToolbar", - "deregisterButton", - "registerButton", - "resizeToolbar", - "getItemIndex", - "getItem", - "setCurrentItem", - "focusOn", - "updateButton", - "updateToolbar", - "switch", - "while" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "SimpleToolbarBehaviors" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../simple-toolbar.js\";\n\ndescribe(\"simple-toolbar test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"simple-toolbar passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"simple-toolbar passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"simple-toolbar can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: alwaysExpanded, ariaControls, ariaLabel, collapsed, config, id, moreShortcuts, shortcutKeys, sticky, __buttons, collapseDisabled, __focused, __hovered" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: shortcut-key-pressed" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "simple-tooltip": { - "element": "simple-tooltip", - "component": { - "properties": [ - { - "name": "for", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "manualMode", - "type": "Boolean", - "attribute": "manual-mode", - "config": "type: Boolean, attribute: \"manual-mode\"", - "defaultValue": "false" - }, - { - "name": "position", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "\"bottom\"" - }, - { - "name": "fitToVisibleBounds", - "type": "Boolean", - "attribute": "fit-to-visible-bounds", - "config": "type: Boolean,\n attribute: \"fit-to-visible-bounds\",", - "defaultValue": "false" - }, - { - "name": "offset", - "type": "Number", - "attribute": null, - "config": "type: Number", - "defaultValue": "14" - }, - { - "name": "marginTop", - "type": "Number", - "attribute": "margin-top", - "config": "type: Number, attribute: \"margin-top\"", - "defaultValue": "14" - }, - { - "name": "animationDelay", - "type": "Number", - "attribute": "animation-delay", - "config": "type: Number, attribute: \"animation-delay\"" - }, - { - "name": "animationEntry", - "type": "String", - "attribute": "animation-entry", - "config": "type: String, attribute: \"animation-entry\"", - "defaultValue": "\"\"" - }, - { - "name": "animationExit", - "type": "String", - "attribute": "animation-exit", - "config": "type: String, attribute: \"animation-exit\"", - "defaultValue": "\"\"" - }, - { - "name": "_showing", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean" - } - ], - "slots": [ - "default" - ], - "events": [], - "methods": [ - "if", - "playAnimation", - "cancelAnimation", - "show", - "for", - "hide", - "updatePosition", - "switch" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../simple-tooltip.js\";\n\ndescribe(\"simple-tooltip test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"simple-tooltip passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"simple-tooltip passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"simple-tooltip can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: for, manualMode, position, fitToVisibleBounds, offset, marginTop, animationDelay, animationEntry, animationExit, _showing" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "simple-wc": { - "element": "simple-wc", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [ - "for", - "if", - "haxProperties" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../simple-wc.js\";\n\ndescribe(\"simple-wc test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html` `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"simple-wc passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"simple-wc passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"simple-wc can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "social-share-link": { - "element": "social-share-link", - "component": { - "properties": [ - { - "name": "buttonStyle", - "type": "Boolean", - "attribute": "button-style", - "config": "type: Boolean,\n reflect: true,\n attribute: \"button-style\",", - "defaultValue": "false" - }, - { - "name": "image", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"\"" - }, - { - "name": "message", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"\"" - }, - { - "name": "mode", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "null" - }, - { - "name": "text", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "null" - }, - { - "name": "type", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"Twitter\"" - }, - { - "name": "url", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "null" - }, - { - "name": "__href", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "__icon", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "__linkText", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "__showIcon", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean," - } - ], - "slots": [], - "events": [], - "methods": [ - "if", - "switch" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../social-share-link.js\";\n\ndescribe(\"social-share-link test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"social-share-link passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"social-share-link passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"social-share-link can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: buttonStyle, image, message, mode, text, type, url, __href, __icon, __linkText, __showIcon" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "sorting-question": { - "element": "sorting-question", - "component": { - "properties": [ - { - "name": "numberCorrect", - "type": "Number", - "attribute": null, - "config": "type: Number", - "defaultValue": "0" - } - ], - "slots": [], - "events": [ - "simple-toast-hide", - "user-engagement" - ], - "methods": [ - "getOptions", - "if", - "checkAnswerCallback", - "resetAnswer", - "for", - "renderInteraction", - "inactiveCase", - "renderDirections", - "renderFeedback", - "haxinlineContextMenu", - "haxClickInlineAdd", - "haxClickInlineRemove" - ], - "hasHaxProperties": true, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../sorting-question.js\";\n\ndescribe(\"sorting-question test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"sorting-question passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"sorting-question passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"sorting-question can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: numberCorrect" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: simple-toast-hide, user-engagement" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "spotify-embed": { - "element": "spotify-embed", - "component": { - "properties": [ - { - "name": "source", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "null" - }, - { - "name": "theme", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "null" - }, - { - "name": "size", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "\"normal\"" - }, - { - "name": "playlistid", - "type": "String", - "attribute": null, - "config": "type: String, attribute: false", - "defaultValue": "null" - }, - { - "name": "type", - "type": "String", - "attribute": null, - "config": "type: String, attribute: false", - "defaultValue": "null" - }, - { - "name": "editing", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true,", - "defaultValue": "false" - } - ], - "slots": [], - "events": [], - "methods": [ - "if", - "haxHooks", - "haxactiveElementChanged", - "haxeditModeChanged" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\nimport \"../spotify-embed.js\";\n\ndescribe(\"elementName test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"basic will it blend\", async () => {\n expect(element).to.exist;\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: source, theme, size, playlistid, type, editing" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "star-rating": { - "element": "star-rating", - "component": { - "properties": [ - { - "name": "score", - "type": "Number", - "attribute": null, - "config": "type: Number", - "defaultValue": "10" - }, - { - "name": "possible", - "type": "Number", - "attribute": null, - "config": "type: Number", - "defaultValue": "100" - }, - { - "name": "interactive", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean, reflect: true" - }, - { - "name": "numStars", - "type": "Number", - "attribute": "num-stars", - "config": "type: Number, attribute: \"num-stars\"", - "defaultValue": "5" - }, - { - "name": "_calPercent", - "type": "Number", - "attribute": null, - "config": "type: Number", - "defaultValue": "0" - } - ], - "slots": [], - "events": [ - "star-rating-click" - ], - "methods": [ - "renderStar", - "if", - "while", - "interactiveEvent" - ], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../star-rating.js\";\n\ndescribe(\"star-rating test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"star-rating passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"star-rating passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"star-rating can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: score, possible, interactive, numStars, _calPercent" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: star-rating-click" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "stop-note": { - "element": "stop-note", - "component": { - "properties": [ - { - "name": "title", - "type": "String", - "attribute": null, - "config": "type: String,\n reflect: true,", - "defaultValue": "\"\"" - }, - { - "name": "url", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "null" - }, - { - "name": "icon", - "type": "String", - "attribute": null, - "config": "type: String,\n reflect: true,", - "defaultValue": "\"stopnoteicons:stop-icon\"" - }, - { - "name": "status", - "type": "String", - "attribute": null, - "config": "type: String,\n reflect: true,", - "defaultValue": "null" - } - ], - "slots": [ - "default", - "message" - ], - "events": [], - "methods": [ - "if", - "haxHooks", - "haxeditModeChanged", - "haxactiveElementChanged" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "I18NMixin" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": true, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../stop-note.js\";\n\ndescribe(\"stop-note test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html`\n You can write any confirmation\n `,\n );\n });\n\n it(\"message slot correct\", async () => {\n expect(\n element.shadowRoot\n .querySelector(\"slot[name='message']\")\n .assignedNodes({ flatten: true })[0].textContent,\n ).to.equal(\"You can write any confirmation\");\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: title, url, icon, status" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "super-daemon": { - "element": "super-daemon", - "component": { - "properties": [ - { - "name": "santaMode", - "type": "Boolean", - "attribute": "santa-mode", - "config": "type: Boolean, reflect: true, attribute: \"santa-mode\"" - }, - { - "name": "opened", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean, reflect: true" - }, - { - "name": "loading", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean, reflect: true" - }, - { - "name": "key1", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "key2", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "icon", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "items", - "type": "Array", - "attribute": null, - "config": "type: Array" - }, - { - "name": "programResults", - "type": "Array", - "attribute": null, - "config": "type: Array" - }, - { - "name": "programName", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "allItems", - "type": "Array", - "attribute": null, - "config": "type: Array" - }, - { - "name": "context", - "type": "Array", - "attribute": null, - "config": "type: Array" - }, - { - "name": "commandContext", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "program", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "programSearch", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "like", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "value", - "type": "String", - "attribute": null, - "config": "type: String" - }, - { - "name": "mini", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean" - }, - { - "name": "wand", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean, reflect: true" - }, - { - "name": "activeNode", - "type": "Object", - "attribute": null, - "config": "type: Object" - }, - { - "name": "programTarget", - "type": "Object", - "attribute": null, - "config": "type: Object" - }, - { - "name": "voiceSearch", - "type": "Boolean", - "attribute": "voice-search", - "config": "type: Boolean, reflect: true, attribute: \"voice-search\"" - }, - { - "name": "voiceCommands", - "type": "Object", - "attribute": null, - "config": "type: Object" - }, - { - "name": "listeningForInput", - "type": "Boolean", - "attribute": "listening-for-input", - "config": "type: Boolean,\n reflect: true,\n attribute: \"listening-for-input\"," - } - ], - "slots": [], - "events": [ - "super-daemon-close", - "super-daemon-toast-hide", - "super-daemon-command-context-changed", - "super-daemon-context-changed" - ], - "methods": [ - "if", - "waveWand", - "runProgramEvent", - "elementMethod", - "elementClick", - "defineOptionEvent", - "defineOption", - "updateSearchInputViaVoice", - "addVoiceCommand", - "keyHandler", - "setListeningStatus", - "close", - "filterItems", - "playSound", - "appendContext", - "removeContext", - "clickOnMiniMode", - "miniCancel", - "open", - "focusout", - "while", - "noResultsSlot", - "likeChanged", - "randomResponse", - "toggleSantaMode", - "merlinSpeak", - "promptMerlin", - "stopMerlin", - "closeMerlin", - "belsnickel", - "defaultVoiceCommands", - "itemsForDisplay", - "reprocessVoiceCommands", - "commandContextChanged", - "switch", - "keyHandlerCallback", - "allowedCallback" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\nimport \"../super-daemon.js\";\n\ndescribe(\"elementName test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html``);\n });\n\n it(\"basic will it blend\", async () => {\n expect(element).to.exist;\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: santaMode, opened, loading, key1, key2, icon, items, programResults, programName, allItems, context, commandContext, program, programSearch, like, value, mini, wand, activeNode, programTarget, voiceSearch, voiceCommands, listeningForInput" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: super-daemon-close, super-daemon-toast-hide, super-daemon-command-context-changed, super-daemon-context-changed" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: santa-mode, voice-search, listening-for-input" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "tagging-question": { - "element": "tagging-question", - "component": { - "properties": [ - { - "name": "dragging", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean, reflect: true", - "defaultValue": "false" - }, - { - "name": "dragEnter", - "type": "Boolean", - "attribute": "drag-enter", - "config": "type: Boolean, reflect: true, attribute: \"drag-enter\"", - "defaultValue": "false" - }, - { - "name": "dragEnterAnswer", - "type": "Boolean", - "attribute": "drag-enter-answer", - "config": "type: Boolean,\n reflect: true,\n attribute: \"drag-enter-answer\",", - "defaultValue": "false" - }, - { - "name": "selectedAnswers", - "type": "Array", - "attribute": null, - "config": "type: Array", - "defaultValue": "[]" - } - ], - "slots": [], - "events": [ - "simple-toast-hide" - ], - "methods": [ - "renderDirections", - "renderInteraction", - "isCorrect", - "renderFeedback", - "randomizeOptions", - "for", - "handleDrag", - "handleDragEnd", - "allowDrop", - "allowDropAnswer", - "handleDrop", - "handleTagMove", - "if", - "handleTagClick", - "addTag", - "removeTag", - "resetAnswer" - ], - "hasHaxProperties": true, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": false, - "hasAccessibilityTests": false, - "testedProperties": [], - "testedSlots": [], - "testedEvents": [], - "testedMethods": [] - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_TEST_FILE", - "message": "No test file found. Create test/${elementName}.test.js" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "terrible-themes": { - "element": "terrible-themes", - "component": { - "properties": [], - "slots": [ - "default" - ], - "events": [], - "methods": [ - "if", - "for" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "HAXCMSRememberRoute" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\nimport \"../terrible-themes.js\";\n\ndescribe(\"elementName test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html``);\n });\n\n it(\"basic will it blend\", async () => {\n expect(element).to.exist;\n });\n /*\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });*/\n});\n" - }, - "recommendations": [ - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ], - "needsWork": true, - "priority": "MEDIUM" - }, - "training-theme": { - "element": "training-theme", - "component": { - "properties": [ - { - "name": "items", - "type": "Array", - "attribute": null, - "config": "type: Array", - "defaultValue": "[]" - }, - { - "name": "activeId", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "null" - }, - { - "name": "time", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "0" - }, - { - "name": "prevPage", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "nextPage", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "maxIndex", - "type": "Number", - "attribute": null, - "config": "type: Number", - "defaultValue": "0" - } - ], - "slots": [ - "default" - ], - "events": [], - "methods": [ - "if" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "HAXCMSOperationButtons" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\nimport \"../training-theme.js\";\n\ndescribe(\"elementName test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html``);\n });\n\n it(\"basic will it blend\", async () => {\n expect(element).to.exist;\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: items, activeId, time, prevPage, nextPage, maxIndex" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "twitter-embed": { - "element": "twitter-embed", - "component": { - "properties": [ - { - "name": "tweet", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "null" - }, - { - "name": "_haxstate", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean," - }, - { - "name": "lang", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "globalThis.document.body.getAttribute(\"xml:lang\") ||\n globalThis.document.body.getAttribute(\"lang\") ||\n globalThis.document.documentElement.getAttribute(\"xml:lang\") ||\n globalThis.document.documentElement.getAttribute(\"lang\") ||\n globalThis.navigator.language ||\n FALLBACK_LANG" - }, - { - "name": "dataWidth", - "type": "String", - "attribute": "data-width", - "config": "type: String,\n attribute: \"data-width\",", - "defaultValue": "\"550px\"" - }, - { - "name": "dataTheme", - "type": "String", - "attribute": "data-theme", - "config": "type: String,\n attribute: \"data-theme\",", - "defaultValue": "\"light\"" - }, - { - "name": "tweetId", - "type": "String", - "attribute": "tweet-id", - "config": "type: String,\n attribute: \"tweet-id\",", - "defaultValue": "null" - }, - { - "name": "noPopups", - "type": "Boolean", - "attribute": "no-popups", - "config": "type: Boolean,\n attribute: \"no-popups\"," - }, - { - "name": "allowPopups", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"allow-popups\"" - } - ], - "slots": [], - "events": [ - "i18n-manager-register-element" - ], - "methods": [ - "haxHooks", - "haxgizmoRegistration", - "haxactiveElementChanged", - "if", - "haxeditModeChanged" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../twitter-embed.js\";\n\ndescribe(\"twitter-embed test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"twitter-embed passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"twitter-embed passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"twitter-embed can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: tweet, _haxstate, lang, dataWidth, dataTheme, tweetId, noPopups, allowPopups" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: i18n-manager-register-element" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "type-writer": { - "element": "type-writer", - "component": { - "properties": [ - { - "name": "delay", - "type": "Number", - "attribute": null, - "config": "type: Number,", - "defaultValue": "100" - }, - { - "name": "cursorDuration", - "type": "Number", - "attribute": "cursor-duration", - "config": "type: Number,\n attribute: \"cursor-duration\",", - "defaultValue": "0" - }, - { - "name": "text", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "speed", - "type": "Number", - "attribute": null, - "config": "type: Number,", - "defaultValue": "150" - }, - { - "name": "elementVisible", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean," - }, - { - "name": "eraseSpeed", - "type": "Number", - "attribute": "erase-speed", - "config": "type: Number,\n attribute: \"erase-speed\",", - "defaultValue": "80" - }, - { - "name": "typing", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "_length", - "type": "Number", - "attribute": null, - "config": "type: Number," - }, - { - "name": "_oldText", - "type": "String", - "attribute": null, - "config": "type: String," - } - ], - "slots": [], - "events": [ - "type-writer-end" - ], - "methods": [ - "if", - "type", - "erase" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "IntersectionObserverMixin" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../type-writer.js\";\n\ndescribe(\"type-writer test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"type-writer passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"type-writer passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"type-writer can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: delay, cursorDuration, text, speed, elementVisible, eraseSpeed, typing, _length, _oldText" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: type-writer-end" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "un-sdg": { - "element": "un-sdg", - "component": { - "properties": [ - { - "name": "loading", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "'lazy'" - }, - { - "name": "fetchpriority", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "'low'" - }, - { - "name": "goal", - "type": "Number", - "attribute": null, - "config": "type: Number, reflect: true", - "defaultValue": "1" - }, - { - "name": "colorOnly", - "type": "Boolean", - "attribute": "color-only", - "config": "type: Boolean, attribute: 'color-only'", - "defaultValue": "false" - }, - { - "name": "alt", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "''" - } - ], - "slots": [], - "events": [], - "methods": [ - "if" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { html, fixture, expect } from '@open-wc/testing';\nimport {unSDGGoalData} from \"../un-sdg.js\";\n\nconst goalnum = 4;\ndescribe(\"UN SDG tests\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"basic will it blend\", async () => {\n expect(element).to.exist;\n });\n\n it(\"Number for goal\", async () => {\n expect(element.goal).to.equal(goalnum);\n });\n it(\"Number for goal\", async () => {\n expect(element.alt).to.equal(`Goal ${goalnum}: ${unSDGGoalData[goalnum-1].name}`);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: loading, fetchpriority, goal, colorOnly, alt" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: color-only" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "undo-manager": { - "element": "undo-manager", - "component": { - "properties": [ - { - "name": "canUndo", - "type": "Boolean", - "attribute": "can-undo", - "config": "type: Boolean,\n attribute: \"can-undo\"," - }, - { - "name": "canRedo", - "type": "Boolean", - "attribute": "can-redo", - "config": "type: Boolean,\n attribute: \"can-redo\"," - }, - { - "name": "undoStackObserverProps", - "type": "Object", - "attribute": null, - "config": "type: Object," - }, - { - "name": "target", - "type": "Object", - "attribute": null, - "config": "type: Object," - }, - { - "name": "stack", - "type": "Object", - "attribute": null, - "config": "type: Object," - } - ], - "slots": [ - "default" - ], - "events": [ - "stack-changed", - "can-undo-changed", - "can-redo-changed" - ], - "methods": [ - "if", - "undoManagerStackLogic", - "undo", - "redo", - "commands", - "execute", - "canUndo", - "canRedo", - "changed" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "UndoManagerBehaviors" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../undo-manager.js\";\n\ndescribe(\"undo-manager test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"undo-manager passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"undo-manager passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"undo-manager can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: canUndo, canRedo, undoStackObserverProps, target, stack" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: stack-changed, can-undo-changed, can-redo-changed" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "unity-webgl": { - "element": "unity-webgl", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [ - "if", - "attributeChangedCallback" - ], - "hasHaxProperties": true, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n/*\nimport \"../unity-webgl.js\";\n\ndescribe(\"unity-webgl test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html`\n `\n );\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n*/\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"unity-webgl passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"unity-webgl passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"unity-webgl can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "user-action": { - "element": "user-action", - "component": { - "properties": [], - "slots": [], - "events": [ - "i18n-manager-register-element" - ], - "methods": [ - "if", - "attributeChangedCallback", - "switch", - "handleIntersectionCallback", - "for", - "userActionEvent", - "haxHooks", - "haxgizmoRegistration", - "haxactiveElementChanged", - "haxeditModeChanged" - ], - "hasHaxProperties": true, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../user-action.js\";\n\ndescribe(\"user-action test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"user-action passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"user-action passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"user-action can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: i18n-manager-register-element" - } - ], - "needsWork": true, - "priority": "MEDIUM" - }, - "user-scaffold": { - "element": "user-scaffold", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [ - "if", - "userActionArchitypes", - "userKeyDownAction", - "userPasteAction", - "userDropAction", - "userDragAction", - "userMouseAction", - "incrementWriteMemory", - "writeMemory", - "deleteMemory", - "readMemory", - "isBase64" - ], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\nimport \"../user-scaffold.js\";\n\ndescribe(\"elementName test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html``);\n });\n\n it(\"basic will it blend\", async () => {\n expect(element).to.exist;\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "utils": { - "element": "utils", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [ - "if", - "for", - "while", - "switch", - "function" - ], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": false, - "hasAccessibilityTests": false, - "testedProperties": [], - "testedSlots": [], - "testedEvents": [], - "testedMethods": [] - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_TEST_FILE", - "message": "No test file found. Create test/${elementName}.test.js" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "video-player": { - "element": "video-player", - "component": { - "properties": [ - { - "name": "sourceType", - "type": "String", - "attribute": null, - "config": "type: String", - "defaultValue": "\"\"" - }, - { - "name": "accentColor", - "type": "String", - "attribute": "accent-color", - "config": "type: String,\n attribute: \"accent-color\",\n reflect: true," - }, - { - "name": "crossorigin", - "type": "String", - "attribute": "crossorigin", - "config": "type: String,\n attribute: \"crossorigin\",\n reflect: true,", - "defaultValue": "\"anonymous\"" - }, - { - "name": "dark", - "type": "Boolean", - "attribute": "dark", - "config": "type: Boolean,\n attribute: \"dark\",\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "darkTranscript", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,", - "defaultValue": "false" - }, - { - "name": "disableInteractive", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,", - "defaultValue": "false" - }, - { - "name": "height", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "hideTimestamps", - "type": "Boolean", - "attribute": "hide-timestamps", - "config": "type: Boolean,\n attribute: \"hide-timestamps\",", - "defaultValue": "false" - }, - { - "name": "hideTranscript", - "type": "Boolean", - "attribute": "hide-transcript", - "config": "type: Boolean,\n reflect: true,\n attribute: \"hide-transcript\",", - "defaultValue": "false" - }, - { - "name": "id", - "type": "String", - "attribute": "id", - "config": "type: String,\n attribute: \"id\",\n reflect: true," - }, - { - "name": "learningMode", - "type": "Boolean", - "attribute": "learning-mode", - "config": "type: Boolean,\n attribute: \"learning-mode\",", - "defaultValue": "false" - }, - { - "name": "lang", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"en\"" - }, - { - "name": "linkable", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,", - "defaultValue": "false" - }, - { - "name": "mediaTitle", - "type": "String", - "attribute": "media-title", - "config": "type: String,\n attribute: \"media-title\",\n reflect: true," - }, - { - "name": "hideYoutubeLink", - "type": "Boolean", - "attribute": "hide-youtube-link", - "config": "type: Boolean,\n attribute: \"hide-youtube-link\",", - "defaultValue": "false" - }, - { - "name": "source", - "type": "String", - "attribute": null, - "config": "type: String,\n reflect: true,", - "defaultValue": "\"\"" - }, - { - "name": "sources", - "type": "Array", - "attribute": null, - "config": "type: Array,", - "defaultValue": "[]" - }, - { - "name": "sourceData", - "type": "Object", - "attribute": null, - "config": "type: Object," - }, - { - "name": "stickyCorner", - "type": "String", - "attribute": "sticky-corner", - "config": "type: String,\n attribute: \"sticky-corner\",\n reflect: true,", - "defaultValue": "\"none\"" - }, - { - "name": "track", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "tracks", - "type": "Array", - "attribute": null, - "config": "type: Array,", - "defaultValue": "[]" - }, - { - "name": "thumbnailSrc", - "type": "String", - "attribute": "thumbnail-src", - "config": "type: String,\n attribute: \"thumbnail-src\",\n reflect: true," - }, - { - "name": "width", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "playing", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,\n reflect: true,", - "defaultValue": "false" - }, - { - "name": "allowBackgroundPlay", - "type": "Boolean", - "attribute": "allow-background-play", - "config": "type: Boolean,\n reflect: true,\n attribute: \"allow-background-play\",", - "defaultValue": "false" - }, - { - "name": "startTime", - "type": "Number", - "attribute": "start-time", - "config": "type: Number,\n attribute: \"start-time\",", - "defaultValue": "null" - }, - { - "name": "endTime", - "type": "Number", - "attribute": "end-time", - "config": "type: Number,\n attribute: \"end-time\",", - "defaultValue": "null" - } - ], - "slots": [], - "events": [], - "methods": [ - "querySelectorAll", - "if", - "haxHooks", - "haxinlineContextMenu", - "haxClickTimeCode", - "haxpostProcessNodeToContent", - "setSourceData", - "playEvent", - "pauseEvent", - "restart", - "restartEvent", - "pause", - "play", - "seek", - "endTimeTest" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "IntersectionObserverMixin" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../video-player.js\";\n\ndescribe(\"video-player test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n \n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"video-player passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"video-player passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"video-player can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: sourceType, accentColor, crossorigin, dark, darkTranscript, disableInteractive, height, hideTimestamps, hideTranscript, id, learningMode, lang, linkable, mediaTitle, hideYoutubeLink, source, sources, sourceData, stickyCorner, track, tracks, thumbnailSrc, width, playing, allowBackgroundPlay, startTime, endTime" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "vocab-term": { - "element": "vocab-term", - "component": { - "properties": [ - { - "name": "popoverMode", - "type": "Boolean", - "attribute": "popover-mode", - "config": "type: Boolean, reflect: true, attribute: \"popover-mode\"", - "defaultValue": "false" - }, - { - "name": "detailsOpen", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean", - "defaultValue": "false" - } - ], - "slots": [], - "events": [], - "methods": [ - "haxHooks", - "haxactiveElementChanged", - "if", - "haxeditModeChanged", - "toggleOpen", - "detailsFocusOut" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../vocab-term.js\";\n\ndescribe(\"vocab-term test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"vocab-term passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"vocab-term passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"vocab-term can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: popoverMode, detailsOpen" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "voice-recorder": { - "element": "voice-recorder", - "component": { - "properties": [ - { - "name": "recording", - "type": "Boolean", - "attribute": null, - "config": "type: Boolean,", - "defaultValue": "false" - }, - { - "name": "label", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "\"Activate Recorder\"" - } - ], - "slots": [], - "events": [ - "voice-recorder-recording-blob" - ], - "methods": [ - "toggleRecording", - "recorder" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../voice-recorder.js\";\n\ndescribe(\"voice-recorder test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"voice-recorder passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"voice-recorder passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"voice-recorder can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: recording, label" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: voice-recorder-recording-blob" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "wc-autoload": { - "element": "wc-autoload", - "component": { - "properties": [], - "slots": [], - "events": [], - "methods": [ - "if", - "for", - "processNewElement" - ], - "hasHaxProperties": false, - "extendsLitElement": false, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../wc-autoload.js\";\n\ndescribe(\"wc-autoload test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"wc-autoload passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"wc-autoload passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"wc-autoload can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [], - "needsWork": false, - "priority": "LOW" - }, - "web-container": { - "element": "web-container", - "component": { - "properties": [ - { - "name": "fname", - "type": "String", - "attribute": null, - "config": "type: String, reflect: true", - "defaultValue": "null" - }, - { - "name": "status", - "type": "String", - "attribute": null, - "config": "type: String, reflect: true", - "defaultValue": "\"Loading\"" - }, - { - "name": "files", - "type": "Object", - "attribute": null, - "config": "type: Object" - }, - { - "name": "filesShown", - "type": "Array", - "attribute": null, - "config": "type: Array", - "defaultValue": "[]" - }, - { - "name": "hideTerminal", - "type": "Boolean", - "attribute": "hide-terminal", - "config": "type: Boolean, reflect: true, attribute: 'hide-terminal'", - "defaultValue": "false" - }, - { - "name": "hideEditor", - "type": "Boolean", - "attribute": "hide-editor", - "config": "type: Boolean, reflect: true, attribute: 'hide-editor'", - "defaultValue": "false" - }, - { - "name": "hideWindow", - "type": "Boolean", - "attribute": "hide-window", - "config": "type: Boolean, reflect: true, attribute: 'hide-window'", - "defaultValue": "false" - } - ], - "slots": [], - "events": [ - "web-container-dependencies-installing", - "web-container-dependencies-installed", - "web-container-npm-start", - "web-container-server-ready", - "web-container-command-start", - "web-container-command-finished" - ], - "methods": [ - "write", - "if", - "for", - "getLanguageFromFileEnding", - "setCodeEditor", - "editorValueChanged", - "refreshIframe" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "DDDSuper" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": false, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { html, fixture, expect } from '@open-wc/testing';\nimport \"../web-container.js\";\n\ndescribe(\"webContainer test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"basic will it blend\", async () => {\n expect(element).to.exist;\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: fname, status, files, filesShown, hideTerminal, hideEditor, hideWindow" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: web-container-dependencies-installing, web-container-dependencies-installed, web-container-npm-start, web-container-server-ready, web-container-command-start, web-container-command-finished" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: hide-terminal, hide-editor, hide-window" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "wikipedia-query": { - "element": "wikipedia-query", - "component": { - "properties": [ - { - "name": "title", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "__now", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "_title", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "headers", - "type": "Object", - "attribute": null, - "config": "type: Object," - }, - { - "name": "hideTitle", - "type": "Boolean", - "attribute": "hide-title", - "config": "type: Boolean,\n attribute: \"hide-title\",", - "defaultValue": "false" - }, - { - "name": "search", - "type": "String", - "attribute": null, - "config": "type: String," - }, - { - "name": "language", - "type": "String", - "attribute": null, - "config": "type: String,", - "defaultValue": "language.split(\"-\")[0]" - } - ], - "slots": [], - "events": [ - "i18n-manager-register-element", - "hax-register-app" - ], - "methods": [ - "updateArticle", - "if", - "handleResponse", - "for", - "haxHooks", - "haxgizmoRegistration" - ], - "hasHaxProperties": true, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "IntersectionObserverMixin" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../wikipedia-query.js\";\n\ndescribe(\"wikipedia-query test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"wikipedia-query passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"wikipedia-query passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"wikipedia-query can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: title, __now, _title, headers, hideTitle, search, language" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: i18n-manager-register-element, hax-register-app" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "word-count": { - "element": "word-count", - "component": { - "properties": [ - { - "name": "words", - "type": "Number", - "attribute": null, - "config": "type: Number" - }, - { - "name": "wordsPrefix", - "type": "String", - "attribute": "words-prefix", - "config": "type: String, attribute: \"words-prefix\"", - "defaultValue": "\"Word count\"" - } - ], - "slots": [ - "default" - ], - "events": [], - "methods": [ - "update", - "if" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [ - "I18NMixin" - ] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../word-count.js\";\n\ndescribe(\"word-count test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(html`\n \n `);\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n/*\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"word-count passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"word-count passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"word-count can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: words, wordsPrefix" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ], - "needsWork": true, - "priority": "HIGH" - }, - "wysiwyg-hax": { - "element": "wysiwyg-hax", - "component": { - "properties": [ - { - "name": "openDefault", - "type": "Boolean", - "attribute": "open-default", - "config": "type: Boolean,\n attribute: \"open-default\"," - }, - { - "name": "redirectLocation", - "type": "String", - "attribute": "redirect-location", - "config": "type: String,\n attribute: \"redirect-location\"," - }, - { - "name": "hidePanelOps", - "type": "Boolean", - "attribute": "hide-panel-ops", - "config": "type: Boolean,\n attribute: \"hide-panel-ops\"," - }, - { - "name": "elementAlign", - "type": "String", - "attribute": "element-align", - "config": "type: String,\n attribute: \"element-align\"," - }, - { - "name": "offsetMargin", - "type": "String", - "attribute": "offset-margin", - "config": "type: String,\n attribute: \"offset-margin\"," - }, - { - "name": "bodyValue", - "type": "String", - "attribute": "body-value", - "config": "type: String,\n attribute: \"body-value\"," - }, - { - "name": "allowedTags", - "type": "Array", - "attribute": "allowed-tags", - "config": "type: Array,\n attribute: \"allowed-tags\"," - }, - { - "name": "appStoreConnection", - "type": "String", - "attribute": "app-store-connection", - "config": "type: String,\n attribute: \"app-store-connection\"," - }, - { - "name": "saveButtonSelector", - "type": "Object", - "attribute": null, - "config": "type: Object," - }, - { - "name": "fieldClass", - "type": "String", - "attribute": "field-class", - "config": "type: String,\n attribute: \"field-class\"," - }, - { - "name": "fieldId", - "type": "String", - "attribute": "field-id", - "config": "type: String,\n attribute: \"field-id\"," - }, - { - "name": "fieldName", - "type": "String", - "attribute": "field-name", - "config": "type: String,\n attribute: \"field-name\"," - }, - { - "name": "syncBody", - "type": "Boolean", - "attribute": "sync-body", - "config": "type: Boolean,\n attribute: \"sync-body\",\n reflect: true," - }, - { - "name": "endPoint", - "type": "String", - "attribute": "end-point", - "config": "type: String,\n attribute: \"end-point\"," - }, - { - "name": "updatePageData", - "type": "String", - "attribute": "update-page-data", - "config": "type: String,\n attribute: \"update-page-data\"," - } - ], - "slots": [], - "events": [ - "hax-save", - "simple-modal-hide" - ], - "methods": [ - "if", - "createRenderRoot" - ], - "hasHaxProperties": false, - "extendsLitElement": true, - "extendsOtherBehaviors": [] - }, - "tests": { - "exists": true, - "hasAccessibilityTests": true, - "hasPropertyTests": false, - "hasAttributeTests": true, - "hasSlotTests": false, - "hasEventTests": false, - "hasMethodTests": false, - "content": "import { fixture, expect, html } from \"@open-wc/testing\";\n\nimport \"../wysiwyg-hax.js\";\n/*\ndescribe(\"wysiwyg-hax test\", () => {\n let element;\n beforeEach(async () => {\n element = await fixture(\n html` `\n );\n });\n\n it(\"passes the a11y audit\", async () => {\n await expect(element).shadowDom.to.be.accessible();\n });\n});\n\n\ndescribe(\"A11y/chai axe tests\", () => {\n it(\"wysiwyg-hax passes accessibility test\", async () => {\n const el = await fixture(html` `);\n await expect(el).to.be.accessible();\n });\n it(\"wysiwyg-hax passes accessibility negation\", async () => {\n const el = await fixture(\n html``\n );\n await assert.isNotAccessible(el);\n });\n});\n\n/*\n// Custom properties test\ndescribe(\"Custom Property Test\", () => {\n it(\"wysiwyg-hax can instantiate a element with custom properties\", async () => {\n const el = await fixture(html``);\n expect(el.foo).to.equal('bar');\n })\n})\n*/\n\n/*\n// Test if element is mobile responsive\ndescribe('Test Mobile Responsiveness', () => {\n before(async () => {z \n await setViewport({width: 375, height: 750});\n })\n it('sizes down to 360px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('360px');\n })\n}) */\n\n/*\n// Test if element sizes up for desktop behavior\ndescribe('Test Desktop Responsiveness', () => {\n before(async () => {\n await setViewport({width: 1000, height: 1000});\n })\n it('sizes up to 410px', async () => {\n const el = await fixture(html``);\n const width = getComputedStyle(el).width;\n expect(width).to.equal('410px');\n })\n it('hides mobile menu', async () => {\n const el await fixture(html``);\n const hidden = el.getAttribute('hidden');\n expect(hidden).to.equal(true);\n })\n}) */\n" - }, - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: openDefault, redirectLocation, hidePanelOps, elementAlign, offsetMargin, bodyValue, allowedTags, appStoreConnection, saveButtonSelector, fieldClass, fieldId, fieldName, syncBody, endPoint, updatePageData" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: hax-save, simple-modal-hide" - } - ], - "needsWork": true, - "priority": "HIGH" - } - } -} \ No newline at end of file diff --git a/test-audit-system.js b/test-audit-system.js deleted file mode 100644 index 928cbefbdb..0000000000 --- a/test-audit-system.js +++ /dev/null @@ -1,379 +0,0 @@ -#!/usr/bin/env node - -const fs = require('fs'); -const path = require('path'); -const { execSync } = require('child_process'); - -/** - * Parse a JavaScript file to extract component properties, slots, events, and methods - */ -function analyzeComponent(elementPath, elementName) { - const jsFilePath = path.join(elementPath, `${elementName}.js`); - - if (!fs.existsSync(jsFilePath)) { - return { - error: `Main JS file not found: ${jsFilePath}`, - properties: [], - slots: [], - events: [], - methods: [] - }; - } - - const content = fs.readFileSync(jsFilePath, 'utf8'); - - const analysis = { - properties: [], - slots: [], - events: [], - methods: [], - hasHaxProperties: false, - extendsLitElement: false, - extendsOtherBehaviors: [] - }; - - try { - // Extract properties from static get properties() - const propertiesMatch = content.match(/static\s+get\s+properties\s*\(\s*\)\s*\{[\s\S]*?return\s*\{([\s\S]*?)\}\s*;?\s*\}/); - if (propertiesMatch) { - const propertiesBlock = propertiesMatch[1]; - - // Parse individual properties - const propertyMatches = propertiesBlock.matchAll(/(\w+)\s*:\s*\{([^}]*)\}/g); - for (const match of propertyMatches) { - const propName = match[1]; - const propConfig = match[2]; - - let type = 'String'; // default - let attribute = null; - let defaultValue = null; - - const typeMatch = propConfig.match(/type\s*:\s*(\w+)/); - if (typeMatch) type = typeMatch[1]; - - const attributeMatch = propConfig.match(/attribute\s*:\s*["']([^"']+)["']/); - if (attributeMatch) attribute = attributeMatch[1]; - - analysis.properties.push({ - name: propName, - type, - attribute, - config: propConfig.trim() - }); - } - } - - // Extract default values from constructor - const constructorMatch = content.match(/constructor\s*\(\s*\)\s*\{([\s\S]*?)\}/); - if (constructorMatch) { - const constructorBody = constructorMatch[1]; - analysis.properties.forEach(prop => { - const defaultMatch = constructorBody.match(new RegExp(`this\\.${prop.name}\\s*=\\s*([^;]+);`)); - if (defaultMatch) { - prop.defaultValue = defaultMatch[1].trim(); - } - }); - } - - // Look for slots in render method - const renderMatch = content.match(/render\s*\(\s*\)\s*\{[\s\S]*?return\s+html`([\s\S]*?)`;?\s*\}/); - if (renderMatch) { - const template = renderMatch[1]; - - // Find slot elements - const slotMatches = template.matchAll(/]*>/g); - for (const match of slotMatches) { - const slotName = match[1] || 'default'; - if (!analysis.slots.includes(slotName)) { - analysis.slots.push(slotName); - } - } - } - - // Look for event dispatching - const eventMatches = content.matchAll(/(?:this\.)?dispatchEvent\s*\(\s*new\s+(?:CustomEvent|Event)\s*\(\s*["']([^"']+)["']/g); - for (const match of eventMatches) { - if (!analysis.events.includes(match[1])) { - analysis.events.push(match[1]); - } - } - - // Check for fire/fireEvent methods (common pattern) - const fireMatches = content.matchAll(/(?:this\.)?fire(?:Event)?\s*\(\s*["']([^"']+)["']/g); - for (const match of fireMatches) { - if (!analysis.events.includes(match[1])) { - analysis.events.push(match[1]); - } - } - - // Check if it has haxProperties - analysis.hasHaxProperties = content.includes('haxProperties') || content.includes('getHaxProperties'); - - // Check inheritance - analysis.extendsLitElement = content.includes('extends LitElement') || content.includes('extends') && content.includes('LitElement'); - - // Look for behavior mixins - const behaviorMatches = content.matchAll(/extends\s+(\w+)\s*\(/g); - for (const match of behaviorMatches) { - analysis.extendsOtherBehaviors.push(match[1]); - } - - // Extract public methods (non-private/protected) - const methodMatches = content.matchAll(/(?:^|\n)\s*([a-zA-Z][a-zA-Z0-9]*)\s*\([^)]*\)\s*\{/g); - for (const match of methodMatches) { - const methodName = match[1]; - // Skip constructor, render, and common lifecycle methods, and private methods - if (!methodName.startsWith('_') && - !['constructor', 'render', 'updated', 'firstUpdated', 'connectedCallback', 'disconnectedCallback', 'get', 'set', 'static'].includes(methodName)) { - if (!analysis.methods.includes(methodName)) { - analysis.methods.push(methodName); - } - } - } - - } catch (error) { - analysis.error = `Error parsing component: ${error.message}`; - } - - return analysis; -} - -/** - * Analyze existing test file - */ -function analyzeExistingTest(elementPath, elementName) { - const testFilePath = path.join(elementPath, 'test', `${elementName}.test.js`); - - if (!fs.existsSync(testFilePath)) { - return { - exists: false, - hasAccessibilityTests: false, - testedProperties: [], - testedSlots: [], - testedEvents: [], - testedMethods: [] - }; - } - - const content = fs.readFileSync(testFilePath, 'utf8'); - - return { - exists: true, - hasAccessibilityTests: content.includes('to.be.accessible()'), - hasPropertyTests: content.includes('Property type validation') || content.includes('property'), - hasAttributeTests: content.includes('Attribute') || content.includes('attribute'), - hasSlotTests: content.includes('slot'), - hasEventTests: content.includes('dispatchEvent') || content.includes('fire'), - hasMethodTests: content.includes('method'), - content: content - }; -} - -/** - * Generate test improvement recommendations - */ -function generateRecommendations(componentAnalysis, testAnalysis, elementName) { - const recommendations = []; - - if (!testAnalysis.exists) { - recommendations.push({ - priority: 'HIGH', - type: 'MISSING_TEST_FILE', - message: `No test file found. Create test/\${elementName}.test.js` - }); - return recommendations; - } - - if (!testAnalysis.hasAccessibilityTests) { - recommendations.push({ - priority: 'HIGH', - type: 'MISSING_A11Y_TESTS', - message: 'Add accessibility tests using await expect(element).shadowDom.to.be.accessible()' - }); - } - - if (componentAnalysis.properties.length > 0 && !testAnalysis.hasPropertyTests) { - recommendations.push({ - priority: 'HIGH', - type: 'MISSING_PROPERTY_TESTS', - message: `Add comprehensive property tests for: ${componentAnalysis.properties.map(p => p.name).join(', ')}` - }); - } - - if (componentAnalysis.slots.length > 0 && !testAnalysis.hasSlotTests) { - recommendations.push({ - priority: 'MEDIUM', - type: 'MISSING_SLOT_TESTS', - message: `Add slot tests for: ${componentAnalysis.slots.join(', ')}` - }); - } - - if (componentAnalysis.events.length > 0 && !testAnalysis.hasEventTests) { - recommendations.push({ - priority: 'MEDIUM', - type: 'MISSING_EVENT_TESTS', - message: `Add event tests for: ${componentAnalysis.events.join(', ')}` - }); - } - - // Check for attributes that should have tests - const attributeProps = componentAnalysis.properties.filter(p => p.attribute); - if (attributeProps.length > 0 && !testAnalysis.hasAttributeTests) { - recommendations.push({ - priority: 'HIGH', - type: 'MISSING_ATTRIBUTE_TESTS', - message: `Add attribute-to-property mapping tests for: ${attributeProps.map(p => p.attribute).join(', ')}` - }); - } - - return recommendations; -} - -/** - * Main audit function - */ -function auditElement(elementName) { - const elementPath = path.join(__dirname, 'elements', elementName); - - if (!fs.existsSync(elementPath)) { - return { - element: elementName, - error: `Element directory not found: ${elementPath}` - }; - } - - const componentAnalysis = analyzeComponent(elementPath, elementName); - const testAnalysis = analyzeExistingTest(elementPath, elementName); - const recommendations = generateRecommendations(componentAnalysis, testAnalysis, elementName); - - return { - element: elementName, - component: componentAnalysis, - tests: testAnalysis, - recommendations, - needsWork: recommendations.length > 0, - priority: recommendations.some(r => r.priority === 'HIGH') ? 'HIGH' : - recommendations.length > 0 ? 'MEDIUM' : 'LOW' - }; -} - -/** - * Audit all elements - */ -function auditAllElements() { - const elementsDir = path.join(__dirname, 'elements'); - const elements = fs.readdirSync(elementsDir).filter(item => { - const itemPath = path.join(elementsDir, item); - return fs.statSync(itemPath).isDirectory(); - }); - - const results = { - summary: { - total: elements.length, - needsWork: 0, - highPriority: 0, - mediumPriority: 0, - lowPriority: 0 - }, - elements: {} - }; - - elements.forEach(element => { - const audit = auditElement(element); - results.elements[element] = audit; - - if (audit.needsWork) { - results.summary.needsWork++; - if (audit.priority === 'HIGH') results.summary.highPriority++; - else if (audit.priority === 'MEDIUM') results.summary.mediumPriority++; - else results.summary.lowPriority++; - } - }); - - return results; -} - -/** - * Generate prioritized work list - */ -function generateWorkList(auditResults) { - const workList = []; - - // High priority items first - Object.keys(auditResults.elements) - .filter(element => auditResults.elements[element].priority === 'HIGH') - .sort() - .forEach(element => { - workList.push({ - element, - priority: 'HIGH', - recommendations: auditResults.elements[element].recommendations - }); - }); - - // Medium priority items - Object.keys(auditResults.elements) - .filter(element => auditResults.elements[element].priority === 'MEDIUM') - .sort() - .forEach(element => { - workList.push({ - element, - priority: 'MEDIUM', - recommendations: auditResults.elements[element].recommendations - }); - }); - - return workList; -} - -// Export functions for use in other scripts -module.exports = { - auditElement, - auditAllElements, - analyzeComponent, - analyzeExistingTest, - generateRecommendations, - generateWorkList -}; - -// CLI usage -if (require.main === module) { - const args = process.argv.slice(2); - - if (args.length === 0) { - console.log('Auditing all elements...'); - const results = auditAllElements(); - const workList = generateWorkList(results); - - console.log('\n='.repeat(80)); - console.log('WEBCOMPONENTS TEST AUDIT SUMMARY'); - console.log('='.repeat(80)); - console.log(`Total Elements: ${results.summary.total}`); - console.log(`Need Work: ${results.summary.needsWork}`); - console.log(`High Priority: ${results.summary.highPriority}`); - console.log(`Medium Priority: ${results.summary.mediumPriority}`); - console.log(`Low Priority: ${results.summary.lowPriority}`); - - console.log('\nWORK LIST (first 20):'); - console.log('-'.repeat(40)); - workList.slice(0, 20).forEach((item, index) => { - console.log(`${index + 1}. [${item.priority}] ${item.element}`); - item.recommendations.forEach(rec => { - console.log(` • ${rec.message}`); - }); - console.log(); - }); - - // Save detailed results - fs.writeFileSync('test-audit-results.json', JSON.stringify(results, null, 2)); - fs.writeFileSync('test-work-list.json', JSON.stringify(workList, null, 2)); - console.log('Detailed results saved to test-audit-results.json'); - console.log('Work list saved to test-work-list.json'); - - } else { - // Audit specific element - const elementName = args[0]; - const result = auditElement(elementName); - console.log(JSON.stringify(result, null, 2)); - } -} diff --git a/test-hidden-themes.js b/test-hidden-themes.js deleted file mode 100644 index 96f496ed33..0000000000 --- a/test-hidden-themes.js +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env node - -// Test to verify hidden themes are properly filtered -async function testHiddenThemes() { - console.log('🔍 Testing hidden themes filtering...'); - - try { - const themesUrl = 'http://localhost:8080/elements/haxcms-elements/lib/themes.json'; - - const response = await fetch(themesUrl); - if (!response.ok) { - throw new Error(`Failed to load themes: ${response.status}`); - } - - const themesData = await response.json(); - const allThemes = Object.values(themesData); - const hiddenThemes = allThemes.filter(theme => theme.hidden); - const visibleThemes = allThemes.filter(theme => !theme.hidden); - const terribleThemes = allThemes.filter(theme => theme.terrible); - - console.log(`📄 Total themes: ${allThemes.length}`); - console.log(`🫥 Hidden themes: ${hiddenThemes.length}`); - console.log(`👁️ Visible themes: ${visibleThemes.length}`); - console.log(`💀 Terrible themes: ${terribleThemes.length}`); - - console.log('\n🫥 Hidden themes list:'); - hiddenThemes.forEach(theme => { - console.log(` - ${theme.element}: ${theme.name}`); - }); - - console.log('\n💀 Terrible themes list:'); - terribleThemes.forEach(theme => { - console.log(` - ${theme.element}: ${theme.name}`); - }); - - // Verify expected hidden themes - const expectedHidden = ['haxcms-json-theme', 'haxcms-blank-theme', 'haxcms-print-theme']; - const actualHidden = hiddenThemes.map(theme => theme.element); - - const correctHidden = expectedHidden.every(expected => - actualHidden.includes(expected) - ); - - console.log(`\n${correctHidden ? '✅' : '❌'} Expected hidden themes correctly marked: ${correctHidden}`); - - // Verify terrible themes have the flag - const terribleCheck = terribleThemes.every(theme => - theme.element.includes('terrible') - ); - - console.log(`${terribleCheck ? '✅' : '❌'} Terrible themes correctly flagged: ${terribleCheck}`); - - console.log('🎉 Hidden themes test completed!'); - return correctHidden && terribleCheck; - - } catch (error) { - console.error('❌ Hidden themes test failed:', error.message); - return false; - } -} - -// Run the test -testHiddenThemes().then(success => { - process.exit(success ? 0 : 1); -}); \ No newline at end of file diff --git a/test-print-route.md b/test-print-route.md deleted file mode 100644 index a6459b6474..0000000000 --- a/test-print-route.md +++ /dev/null @@ -1,33 +0,0 @@ -# Print Route Implementation - -## Summary of Changes - -I've successfully implemented a print route for HAXcms that eliminates the need for the `format=print-page` URL parameter by using an internal route system. - -### Key Components: - -1. **site-print-route.js** - Route component that handles print mode -2. **Updated haxcms-site-store.js** - Added print route with theme-switching callback -3. **Theme switching** - Automatically switches to `haxcms-print-theme` when accessing the route - -### How it works: - -1. User navigates to `x/print?page=some-page-slug` -2. The store's callback automatically switches the theme to `haxcms-print-theme` -3. The route component loads the specified page content -4. The page displays in print mode using the print theme - -### Usage Examples: - -- `x/print?page=introduction` - Shows "introduction" page in print mode -- `x/print` - Shows home/first page in print mode (fallback) - -### Benefits: - -- Eliminates the need for `format=print-page` URL parameters -- Cleaner URL structure -- Leverages existing HAXcms internal route system -- Automatic theme switching -- Proper error handling and fallbacks - -The implementation is complete and ready for testing! \ No newline at end of file diff --git a/test-work-list.json b/test-work-list.json deleted file mode 100644 index 95b5d6b114..0000000000 --- a/test-work-list.json +++ /dev/null @@ -1,2584 +0,0 @@ -[ - { - "element": ".idea", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_TEST_FILE", - "message": "No test file found. Create test/${elementName}.test.js" - } - ] - }, - { - "element": ".vscode", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_TEST_FILE", - "message": "No test file found. Create test/${elementName}.test.js" - } - ] - }, - { - "element": "a11y-behaviors", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_A11Y_TESTS", - "message": "Add accessibility tests using await expect(element).shadowDom.to.be.accessible()" - } - ] - }, - { - "element": "a11y-compare-image", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: activeLayer, opacity, label, position, __lower, __upper, __markers" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: active-layer" - } - ] - }, - { - "element": "a11y-details", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: closeText, openText" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: summary, details, default" - } - ] - }, - { - "element": "a11y-figure", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: imgSrc, imgAlt, __hasDetail" - } - ] - }, - { - "element": "a11y-gif-player", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: alt, disabled, describedBy, longdesc, src, srcWithoutAnimation, __playing, __gifLoaded" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ] - }, - { - "element": "a11y-media-player", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: __playerReady, allowConcurrent, audioOnly, autoplay, captionsTrack, cc, currentTime, crossorigin, disablePrintButton, disableSearch, disableScroll, disableSeek, darkTranscript, disableFullscreen, disableInteractive, height, hideElapsedTime, hideTimestamps, hideTranscript, id, lang, learningMode, linkable, localization, loop, mediaLang, mediaTitle, muted, hideYoutubeLink, playbackRate, preload, responsiveSize, search, standAlone, source, sources, stackedLayout, sticky, stickyCorner, thumbnailSrc, tracks, transcriptTrack, volume, width, youtubeId, __currentTime, __captionsOption, __cues, __loadedTracks, __playing, __preloadedDuration, __settingsOpen, __transcriptOption" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: mute-changed, transcript-downloaded, transcript-printed, play, a11y-player-playing, pause, stop, restart, backward, forward, seek, playback-rate-changed, volume-changed, cc-toggle, fullscreen-toggle, loop-toggle, play-toggle, muted-toggle, settings-toggled, player-sticky, transcript-toggle, responsive-element, a11y-player" - } - ] - }, - { - "element": "a11y-menu-button", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: currentItem, disabled, expanded, focused, hovered, keepOpenOnClick, menuItems, noOpenOnHover, offset, position, positionAlign" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: close, open, item-click" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: disabled, expanded, focused, hovered, keep-open-on-click, no-open-on-hover, offset, position, position-align" - } - ] - }, - { - "element": "a11y-tabs", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: ariaLabel, activeTab, fullWidth, disabled, hidden, iconBreakpoint, id, layoutBreakpoint, responsiveSize, sticky, __tabs, __tabButtons, __tabFocus" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: a11y-tabs-active-changed" - } - ] - }, - { - "element": "a11y-utils", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_A11Y_TESTS", - "message": "Add accessibility tests using await expect(element).shadowDom.to.be.accessible()" - } - ] - }, - { - "element": "absolute-position-behavior", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: allowOverlap, auto, fitToVisibleBounds, hidden, for, offset, sticky, position, positionAlign, justify, target, __positions" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ] - }, - { - "element": "accent-card", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: accentBackground, accentHeading, flat, horizontal, imageAlign, imageSrc, imageValign, noBorder, ready, link, iconSize, imageWidth" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: image-corner, heading, corner, subheading, content, footer" - } - ] - }, - { - "element": "aframe-player", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: source, height, width, skyColor, ar, x, y, z, position" - } - ] - }, - { - "element": "app-hax", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: unlockComingSoon, unlockTerrible, courses, userName, activeItem, soundIcon, searchTerm, appMode, isNewUser, phrases, userMenuOpen, siteReady, basePath, token" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: jwt-login-logout, simple-modal-show, app-hax-loaded" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: base-path" - } - ] - }, - { - "element": "audio-player", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_A11Y_TESTS", - "message": "Add accessibility tests using await expect(element).shadowDom.to.be.accessible()" - } - ] - }, - { - "element": "awesome-explosion", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: state, stopped, playing, paused, image, sound, size, color, resetSound" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: awesome-event" - } - ] - }, - { - "element": "b-r", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: amount" - } - ] - }, - { - "element": "barcode-reader", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_A11Y_TESTS", - "message": "Add accessibility tests using await expect(element).shadowDom.to.be.accessible()" - }, - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: value, scale, hideinput" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: value-changed" - } - ] - }, - { - "element": "baseline-build-hax", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_A11Y_TESTS", - "message": "Add accessibility tests using await expect(element).shadowDom.to.be.accessible()" - } - ] - }, - { - "element": "beaker-broker", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: archive, datUrl" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: archive-changed, dat-url-changed" - } - ] - }, - { - "element": "bootstrap-theme", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_A11Y_TESTS", - "message": "Add accessibility tests using await expect(element).shadowDom.to.be.accessible()" - }, - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: searchTerm, menuOpen, colorTheme" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: menu-open, color-theme" - } - ] - }, - { - "element": "chartist-render", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: chartTitle, chartData, chartDesc, data, dataSource, id, options, axisX, axisY" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: chartist-render-ready, chart-data-changed, data-source-changed, data-changed, chartist-render-data, chartist-render-created, chartist-render-draw" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: chart-title, chart-data, chart-desc, data, data-source" - } - ] - }, - { - "element": "chat-agent", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: isFullView, isInterfaceHidden" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: is-full-view, is-interface-hidden" - } - ] - }, - { - "element": "check-it-out", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: checkedOut, source, icon, __computedSource, type, label, filePath, modalTitle, hideExplorer, ctl, view, modal" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: checked-out, file-path, modal-title, hide-explorer" - } - ] - }, - { - "element": "citation-element", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: title, scope, displayMethod, creator, source, date, licenseName, licenseLink, license" - } - ] - }, - { - "element": "clean-one", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: searchTerm" - } - ] - }, - { - "element": "clean-portfolio-theme", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: activeItem, activeParent, ancestorItem, prevSibling, nextSibling, topItems, items, activeTags, categoryTags, allTags, menuOverflow, menuOpen, copyrightYear, pageCurrent, pageTotal, siteTitle, homeLink, activeLayout, selectedTag, lastUpdated, licenseName, licenseLink, licenseImage, dataPrimary" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: data-primary" - } - ] - }, - { - "element": "clean-two", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: searchTerm, prevPage, nextPage, pageTimestamp" - } - ] - }, - { - "element": "cms-hax", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: ready, openDefault, hidePanelOps, offsetMargin, elementAlign, allowedTags, endPoint, method, appStoreConnection, __appStore, syncBody, bodyValue, hideMessage, redirectLocation, redirectOnSave, __imported" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: hax-body-content-changed, cms-hax-saved" - } - ] - }, - { - "element": "code-editor", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: libPath, title, showCodePen, readOnly, codePenData, editorValue, value, theme, mode, language, fontSize, wordWrap, autofocus, hideLineNumbers, focused, tabSize, ready" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: show-code-pen-changed, value-changed, focused-changed" - } - ] - }, - { - "element": "code-sample", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: editMode, _haxstate, copyClipboardButton, theme, type, highlightStart, highlightEnd" - } - ] - }, - { - "element": "collection-list", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: responsiveSize" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: responsive-size" - } - ] - }, - { - "element": "count-up", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: start, end, duration, noeasing, decimalplaces, separator, decimal, prefixtext, suffixtext, thresholds, rootMargin, ratio, elementVisible" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: prefix, suffix" - } - ] - }, - { - "element": "course-model", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: visible, title, src, alt" - } - ] - }, - { - "element": "csv-render", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: dataSource, loading, caption, summary, table, tableHeadings, tableData" - } - ] - }, - { - "element": "d-d-d", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: dataPulse" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: data-pulse" - } - ] - }, - { - "element": "d-d-docs", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: option, options" - } - ] - }, - { - "element": "date-card", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: month, date, day, title, startTime, endTime, location, borderSpacing" - } - ] - }, - { - "element": "deduping-fix", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_TEST_FILE", - "message": "No test file found. Create test/${elementName}.test.js" - } - ] - }, - { - "element": "discord-embed", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: height, width, source" - } - ] - }, - { - "element": "disqus-embed", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: loadingText, pageURL, pageIdentifier, pageTitle, shortName, lang" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: loading-text, page-url, page-identifier, page-title, short-name" - } - ] - }, - { - "element": "documentation-player", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: label, haxSchema, imageUrl, url" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: hax-insert" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: image-url, url" - } - ] - }, - { - "element": "editable-table", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: editMode" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: toggle-edit-mode" - } - ] - }, - { - "element": "elmsln-loading", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: dark, color, contrast, size" - } - ] - }, - { - "element": "enhanced-text", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: wikipedia, vide, fixationPoint, haxcmsGlossary, haxcmsSiteLocation, haxcmsSite, haxcmsMarkAll, loading, auto" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: fixation-point, haxcms-glossary, haxcms-site-location, haxcms-site, haxcms-mark-all" - } - ] - }, - { - "element": "es-global-bridge", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_TEST_FILE", - "message": "No test file found. Create test/${elementName}.test.js" - } - ] - }, - { - "element": "event-badge", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: title, image, name, position, logo, organization, tvcolor, knobcolor, sepia, blackwhite" - } - ] - }, - { - "element": "example-hax-element", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: title" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ] - }, - { - "element": "example-haxcms-theme", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: activeId, _items" - } - ] - }, - { - "element": "figure-label", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: title, description" - } - ] - }, - { - "element": "fill-in-the-blanks", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_TEST_FILE", - "message": "No test file found. Create test/${elementName}.test.js" - } - ] - }, - { - "element": "flash-card", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: inverted, imgSource, imgKeyword, status" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: img-source, img-keyword" - } - ] - }, - { - "element": "full-width-image", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: source, caption" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ] - }, - { - "element": "fullscreen-behaviors", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: fullscreen, fullscreenEnabled" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ] - }, - { - "element": "git-corner", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: source, alt, corner, size" - } - ] - }, - { - "element": "github-preview", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: repo, org, __description, repoLang, __stars, __forks, __assetAvailable, extended, readmeExtended, headers, viewMoreText, notFoundText, __readmeText, branch, url, apiUrl, rawUrl, readMe" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: hax-register-app" - } - ] - }, - { - "element": "glossy-portfolio-theme", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: title, siteDescription, relatedItem, isHome, items" - } - ] - }, - { - "element": "grade-book", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: displayMode, settings, disabled, loading, ready, activeStudent, activeAssignment, totalScore, scoreLock, source, sourceData, activeSubmission, database, activeRubric, assessmentView, activeGrading, activeStudentSubmissions" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: app-name" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: simple-tag-drop, simple-tag-dragstart" - } - ] - }, - { - "element": "grid-plate", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: itemPadding, itemMargin, breakpointSm, breakpointMd, breakpointLg, breakpointXl, columns, dataHaxRay, disableResponsive, layout" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: col-${num}" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: responsive-element, disable-responsive-changed, resize" - } - ] - }, - { - "element": "h5p-element", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: source" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ] - }, - { - "element": "hal-9000", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: toast, commands, respondsTo, debug, auto, enabled, pitch, rate, language" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: super-daemon-toast-hide, super-daemon-toast-show" - } - ] - }, - { - "element": "hax-body", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: _useristyping, haxMover, editMode, elementAlign, trayDetail, trayStatus, activeNode, canMoveElement, viewSourceToggle" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: hax-register-body, place-holder-file-drop, hax-drop-focus-event" - } - ] - }, - { - "element": "haxor-slevin", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: color, selectedPage, activeManifestIndexCounter, activeItem, stateClass, __mainPosts, __followUpPosts" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: resize" - } - ] - }, - { - "element": "hex-picker", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: value, disabled, largeDisplay" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: value-changed" - } - ] - }, - { - "element": "hexagon-loader", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: color, size, loading, items, itemCount" - } - ] - }, - { - "element": "iframe-loader", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: loading, height, width, isPDF, disabled, source" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ] - }, - { - "element": "image-compare-slider", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: bottomAlt, bottomDescriptionId, bottomSrc, opacity, position, title, topAlt, topDescriptionId, topSrc" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: bottom-alt, bottom-description-id, bottom-src, top-alt, top-description-id, top-src" - } - ] - }, - { - "element": "image-inspector", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: noLeft, degrees, src, hoverClass" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: toolbar, default" - } - ] - }, - { - "element": "img-pan-zoom", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: src, sources, page, describedBy, dzi, fadeIn, fullscreenToggled, flipToggled, loading, hideSpinner, loaded, showNavigationControl, showNavigator, zoomPerClick, zoomPerScroll, animationTime, navPrevNextWrap, showRotationControl, minZoomImageRatio, maxZoomPixelRatio, constrainDuringPan, visibilityRatio, navigatorAutoFade, navigatorPosition, navigatorTop, navigatorBottom, navigatorLeft, navigatorRight, navigatorHeight, navigatorWidth, navigatorToggled, sequenceMode, preserveViewport, showReferenceStrip, referenceStripScroll, previousButton, nextButton, homeButton, zoomInButton, zoomOutButton, fullScreenButton" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: loading-changed, loaded-changed, zoom, page, pan, update-viewport, viewport-changed" - } - ] - }, - { - "element": "img-view-modal", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: title, modal" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: modal-button-click" - } - ] - }, - { - "element": "inline-audio", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: source, icon, aria, title, playing, shiny" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: playing-changed" - } - ] - }, - { - "element": "intersection-element", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_TEST_FILE", - "message": "No test file found. Create test/${elementName}.test.js" - } - ] - }, - { - "element": "journey-theme", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: _items, activeItem, ancestorItem, location, basePath, dataPrimary, siteTheme, licenseName, licenseLink, licenseImage, lastUpdated, copyrightYear, pageCurrent, pageTotal" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: data-primary, site-theme" - } - ] - }, - { - "element": "jwt-login", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: auto, refreshUrl, redirectUrl, logoutUrl, url, method, body, key, jwt" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: jwt-login-refresh-error, jwt-changed, jwt-logged-in, jwt-token, jwt-login-login-failed" - } - ] - }, - { - "element": "la-tex", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: hydrated, initialText" - } - ] - }, - { - "element": "lazy-image-helpers", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: imageLoaded" - } - ] - }, - { - "element": "learn-two-theme", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: opened" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ] - }, - { - "element": "license-element", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: title, creator, source, licenseName, licenseImage, licenseLink, license, moreLabel, moreLink, hasMore" - } - ] - }, - { - "element": "lorem-data", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: schemas" - } - ] - }, - { - "element": "lrn-gitgraph", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: commits, template, orientation, mode, reverseArrow, config" - } - ] - }, - { - "element": "lrn-table", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: title, csvFile, description" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ] - }, - { - "element": "lrn-vocab", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: term" - } - ] - }, - { - "element": "lrndesign-chart", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: accentColor, dark, height, reverseData, width" - } - ] - }, - { - "element": "lrndesign-imagemap", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: label, src, hotspotDetails, subtopicOf, parent, __activeHotspot" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: heading" - } - ] - }, - { - "element": "lrndesign-timeline", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: events, timelineSize, title" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: responsive-element" - } - ] - }, - { - "element": "lunr-search", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: dataSource, __auto, data, method, search, results, noStopWords, fields, indexNoStopWords, index, __lunrLoaded, limit, minScore, log, demo" - } - ] - }, - { - "element": "map-menu", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: disabled, editControls, isFlex, isHorizontal, maxDepth, title, data, manifest, items, selected, activeItem, autoScroll, activeIndicator" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: selected, map-menu-item-hidden-check" - } - ] - }, - { - "element": "mark-the-words", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: wordList, statement, missedAnswers, numberCorrect, numberGuessed" - } - ] - }, - { - "element": "matching-question", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_TEST_FILE", - "message": "No test file found. Create test/${elementName}.test.js" - } - ] - }, - { - "element": "md-block", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: source, markdown" - } - ] - }, - { - "element": "media-image", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: link, asMd, __figureLabel, modalTitle, disableZoom, _hasCaption, source, citation, caption, alt, size, round, card, box, offset, figureLabelTitle, figureLabelDescription" - } - ] - }, - { - "element": "media-quote", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_TEST_FILE", - "message": "No test file found. Create test/${elementName}.test.js" - } - ] - }, - { - "element": "meme-maker", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: alt, crossorigin, describedBy, imageUrl, topText, bottomText" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: i18n-manager-register-element" - } - ] - }, - { - "element": "merit-badge", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: badgeDate, badgeImage, badgeTitle, badgeDetails, hyperLink, badgeSkills, skillsOpened, detailsOpened, badgeUnlocked, badgeColor" - } - ] - }, - { - "element": "moment-element", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: datetime, inputFormat, outputFormat, from, to, output, libraryLoaded" - } - ] - }, - { - "element": "music-player", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: source, visualizer, noWaterfall, noVisual" - } - ] - }, - { - "element": "oer-schema", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: text, oerProperty, typeof, relatedResource" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ] - }, - { - "element": "outline-designer", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: haxGizmos, hideDelete, activeItemForActions, storeTools, eventData, items, appReady, activePreview, activePreviewIndex, hideContentOps, fidelity, liveRegionText" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: simple-modal-hide" - } - ] - }, - { - "element": "outline-player", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: opened, closed, activeId, narrow" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: title, default" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: closed-changed, resize" - } - ] - }, - { - "element": "page-break", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: iconType, noderefs, relatedItems, icon, accentColor, entityType, description, order, hideInMenu, tags, developerTheme, title, slug, image, parent, published, locked, depth, itemId, breakType, status, pageType, _haxState" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: page-break-registration, page-break-change, hax-refresh-tray-form" - } - ] - }, - { - "element": "page-contents-menu", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: contentContainer, relationship, items, position, mobile, label, hideSettings, hideIfEmpty, isEmpty" - } - ] - }, - { - "element": "page-flag", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: label, opened, show" - } - ] - }, - { - "element": "page-section", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: anchor, scrollerLabel, filter, fold, full, scroller, bg, image, preset" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default, entice, buttons" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: scroller-label" - } - ] - }, - { - "element": "paper-input-flagged", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: label, disabled, icon, maxlength, minlength, status, value, flaggedInput, inputSuccess, __activeMessage" - } - ] - }, - { - "element": "paper-stepper", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: selected, progressBar, backLabel, nextLabel, disablePrevious, disableNext, noButtons" - } - ] - }, - { - "element": "parallax-image", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: imageBg, describedBy" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: parallax_heading" - } - ] - }, - { - "element": "pdf-browser-viewer", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: file, notSupportedMessage, notSupportedLinkMessage, height, width, card, downloadLabel, elevation" - } - ] - }, - { - "element": "person-testimonial", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: describedBy, image, name, position" - } - ] - }, - { - "element": "place-holder", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: iconFromType, text, directions, calcText, type, dragOver" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: place-holder-replace, place-holder-file-drop" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: drag-over" - } - ] - }, - { - "element": "play-list", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: items, loop, edit, navigation, pagination, aspectRatio, orientation, slide" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: aspect-ratio" - } - ] - }, - { - "element": "polaris-theme", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: searchTerm, siteDescription, imageLink, image, imageAlt, pageTimestamp" - } - ] - }, - { - "element": "post-card", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: t, to, from, message, photoSrc, stampSrc, postMarkLocations" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: i18n-manager-register-element" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: photo-src, stamp-src, post-mark-locations" - } - ] - }, - { - "element": "product-card", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: disabled, heading, subheading, icon, hasDemo" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: product-card-demo-show" - } - ] - }, - { - "element": "product-glance", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: title, subtitle, icon" - } - ] - }, - { - "element": "product-offering", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: alt, source, icon, title, _titleOne, _titleTwo, description" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: description" - } - ] - }, - { - "element": "progress-donut", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: animation, animationDelay, complete, desc, imageSrc, imageAlt" - } - ] - }, - { - "element": "q-r", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: data, title, modulesize, margin, format" - } - ] - }, - { - "element": "radio-behaviors", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: itemData, selection" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: selection-changed" - } - ] - }, - { - "element": "relative-heading", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: closeIcon, closeLabel, copyMessage, disableLink, linkAlignRight, linkIcon, linkLabel" - } - ] - }, - { - "element": "retro-card", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: title, subtitle, tags, mediaSource, url, hoverSource, hoverState, __cardTags, nosource, __source" - } - ] - }, - { - "element": "rich-text-editor", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: id, contenteditable, disabled, disableHover, placeholder, toolbarId, range, rawhtml, type, viewSource, __codeEditorValue, __needsUpdate, __focused, __hovered" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: focus, contenteditable-change" - } - ] - }, - { - "element": "rpg-character", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: literalseed, accessories, height, width, base, face, faceItem, hair, pants, shirt, skin, hatColor, hat, walking, leg, seed, speed, circle, fire, demo, reduceMotion" - } - ] - }, - { - "element": "runkit-embed", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_TEST_FILE", - "message": "No test file found. Create test/${elementName}.test.js" - } - ] - }, - { - "element": "schema-behaviors", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: schemaMap" - } - ] - }, - { - "element": "scroll-button", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: target, icon, label, _label, position, t" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: i18n-manager-register-element" - } - ] - }, - { - "element": "self-check", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: title, question, image, alt, describedBy, link, correct" - } - ] - }, - { - "element": "simple-autocomplete", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: opened, hideInput, selectionPosition, value, itemLimit" - } - ] - }, - { - "element": "simple-blog", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: selectedPage" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: resize" - } - ] - }, - { - "element": "simple-colors", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: accentColor, dark" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ] - }, - { - "element": "simple-colors-shared-styles", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: colors, contrasts" - } - ] - }, - { - "element": "simple-cta", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: link, label, icon, editMode, hideIcon, large, light, hotline, saturate, disabled" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ] - }, - { - "element": "simple-datetime", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: timestamp, format, date, unix" - } - ] - }, - { - "element": "simple-fields", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: disableResponsive, fields, schematizer, label, __activeTabs, codeTheme" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: active-tabs-changed" - } - ] - }, - { - "element": "simple-filter", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: items, like, where, caseSensitive, multiMatch, filtered" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: filter, filtered-changed" - } - ] - }, - { - "element": "simple-icon", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: contrast" - } - ] - }, - { - "element": "simple-icon-picker", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: allowNull, icons, includeSets, excludeSets, exclude, value, optionsPerRow, __iconList" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: value-changed" - } - ] - }, - { - "element": "simple-login", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: username, password, loading, userInputLabel, userInputErrMsg, passwordInputLabel, passwordInputErrMsg, loginBtnText" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: simple-login-login" - } - ] - }, - { - "element": "simple-modal", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: title, opened, closeLabel, closeIcon, invokedBy, modal, mode" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: simple-toast-hide" - } - ] - }, - { - "element": "simple-picker", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: allowNull, alignRight, ariaLabelledby, blockLabel, disabled, expanded, hideOptionLabels, hideNullOption, hideSample, justify, label, options, titleAsHtml, value, __activeDesc, __options, __selectedOption, __ready" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: changed, click, mousedown, keydown, option-focus, value-changed, change, expand, collapse" - } - ] - }, - { - "element": "simple-range-input", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: dragging, immediateValue, value, min, step, max, label, disabled" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: immediate-value-changed, value-changed" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: immediate-value" - } - ] - }, - { - "element": "simple-search", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: alwaysFloatLabel, caseSensitive, controls, inline, nextButtonIcon, nextButtonLabel, noLabelFloat, prevButtonIcon, prevButtonLabel, resultCount, resultPointer, selector, searchInputIcon, searchInputLabel, searchTerms, target, __hideNext, __hidePrev" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: simple-search, goto-result" - } - ] - }, - { - "element": "simple-toast", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: opened, text, classStyle, closeText, duration, eventCallback, closeButton" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ] - }, - { - "element": "simple-toolbar", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: alwaysExpanded, ariaControls, ariaLabel, collapsed, config, id, moreShortcuts, shortcutKeys, sticky, __buttons, collapseDisabled, __focused, __hovered" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: shortcut-key-pressed" - } - ] - }, - { - "element": "simple-tooltip", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: for, manualMode, position, fitToVisibleBounds, offset, marginTop, animationDelay, animationEntry, animationExit, _showing" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ] - }, - { - "element": "social-share-link", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: buttonStyle, image, message, mode, text, type, url, __href, __icon, __linkText, __showIcon" - } - ] - }, - { - "element": "sorting-question", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: numberCorrect" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: simple-toast-hide, user-engagement" - } - ] - }, - { - "element": "spotify-embed", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: source, theme, size, playlistid, type, editing" - } - ] - }, - { - "element": "star-rating", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: score, possible, interactive, numStars, _calPercent" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: star-rating-click" - } - ] - }, - { - "element": "stop-note", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: title, url, icon, status" - } - ] - }, - { - "element": "super-daemon", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: santaMode, opened, loading, key1, key2, icon, items, programResults, programName, allItems, context, commandContext, program, programSearch, like, value, mini, wand, activeNode, programTarget, voiceSearch, voiceCommands, listeningForInput" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: super-daemon-close, super-daemon-toast-hide, super-daemon-command-context-changed, super-daemon-context-changed" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: santa-mode, voice-search, listening-for-input" - } - ] - }, - { - "element": "tagging-question", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_TEST_FILE", - "message": "No test file found. Create test/${elementName}.test.js" - } - ] - }, - { - "element": "training-theme", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: items, activeId, time, prevPage, nextPage, maxIndex" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ] - }, - { - "element": "twitter-embed", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: tweet, _haxstate, lang, dataWidth, dataTheme, tweetId, noPopups, allowPopups" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: i18n-manager-register-element" - } - ] - }, - { - "element": "type-writer", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: delay, cursorDuration, text, speed, elementVisible, eraseSpeed, typing, _length, _oldText" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: type-writer-end" - } - ] - }, - { - "element": "un-sdg", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: loading, fetchpriority, goal, colorOnly, alt" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: color-only" - } - ] - }, - { - "element": "undo-manager", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: canUndo, canRedo, undoStackObserverProps, target, stack" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: stack-changed, can-undo-changed, can-redo-changed" - } - ] - }, - { - "element": "utils", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_TEST_FILE", - "message": "No test file found. Create test/${elementName}.test.js" - } - ] - }, - { - "element": "video-player", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: sourceType, accentColor, crossorigin, dark, darkTranscript, disableInteractive, height, hideTimestamps, hideTranscript, id, learningMode, lang, linkable, mediaTitle, hideYoutubeLink, source, sources, sourceData, stickyCorner, track, tracks, thumbnailSrc, width, playing, allowBackgroundPlay, startTime, endTime" - } - ] - }, - { - "element": "vocab-term", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: popoverMode, detailsOpen" - } - ] - }, - { - "element": "voice-recorder", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: recording, label" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: voice-recorder-recording-blob" - } - ] - }, - { - "element": "web-container", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: fname, status, files, filesShown, hideTerminal, hideEditor, hideWindow" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: web-container-dependencies-installing, web-container-dependencies-installed, web-container-npm-start, web-container-server-ready, web-container-command-start, web-container-command-finished" - }, - { - "priority": "HIGH", - "type": "MISSING_ATTRIBUTE_TESTS", - "message": "Add attribute-to-property mapping tests for: hide-terminal, hide-editor, hide-window" - } - ] - }, - { - "element": "wikipedia-query", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: title, __now, _title, headers, hideTitle, search, language" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: i18n-manager-register-element, hax-register-app" - } - ] - }, - { - "element": "word-count", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: words, wordsPrefix" - }, - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ] - }, - { - "element": "wysiwyg-hax", - "priority": "HIGH", - "recommendations": [ - { - "priority": "HIGH", - "type": "MISSING_PROPERTY_TESTS", - "message": "Add comprehensive property tests for: openDefault, redirectLocation, hidePanelOps, elementAlign, offsetMargin, bodyValue, allowedTags, appStoreConnection, saveButtonSelector, fieldClass, fieldId, fieldName, syncBody, endPoint, updatePageData" - }, - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: hax-save, simple-modal-hide" - } - ] - }, - { - "element": "a11y-carousel", - "priority": "MEDIUM", - "recommendations": [ - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: above, img, default" - } - ] - }, - { - "element": "course-design", - "priority": "MEDIUM", - "recommendations": [ - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ] - }, - { - "element": "dynamic-import-registry", - "priority": "MEDIUM", - "recommendations": [ - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: dynamic-import-registry-loaded, dynamic-import-registry-failure" - } - ] - }, - { - "element": "future-terminal-text", - "priority": "MEDIUM", - "recommendations": [ - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ] - }, - { - "element": "h-a-x", - "priority": "MEDIUM", - "recommendations": [ - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: hax-save-body-value" - } - ] - }, - { - "element": "lesson-overview", - "priority": "MEDIUM", - "recommendations": [ - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: prefix, default" - } - ] - }, - { - "element": "pouch-db", - "priority": "MEDIUM", - "recommendations": [ - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: pouch-db-show-data" - } - ] - }, - { - "element": "responsive-utility", - "priority": "MEDIUM", - "recommendations": [ - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ] - }, - { - "element": "simple-emoji", - "priority": "MEDIUM", - "recommendations": [ - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ] - }, - { - "element": "simple-popover", - "priority": "MEDIUM", - "recommendations": [ - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ] - }, - { - "element": "terrible-themes", - "priority": "MEDIUM", - "recommendations": [ - { - "priority": "MEDIUM", - "type": "MISSING_SLOT_TESTS", - "message": "Add slot tests for: default" - } - ] - }, - { - "element": "user-action", - "priority": "MEDIUM", - "recommendations": [ - { - "priority": "MEDIUM", - "type": "MISSING_EVENT_TESTS", - "message": "Add event tests for: i18n-manager-register-element" - } - ] - } -] \ No newline at end of file From 6a1ff12c2f0a3a7beb0b44f42414ac56e7996c8d Mon Sep 17 00:00:00 2001 From: btopro Date: Thu, 16 Oct 2025 14:23:20 -0400 Subject: [PATCH 129/166] https://github.com/haxtheweb/issues/issues/2473 https://github.com/haxtheweb/issues/issues/2472 https://github.com/haxtheweb/issues/issues/2471 https://github.com/haxtheweb/issues/issues/2470 https://github.com/haxtheweb/issues/issues/301 https://github.com/haxtheweb/issues/issues/1089 --- elements/utils/package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/elements/utils/package.json b/elements/utils/package.json index 663a121488..232af0f92c 100755 --- a/elements/utils/package.json +++ b/elements/utils/package.json @@ -29,8 +29,7 @@ "test": "web-test-runner \"test/**/*.test.js\" --node-resolve --config=../../web-test-runner.config.mjs --playwright --browsers chromium" }, "dependencies": { - "lit": "3.3.1", - "@haxtheweb/github-preview": "^11.0.0" + "lit": "3.3.1" }, "devDependencies": { "@babel/preset-env": "^7.16.4", From dac7045a58920c7421b69214656e686f8ecdb126 Mon Sep 17 00:00:00 2001 From: btopro Date: Thu, 16 Oct 2025 14:34:46 -0400 Subject: [PATCH 130/166] removed old element unused --- elements/secure-request/.dddignore | 39 ---- elements/secure-request/.editorconfig | 17 -- elements/secure-request/.gitignore | 26 --- elements/secure-request/.npmignore | 1 - elements/secure-request/.surgeignore | 1 - elements/secure-request/.travis.yml | 18 -- elements/secure-request/LICENSE.md | 201 ------------------ elements/secure-request/README.md | 35 --- elements/secure-request/demo/index.html | 27 --- elements/secure-request/gulpfile.cjs | 25 --- elements/secure-request/index.html | 13 -- elements/secure-request/package.json | 67 ------ elements/secure-request/polymer.json | 31 --- elements/secure-request/secure-request.js | 109 ---------- .../test/secure-request.test.js | 71 ------- 15 files changed, 681 deletions(-) delete mode 100644 elements/secure-request/.dddignore delete mode 100644 elements/secure-request/.editorconfig delete mode 100644 elements/secure-request/.gitignore delete mode 100644 elements/secure-request/.npmignore delete mode 100644 elements/secure-request/.surgeignore delete mode 100644 elements/secure-request/.travis.yml delete mode 100644 elements/secure-request/LICENSE.md delete mode 100644 elements/secure-request/README.md delete mode 100644 elements/secure-request/demo/index.html delete mode 100755 elements/secure-request/gulpfile.cjs delete mode 100755 elements/secure-request/index.html delete mode 100755 elements/secure-request/package.json delete mode 100755 elements/secure-request/polymer.json delete mode 100644 elements/secure-request/secure-request.js delete mode 100644 elements/secure-request/test/secure-request.test.js diff --git a/elements/secure-request/.dddignore b/elements/secure-request/.dddignore deleted file mode 100644 index dddc016cd5..0000000000 --- a/elements/secure-request/.dddignore +++ /dev/null @@ -1,39 +0,0 @@ -# Directories -# (Must start with with / or \, as seen below) -/.github # Inline comments are supported -/.vscode -/.idea -/locales -\test -/dist -/build -/public # ignored by program regardless of presence in .dddignore -/node_modules # ignored by program regardless of presence in .dddignore - -# Files -# (Must include filename and extension, as seen below) -LICENSE -.dddignore -.editorconfig -.gitignore -.gitkeep -.nojekyll -.npmignore -.surgeignore -rollup.config.js - -# File extension -# (Must start with *, as seen below) -*.html -*.md -*.yml -*.json -*.toml -*.mjs -*.cjs -*.png -*.ico -*.svg -*.jpg -*.jpeg -*.stories.js diff --git a/elements/secure-request/.editorconfig b/elements/secure-request/.editorconfig deleted file mode 100644 index 7968a8836c..0000000000 --- a/elements/secure-request/.editorconfig +++ /dev/null @@ -1,17 +0,0 @@ -# EditorConfig: http://EditorConfig.org - -# Top-most EditorConfig file -root = true - -# Rules for JavaScript files: - -[*.{js,py,json,sh,html}] -# 4 space indentation -indent_style = space -indent_size = 2 -# No trailing spaces -trim_trailing_whitespace = true -# Unix-style newlines -end_of_line = lf -# Newline ending every file -insert_final_newline = true diff --git a/elements/secure-request/.gitignore b/elements/secure-request/.gitignore deleted file mode 100644 index 5456ae68cd..0000000000 --- a/elements/secure-request/.gitignore +++ /dev/null @@ -1,26 +0,0 @@ -## editors -/.idea -/.vscode - -## system files -.DS_Store - -## npm -/node_modules/ -/npm-debug.log - -## testing -/coverage/ - -## temp folders -/.tmp/ - -# build -/_site/ -/dist/ -/out-tsc/ -/public/ - -storybook-static -custom-elements.json -.vercel \ No newline at end of file diff --git a/elements/secure-request/.npmignore b/elements/secure-request/.npmignore deleted file mode 100644 index 3c3629e647..0000000000 --- a/elements/secure-request/.npmignore +++ /dev/null @@ -1 +0,0 @@ -node_modules diff --git a/elements/secure-request/.surgeignore b/elements/secure-request/.surgeignore deleted file mode 100644 index ddf342489b..0000000000 --- a/elements/secure-request/.surgeignore +++ /dev/null @@ -1 +0,0 @@ -!node_modules/ diff --git a/elements/secure-request/.travis.yml b/elements/secure-request/.travis.yml deleted file mode 100644 index 0781f91604..0000000000 --- a/elements/secure-request/.travis.yml +++ /dev/null @@ -1,18 +0,0 @@ -language: node_js -dist: trusty -sudo: required -addons: - firefox: "latest" - apt: - sources: - - google-chrome - packages: - - google-chrome-stable -node_js: stable -before_install: - - npm install -g web-component-tester -install: - - npm install -before_script: -script: - - xvfb-run npm run test diff --git a/elements/secure-request/LICENSE.md b/elements/secure-request/LICENSE.md deleted file mode 100644 index 4618ce4775..0000000000 --- a/elements/secure-request/LICENSE.md +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2018 The Pennsylvania State University - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/elements/secure-request/README.md b/elements/secure-request/README.md deleted file mode 100644 index 5191d3224f..0000000000 --- a/elements/secure-request/README.md +++ /dev/null @@ -1,35 +0,0 @@ -# <secure-request> - -Request -> Automated conversion of secure-request/ - -## Usage -To use this web component in your project you can utilize one of the following styles of syntax. - -```js -/* In an existing module / web component */ -import '@haxtheweb/secure-request.js'; - - - -``` - -## Develop / Demo -Running `npm start` will start a local development server and open your default browser to display it. It will start watching *.js and lib/*.js files for changes automatically for your demo. -```bash -$ npm start -``` - - -## Contributing - -1. Fork it! `git clone git@github.com/haxtheweb/webcomponents.git` -2. Create your feature branch: `git checkout -b my-new-feature` -3. Commit your changes: `git commit -m 'Add some feature'` -4. Push to the branch: `git push origin my-new-feature` -5. Submit a pull request :D - -Request - -## License -[Apache-2.0 License](http://opensource.org/licenses/Apache-2.0) \ No newline at end of file diff --git a/elements/secure-request/demo/index.html b/elements/secure-request/demo/index.html deleted file mode 100644 index 29c2c39bb2..0000000000 --- a/elements/secure-request/demo/index.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - SecureRequest: secure-request Demo - - - - - - -
    -

    Basic secure-request demo

    - - - -
    - - diff --git a/elements/secure-request/gulpfile.cjs b/elements/secure-request/gulpfile.cjs deleted file mode 100755 index 6d00d02f13..0000000000 --- a/elements/secure-request/gulpfile.cjs +++ /dev/null @@ -1,25 +0,0 @@ -const gulp = require("gulp"); -const fs = require("fs"); -const path = require("path"); -const packageJson = require("./package.json"); -// run polymer analyze to generate documentation -gulp.task("analyze", () => { - var exec = require("child_process").exec; - return exec( - "polymer analyze --input demo/index.html > analysis.json", - function(error, stdout, stderr) { - if (error !== null) { - console.log("exec error: " + error); - } - } - ); -}); - -gulp.task("watch", () => { - return gulp.watch(["./*.js","./lib/*", "./demo/*"], gulp.series("analyze")); -}); - -// simple developer flow -gulp.task("dev", gulp.series("analyze", "watch")); - -gulp.task("default", gulp.series("analyze")); diff --git a/elements/secure-request/index.html b/elements/secure-request/index.html deleted file mode 100755 index 7cb25e0705..0000000000 --- a/elements/secure-request/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - secure-request documentation - - - - - - - diff --git a/elements/secure-request/package.json b/elements/secure-request/package.json deleted file mode 100755 index 3925763d55..0000000000 --- a/elements/secure-request/package.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "name": "@haxtheweb/secure-request", - "wcfactory": { - "className": "SecureRequest", - "customElementClass": "PolymerElement", - "elementName": "secure-request", - "generator-wcfactory-version": "0.3.2", - "useHAX": true, - "useSass": false, - "files": { - "css": "src/secure-request.css", - "html": "src/secure-request.html", - "js": "src/secure-request.js", - "properties": "src/secure-request-properties.json", - "hax": "src/secure-request-hax.json" - }, - "sharedStyles": [] - }, - "version": "11.0.5", - "description": "Automated conversion of secure-request/", - "repository": { - "type": "git", - "url": "https://github.com/haxtheweb/webcomponents.git" - }, - "type": "module", - "main": "secure-request.js", - "module": "secure-request.js", - "scripts": { - "start": "yarn run dev", - "build": "gulp --gulpfile=gulpfile.cjs && prettier --ignore-path ../../.prettierignore --write \"**/*.{js,json}\" && cem analyze --litelement --exclude \"(public|*.stories.js)\" --globs \"{*,lib/**}.js\"", - "dev": "concurrently --kill-others \"yarn run watch\" \"yarn run serve\"", - "watch": "gulp dev --gulpfile=gulpfile.cjs", - "serve": "web-dev-server -c ../../web-dev-server.config.mjs", - "lighthouse": "gulp lighthouse --gulpfile=gulpfile.cjs", - "test:watch": "web-test-runner \"test/**/*.test.js\" --node-resolve --config=../../web-test-runner.config.mjs --playwright --browsers chromium --watch", - "test": "web-test-runner \"test/**/*.test.js\" --node-resolve --config=../../web-test-runner.config.mjs --playwright --browsers chromium" - }, - "author": { - "name": "haxtheweb", - "url": "https://hax.psu.edu/" - }, - "license": "Apache-2.0", - "dependencies": { - "@polymer/polymer": "3.5.2" - }, - "devDependencies": { - "@custom-elements-manifest/analyzer": "0.10.4", - "@haxtheweb/deduping-fix": "^11.0.0", - "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", - "@web/dev-server": "0.4.6", - "concurrently": "9.1.2", - "wct-browser-legacy": "1.0.2" - }, - "private": false, - "publishConfig": { - "access": "public" - }, - "customElements": "custom-elements.json", - "keywords": [ - "webcomponents", - "html", - "haxtheweb", - "lit" - ], - "gitHead": "73a678e1d035b003097fd50b7b23c0d9c30f9b26" -} diff --git a/elements/secure-request/polymer.json b/elements/secure-request/polymer.json deleted file mode 100755 index 41b0487735..0000000000 --- a/elements/secure-request/polymer.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "entrypoint": "demo/index.html", - "extraDependencies": [ - "node_modules/@webcomponents/webcomponentsjs/*.js", - "!node_modules/@webcomponents/webcomponentsjs/gulpfile.js", - "node_modules/@webcomponents/webcomponentsjs/bundles/*.js" - ], - "sources": [], - "builds": [ - { - "name": "es6", - "browserCapabilities": ["es2018", "modules"], - "js": { - "minify": true - }, - "css": { - "minify": true - }, - "html": { - "minify": true - }, - "bundle": false, - "addServiceWorker": false - } - ], - "moduleResolution": "node", - "npm": true, - "lint": { - "rules": ["polymer-3"] - } -} diff --git a/elements/secure-request/secure-request.js b/elements/secure-request/secure-request.js deleted file mode 100644 index 852c628058..0000000000 --- a/elements/secure-request/secure-request.js +++ /dev/null @@ -1,109 +0,0 @@ -/** - * `secure-request` - * @element secure-request - * `Wrapper behavior to provide the basis for a secure XHR` - * - * @demo demo/index.html - * @polymerBehavior - * @polymer - */ -// superclass element mix in -export const SecureRequestXhr = function (SuperClass) { - return class extends SuperClass { - /** - * Set cookies for the request - */ - setCookies(endPoint, csrfToken) { - this._eraseCookie("securerequest-endpoint"); - this._eraseCookie("securerequest-csrftoken"); - this._createCookie("securerequest-endpoint", endPoint, 30, endPoint); - this._createCookie("securerequest-csrftoken", csrfToken, 30, endPoint); - } - // call this function from your child components to generate secure urls - generateUrl(url) { - const endPoint = this.getEndPoint(); - const csrfToken = this.getCsrfToken(); - if (endPoint && csrfToken) { - return endPoint + url + "?token=" + csrfToken; - } - return null; - } - getEndPoint() { - return this._readCookie("securerequest-endpoint"); - } - getCsrfToken() { - return this._readCookie("securerequest-csrftoken"); - } - _createCookie(name, value, days, path) { - var expires = ""; - if (days) { - var date = new Date(); - date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000); - expires = "; expires=" + date.toUTCString(); - } - globalThis.document.cookie = - name + "=" + value + expires + "; path=" + path; - } - _readCookie(name) { - var nameEQ = name + "="; - var ca = globalThis.document.cookie.split(";"); - for (var i = 0; i < ca.length; i++) { - var c = ca[i]; - while (c.charAt(0) == " ") c = c.substring(1, c.length); - if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length); - } - return null; - } - _eraseCookie(name) { - this._createCookie(name, "", -1); - } - }; -}; -globalThis.SecureRequest = globalThis.SecureRequest || {}; -globalThis.SecureRequest.xhr = { - // Call this function in your root component. - setCookies(endPoint, csrfToken) { - this._eraseCookie("securerequest-endpoint"); - this._eraseCookie("securerequest-csrftoken"); - this._createCookie("securerequest-endpoint", endPoint, 30, endPoint); - this._createCookie("securerequest-csrftoken", csrfToken, 30, endPoint); - }, - // call this function from your child components to generate secure urls - generateUrl(url) { - const endPoint = this.getEndPoint(); - const csrfToken = this.getCsrfToken(); - if (endPoint && csrfToken) { - return endPoint + url + "?token=" + csrfToken; - } - return null; - }, - getEndPoint() { - return this._readCookie("securerequest-endpoint"); - }, - getCsrfToken() { - return this._readCookie("securerequest-csrftoken"); - }, - _createCookie(name, value, days, path) { - var expires = ""; - if (days) { - var date = new Date(); - date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000); - expires = "; expires=" + date.toUTCString(); - } - globalThis.document.cookie = - name + "=" + value + expires + "; path=" + path; - }, - _readCookie(name) { - var nameEQ = name + "="; - var ca = globalThis.document.cookie.split(";"); - for (var i = 0; i < ca.length; i++) { - var c = ca[i]; - while (c.charAt(0) == " ") c = c.substring(1, c.length); - if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length); - } - return null; - }, - _eraseCookie(name) { - this._createCookie(name, "", -1); - }, -}; diff --git a/elements/secure-request/test/secure-request.test.js b/elements/secure-request/test/secure-request.test.js deleted file mode 100644 index 4383bc5626..0000000000 --- a/elements/secure-request/test/secure-request.test.js +++ /dev/null @@ -1,71 +0,0 @@ -import { fixture, expect, html } from "@open-wc/testing"; - -import "../secure-request.js"; - -describe("secure-request test", () => { - let element; - beforeEach(async () => { - element = await fixture(html` - - `); - }); - - it("passes the a11y audit", async () => { - await expect(element).shadowDom.to.be.accessible(); - }); -}); - -/* -describe("A11y/chai axe tests", () => { - it("secure-request passes accessibility test", async () => { - const el = await fixture(html` `); - await expect(el).to.be.accessible(); - }); - it("secure-request passes accessibility negation", async () => { - const el = await fixture( - html`` - ); - await assert.isNotAccessible(el); - }); -}); - -/* -// Custom properties test -describe("Custom Property Test", () => { - it("secure-request can instantiate a element with custom properties", async () => { - const el = await fixture(html``); - expect(el.foo).to.equal('bar'); - }) -}) -*/ - -/* -// Test if element is mobile responsive -describe('Test Mobile Responsiveness', () => { - before(async () => {z - await setViewport({width: 375, height: 750}); - }) - it('sizes down to 360px', async () => { - const el = await fixture(html``); - const width = getComputedStyle(el).width; - expect(width).to.equal('360px'); - }) -}) */ - -/* -// Test if element sizes up for desktop behavior -describe('Test Desktop Responsiveness', () => { - before(async () => { - await setViewport({width: 1000, height: 1000}); - }) - it('sizes up to 410px', async () => { - const el = await fixture(html``); - const width = getComputedStyle(el).width; - expect(width).to.equal('410px'); - }) - it('hides mobile menu', async () => { - const el await fixture(html``); - const hidden = el.getAttribute('hidden'); - expect(hidden).to.equal(true); - }) -}) */ From 4122801a0826c24b027940d02db8a9e7871d5572 Mon Sep 17 00:00:00 2001 From: btopro Date: Thu, 16 Oct 2025 14:44:23 -0400 Subject: [PATCH 131/166] https://github.com/haxtheweb/issues/issues/2473 --- elements/a11y-media-player/package.json | 1 - elements/a11y-menu-button/package.json | 1 - elements/app-hax/package.json | 1 - elements/bootstrap-theme/package.json | 1 - elements/chartist-render/package.json | 1 - elements/citation-element/package.json | 1 - elements/clean-one/package.json | 1 - elements/clean-two/package.json | 1 - elements/code-editor/package.json | 1 - elements/documentation-player/package.json | 1 - elements/editable-table/package.json | 1 - elements/grade-book/package.json | 1 - elements/grid-plate/package.json | 1 - elements/hax-body/package.json | 1 - elements/img-view-modal/package.json | 1 - elements/lrs-elements/package.json | 1 - elements/page-contents-menu/package.json | 1 - elements/play-list/package.json | 1 - elements/product-card/package.json | 1 - elements/rich-text-editor/package.json | 1 - elements/schema-behaviors/package.json | 1 - elements/simple-autocomplete/package.json | 1 - elements/simple-cta/package.json | 1 - elements/simple-fields/package.json | 1 - elements/simple-toolbar/package.json | 1 - elements/video-player/package.json | 1 - .../lib/web-container-doc-player.js | 6 +- find-double-utils.sh | 38 +++++++++++ fix-double-utils.sh | 60 +++++++++++++++++ update-devdeps-simple.sh | 33 ++++++++++ update-devdeps.sh | 66 +++++++++++++++++++ 31 files changed, 200 insertions(+), 29 deletions(-) mode change 100755 => 100644 elements/a11y-media-player/package.json mode change 100755 => 100644 elements/a11y-menu-button/package.json mode change 100755 => 100644 elements/chartist-render/package.json mode change 100755 => 100644 elements/citation-element/package.json mode change 100755 => 100644 elements/code-editor/package.json mode change 100755 => 100644 elements/editable-table/package.json mode change 100755 => 100644 elements/grid-plate/package.json mode change 100755 => 100644 elements/hax-body/package.json mode change 100755 => 100644 elements/img-view-modal/package.json mode change 100755 => 100644 elements/product-card/package.json mode change 100755 => 100644 elements/rich-text-editor/package.json mode change 100755 => 100644 elements/schema-behaviors/package.json mode change 100755 => 100644 elements/simple-fields/package.json mode change 100755 => 100644 elements/video-player/package.json create mode 100755 find-double-utils.sh create mode 100755 fix-double-utils.sh create mode 100755 update-devdeps-simple.sh create mode 100755 update-devdeps.sh diff --git a/elements/a11y-media-player/package.json b/elements/a11y-media-player/package.json old mode 100755 new mode 100644 index 9099807d09..f0dea915f1 --- a/elements/a11y-media-player/package.json +++ b/elements/a11y-media-player/package.json @@ -62,7 +62,6 @@ "devDependencies": { "@custom-elements-manifest/analyzer": "0.10.4", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/a11y-menu-button/package.json b/elements/a11y-menu-button/package.json old mode 100755 new mode 100644 index c55084dcc3..30903aaf49 --- a/elements/a11y-menu-button/package.json +++ b/elements/a11y-menu-button/package.json @@ -49,7 +49,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/app-hax/package.json b/elements/app-hax/package.json index 92151e2acf..85633b3317 100644 --- a/elements/app-hax/package.json +++ b/elements/app-hax/package.json @@ -82,7 +82,6 @@ "devDependencies": { "@custom-elements-manifest/analyzer": "0.10.4", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/bootstrap-theme/package.json b/elements/bootstrap-theme/package.json index 93d20e534e..1153aff147 100644 --- a/elements/bootstrap-theme/package.json +++ b/elements/bootstrap-theme/package.json @@ -58,7 +58,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/chartist-render/package.json b/elements/chartist-render/package.json old mode 100755 new mode 100644 index 23c906e314..e4ab9f3a99 --- a/elements/chartist-render/package.json +++ b/elements/chartist-render/package.json @@ -55,7 +55,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/citation-element/package.json b/elements/citation-element/package.json old mode 100755 new mode 100644 index 166941eb3b..779cde88e2 --- a/elements/citation-element/package.json +++ b/elements/citation-element/package.json @@ -47,7 +47,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/clean-one/package.json b/elements/clean-one/package.json index 693acc58e1..527528f0b1 100644 --- a/elements/clean-one/package.json +++ b/elements/clean-one/package.json @@ -59,7 +59,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/clean-two/package.json b/elements/clean-two/package.json index c0376d947b..e8026bd222 100644 --- a/elements/clean-two/package.json +++ b/elements/clean-two/package.json @@ -56,7 +56,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/code-editor/package.json b/elements/code-editor/package.json old mode 100755 new mode 100644 index df314aba10..6b98fea448 --- a/elements/code-editor/package.json +++ b/elements/code-editor/package.json @@ -50,7 +50,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/documentation-player/package.json b/elements/documentation-player/package.json index 258069a757..00474fe500 100644 --- a/elements/documentation-player/package.json +++ b/elements/documentation-player/package.json @@ -55,7 +55,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "gulp-babel": "8.0.0", diff --git a/elements/editable-table/package.json b/elements/editable-table/package.json old mode 100755 new mode 100644 index 22235a549d..ccd33994b0 --- a/elements/editable-table/package.json +++ b/elements/editable-table/package.json @@ -57,7 +57,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/grade-book/package.json b/elements/grade-book/package.json index d763e03556..b9093d2bfe 100644 --- a/elements/grade-book/package.json +++ b/elements/grade-book/package.json @@ -68,7 +68,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/grid-plate/package.json b/elements/grid-plate/package.json old mode 100755 new mode 100644 index 74d150cab5..265b813253 --- a/elements/grid-plate/package.json +++ b/elements/grid-plate/package.json @@ -46,7 +46,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/hax-body/package.json b/elements/hax-body/package.json old mode 100755 new mode 100644 index 274963b627..184cdcf4d6 --- a/elements/hax-body/package.json +++ b/elements/hax-body/package.json @@ -97,7 +97,6 @@ "@haxtheweb/video-player": "^11.0.5", "@haxtheweb/wikipedia-query": "^11.0.5", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/img-view-modal/package.json b/elements/img-view-modal/package.json old mode 100755 new mode 100644 index d22ee95133..794d10c893 --- a/elements/img-view-modal/package.json +++ b/elements/img-view-modal/package.json @@ -55,7 +55,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/lrs-elements/package.json b/elements/lrs-elements/package.json index b1c3c726ef..bf480e380f 100644 --- a/elements/lrs-elements/package.json +++ b/elements/lrs-elements/package.json @@ -53,7 +53,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/page-contents-menu/package.json b/elements/page-contents-menu/package.json index 22236ee1f6..62c8957d61 100644 --- a/elements/page-contents-menu/package.json +++ b/elements/page-contents-menu/package.json @@ -52,7 +52,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/play-list/package.json b/elements/play-list/package.json index 0a0219639d..c85035d7fb 100644 --- a/elements/play-list/package.json +++ b/elements/play-list/package.json @@ -53,7 +53,6 @@ "@haxtheweb/deduping-fix": "^11.0.0", "@haxtheweb/video-player": "^11.0.5", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "gulp-babel": "8.0.0", diff --git a/elements/product-card/package.json b/elements/product-card/package.json old mode 100755 new mode 100644 index 2ae8057898..e8cc3f0b51 --- a/elements/product-card/package.json +++ b/elements/product-card/package.json @@ -81,7 +81,6 @@ "@haxtheweb/wikipedia-query": "^11.0.5", "@lrnwebcomponents/lrndesign-gallery": "^7.0.11", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/rich-text-editor/package.json b/elements/rich-text-editor/package.json old mode 100755 new mode 100644 index 7a47438f4d..99c8c4899e --- a/elements/rich-text-editor/package.json +++ b/elements/rich-text-editor/package.json @@ -62,7 +62,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/schema-behaviors/package.json b/elements/schema-behaviors/package.json old mode 100755 new mode 100644 index bf53b55df1..6163651a54 --- a/elements/schema-behaviors/package.json +++ b/elements/schema-behaviors/package.json @@ -43,7 +43,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/simple-autocomplete/package.json b/elements/simple-autocomplete/package.json index aaaa25cec2..fcf9384c16 100644 --- a/elements/simple-autocomplete/package.json +++ b/elements/simple-autocomplete/package.json @@ -49,7 +49,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/simple-cta/package.json b/elements/simple-cta/package.json index c456346ec3..e3642bfb0a 100644 --- a/elements/simple-cta/package.json +++ b/elements/simple-cta/package.json @@ -54,7 +54,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/simple-fields/package.json b/elements/simple-fields/package.json old mode 100755 new mode 100644 index d389109d4d..e78cbfcaa8 --- a/elements/simple-fields/package.json +++ b/elements/simple-fields/package.json @@ -64,7 +64,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/simple-toolbar/package.json b/elements/simple-toolbar/package.json index 72c7da694a..0fab625b54 100644 --- a/elements/simple-toolbar/package.json +++ b/elements/simple-toolbar/package.json @@ -55,7 +55,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "concurrently": "9.1.2", "gulp-sourcemaps": "3.0.0", "wct-browser-legacy": "1.0.2" diff --git a/elements/video-player/package.json b/elements/video-player/package.json old mode 100755 new mode 100644 index 8f00bc5a18..cdb74d9cc5 --- a/elements/video-player/package.json +++ b/elements/video-player/package.json @@ -58,7 +58,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/web-container/lib/web-container-doc-player.js b/elements/web-container/lib/web-container-doc-player.js index 95b8d91062..c2ba3319e8 100644 --- a/elements/web-container/lib/web-container-doc-player.js +++ b/elements/web-container/lib/web-container-doc-player.js @@ -149,9 +149,9 @@ export class WebContainerDocPlayer extends DDDSuper(LitElement) { "name": "${this.element} doc example", "type": "module", "dependencies": { - "@haxtheweb/utils": "^10.0.0", - "@haxtheweb/code-sample": "^10.0.2", - "@haxtheweb/code-editor": "^10.0.2", + "@haxtheweb/demo-snippet": "^11.0.0", + "@haxtheweb/code-sample": "^11.0.0", + "@haxtheweb/code-editor": "^11.0.0", "wc-dox": "^1.1.0", "${this.project}": "${this.version}" }, diff --git a/find-double-utils.sh b/find-double-utils.sh new file mode 100755 index 0000000000..ad6f319b34 --- /dev/null +++ b/find-double-utils.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +# Script to find package.json files that have @haxtheweb/utils in BOTH dependencies and devDependencies +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ELEMENTS_DIR="${SCRIPT_DIR}/elements" + +echo "🔍 Finding files with @haxtheweb/utils in BOTH dependencies AND devDependencies" +echo "📂 Working in: $ELEMENTS_DIR" +echo "" + +count=0 +echo "Files with BOTH regular dependencies AND devDependencies on @haxtheweb/utils:" +echo "=================================================================" + +find "$ELEMENTS_DIR" -name "package.json" -not -path "*/node_modules/*" | while read -r file; do + # Check if file has utils in regular dependencies using jq + has_dependency=$(jq -r '.dependencies."@haxtheweb/utils" // empty' "$file") + # Check if file has utils in devDependencies using jq + has_devdependency=$(jq -r '.devDependencies."@haxtheweb/utils" // empty' "$file") + + if [[ -n "$has_dependency" && -n "$has_devdependency" ]]; then + echo "📦 $file" + echo " - Has utils in dependencies: ✓ ($has_dependency)" + echo " - Has utils in devDependencies: ✓ ($has_devdependency)" + echo "" + count=$((count + 1)) + fi +done + +if [ $count -eq 0 ]; then + echo "✅ No files found with utils in BOTH dependencies and devDependencies" + echo " This means there are no conflicts to resolve!" +else + echo "📊 Total files with both: $count" + echo "" + echo "💡 These are the ONLY files where devDependencies should be changed" + echo " because they have a legitimate dependency conflict." +fi \ No newline at end of file diff --git a/fix-double-utils.sh b/fix-double-utils.sh new file mode 100755 index 0000000000..9264687b4b --- /dev/null +++ b/fix-double-utils.sh @@ -0,0 +1,60 @@ +#!/bin/bash + +# Script to fix @haxtheweb/utils conflicts by removing devDependencies entries +# while preserving the runtime dependencies entries + +echo "🔧 Fixing @haxtheweb/utils conflicts by removing devDependencies entries" +echo "📂 Working in: $(pwd)/elements" +echo "" + +# Keep track of changes +changes_made=0 +backup_dir="backup_$(date +%Y%m%d_%H%M%S)" + +# Function to fix a single package.json file +fix_package_json() { + local file="$1" + + echo "🔍 Checking: $file" + + # Check if file has utils in both dependencies and devDependencies + has_deps=$(jq -r '.dependencies."@haxtheweb/utils" // empty' "$file") + has_dev_deps=$(jq -r '.devDependencies."@haxtheweb/utils" // empty' "$file") + + if [[ -n "$has_deps" && -n "$has_dev_deps" ]]; then + echo " ✅ Found conflict - has utils in both sections" + echo " 📋 Runtime dependency: $has_deps" + echo " 📋 Dev dependency: $has_dev_deps" + + # Create backup + mkdir -p "$backup_dir/$(dirname "$file")" + cp "$file" "$backup_dir/$file" + + # Remove the devDependencies entry for @haxtheweb/utils + jq 'del(.devDependencies."@haxtheweb/utils")' "$file" > "${file}.tmp" && mv "${file}.tmp" "$file" + + echo " 🔧 Removed devDependencies entry, kept runtime dependency" + ((changes_made++)) + echo "" + else + echo " ⏭️ No conflict found" + echo "" + fi +} + +# Find all package.json files in elements/ and process them +find elements/ -name "package.json" -type f | while read -r file; do + fix_package_json "$file" +done + +echo "==================================================" +echo "✅ Processing complete!" +echo "📊 Files modified: $changes_made" +echo "💾 Backups created in: $backup_dir" +echo "" +echo "🔍 To verify changes:" +echo " ./find-double-utils.sh" +echo "" +echo "🔄 To restore all changes:" +echo " cp -r $backup_dir/* ./" +echo " rm -rf $backup_dir" \ No newline at end of file diff --git a/update-devdeps-simple.sh b/update-devdeps-simple.sh new file mode 100755 index 0000000000..272455e4f2 --- /dev/null +++ b/update-devdeps-simple.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# Simple script to replace @haxtheweb/utils with @haxtheweb/demo-snippet in devDependencies +# Get the directory where this script is located +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ELEMENTS_DIR="${SCRIPT_DIR}/elements" + +echo "🔧 Simple replacement of @haxtheweb/utils with @haxtheweb/demo-snippet in devDependencies" +echo "📂 Working in: $ELEMENTS_DIR" +echo "" + +count=0 +# Find all package.json files and process them +find "$ELEMENTS_DIR" -name "package.json" -not -path "*/node_modules/*" | while read -r file; do + # Check if file contains @haxtheweb/utils in devDependencies section + if grep -A 10 '"devDependencies"' "$file" | grep -q '"@haxtheweb/utils"'; then + echo "📝 Updating: $file" + # Create backup + cp "$file" "${file}.simple_backup" + + # Use sed to replace the specific line + sed -i 's/"@haxtheweb\/utils": "\^11\.0\.0"/"@haxtheweb\/demo-snippet": "^11.0.5"/g' "$file" + + count=$((count + 1)) + fi +done + +echo "" +echo "✅ Processing complete!" +echo "📊 Files processed: Check the output above" +echo "" +echo "🔍 To verify changes:" +echo " find \"$ELEMENTS_DIR\" -name 'package.json' -exec grep -l '@haxtheweb/demo-snippet' {} \\;" \ No newline at end of file diff --git a/update-devdeps.sh b/update-devdeps.sh new file mode 100755 index 0000000000..26ef2010a3 --- /dev/null +++ b/update-devdeps.sh @@ -0,0 +1,66 @@ +#!/bin/bash + +# Script to replace @haxtheweb/utils with @haxtheweb/demo-snippet in devDependencies sections only +# This preserves legitimate dependencies on utils while updating devDependencies + +# Get the directory where this script is located +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ELEMENTS_DIR="${SCRIPT_DIR}/elements" + +echo "🔍 Searching for package.json files with @haxtheweb/utils in devDependencies..." +echo "📂 Working in: $ELEMENTS_DIR" +echo "" + +# Find all package.json files in the elements directory +find "$ELEMENTS_DIR" -name "package.json" -type f | while read -r file; do + echo "📋 Checking: $file" + + # Check if the file contains @haxtheweb/utils in devDependencies section + if grep -A 20 '"devDependencies"' "$file" | grep -q '"@haxtheweb/utils"'; then + echo "✅ Found @haxtheweb/utils in devDependencies of $file" + + # Create a backup + cp "$file" "${file}.backup" + echo "💾 Created backup: ${file}.backup" + + # Use perl for more precise replacement within devDependencies section only + perl -i -pe ' + BEGIN { $in_devdeps = 0; } + + # Track when we enter devDependencies section + if (/"devDependencies"\s*:\s*\{/) { + $in_devdeps = 1; + } + + # Track when we exit devDependencies (end of object) + if ($in_devdeps && /^\s*\}/) { + $in_devdeps = 0; + } + + # Only replace if we are in devDependencies section + if ($in_devdeps && /"@haxtheweb\/utils"/) { + s/"@haxtheweb\/utils":\s*"\^11\.0\.0"/"@haxtheweb\/demo-snippet": "^11.0.5"/g; + print STDERR " 🔄 Replaced utils with demo-snippet in devDependencies\n"; + } + ' "$file" + + echo "✅ Updated $file" + echo "" + else + echo "⏭️ No @haxtheweb/utils in devDependencies found in $file" + fi +done + +echo "" +echo "🎉 Script completed!" +echo "" +echo "📝 Summary of changes:" +echo " - Only devDependencies sections were modified" +echo " - Regular dependencies on @haxtheweb/utils were preserved" +echo " - Backup files created with .backup extension" +echo "" +echo "🔍 To verify changes, you can run:" +echo " find \"$ELEMENTS_DIR\" -name 'package.json' -exec grep -l '@haxtheweb/demo-snippet' {} \;" +echo "" +echo "🔙 To restore from backups if needed:" +echo " find \"$ELEMENTS_DIR\" -name 'package.json.backup' -exec sh -c 'mv \"\$1\" \"\${1%.backup}\"' _ {} \;" From 88aea8d81f6174d853747e47f67920a953f36306 Mon Sep 17 00:00:00 2001 From: btopro Date: Thu, 16 Oct 2025 14:54:29 -0400 Subject: [PATCH 132/166] https://github.com/haxtheweb/issues/issues/2473 --- .wcflibcache.json | 2 +- api/package.json | 2 +- elements/a11y-behaviors/package.json | 1 - elements/a11y-carousel/package.json | 1 - elements/a11y-collapse/package.json | 1 - elements/a11y-compare-image/package.json | 1 - elements/a11y-details/package.json | 1 - elements/a11y-figure/package.json | 1 - elements/a11y-gif-player/package.json | 1 - elements/a11y-tabs/package.json | 1 - elements/a11y-utils/package.json | 1 - .../absolute-position-behavior/package.json | 1 - elements/accent-card/package.json | 1 - elements/aframe-player/package.json | 1 - elements/air-horn/package.json | 1 - elements/anchor-behaviors/package.json | 1 - elements/audio-player/package.json | 1 - elements/awesome-explosion/package.json | 1 - elements/b-r/package.json | 1 - elements/barcode-reader/package.json | 1 - elements/baseline-build-hax/package.json | 1 - elements/beaker-broker/package.json | 1 - elements/chat-agent/package.json | 1 - elements/check-it-out/package.json | 1 - elements/cms-hax/package.json | 1 - elements/code-sample/package.json | 1 - elements/collection-list/package.json | 1 - elements/count-up/package.json | 1 - elements/course-design/package.json | 1 - elements/course-model/package.json | 1 - elements/csv-render/package.json | 1 - elements/d-d-d/package.json | 1 - elements/data-viz/package.json | 1 - elements/date-card/package.json | 1 - elements/discord-embed/package.json | 1 - elements/disqus-embed/package.json | 1 - elements/dl-behavior/package.json | 1 - elements/dynamic-import-registry/package.json | 1 - elements/elmsln-loading/package.json | 1 - elements/enhanced-text/package.json | 1 - elements/event-badge/package.json | 1 - elements/figure-label/package.json | 1 - elements/file-system-broker/package.json | 1 - elements/fill-in-the-blanks/package.json | 1 - elements/flash-card/package.json | 1 - elements/fluid-type/package.json | 1 - elements/full-width-image/package.json | 1 - elements/fullscreen-behaviors/package.json | 1 - elements/future-terminal-text/package.json | 1 - elements/git-corner/package.json | 1 - elements/github-preview/package.json | 1 - elements/h-a-x/package.json | 1 - elements/h5p-element/package.json | 1 - elements/hal-9000/package.json | 1 - elements/hax-body-behaviors/package.json | 1 - elements/hax-bookmarklet/package.json | 1 - elements/hax-cloud/package.json | 1 - elements/hax-iconset/package.json | 1 - elements/hax-logo/package.json | 1 - elements/haxcms-elements/package.json | 1 - elements/haxor-slevin/package.json | 1 - elements/hex-picker/package.json | 1 - elements/hexagon-loader/package.json | 1 - elements/html-block/package.json | 1 - elements/i18n-manager/package.json | 1 - elements/iframe-loader/package.json | 1 - elements/image-compare-slider/package.json | 1 - elements/image-inspector/package.json | 1 - elements/img-pan-zoom/package.json | 1 - elements/inline-audio/package.json | 1 - elements/json-outline-schema/package.json | 1 - elements/jwt-login/package.json | 1 - elements/la-tex/package.json | 1 - elements/lazy-image-helpers/package.json | 1 - elements/lazy-import-discover/package.json | 1 - elements/learn-two-theme/package.json | 1 - elements/lesson-overview/package.json | 1 - elements/license-element/package.json | 1 - elements/lorem-data/package.json | 1 - elements/lrn-gitgraph/package.json | 1 - elements/lrn-math/package.json | 1 - elements/lrn-table/package.json | 1 - elements/lrn-vocab/package.json | 1 - elements/lrndesign-chart/package.json | 1 - elements/lrndesign-imagemap/package.json | 1 - elements/lrndesign-timeline/package.json | 1 - elements/lunr-search/package.json | 1 - elements/map-menu/package.json | 1 - elements/mark-the-words/package.json | 1 - elements/matching-question/package.json | 1 - elements/md-block/package.json | 1 - elements/media-behaviors/package.json | 1 - elements/media-image/package.json | 1 - elements/media-quote/package.json | 1 - elements/meme-maker/package.json | 1 - elements/merit-badge/package.json | 1 - elements/micro-frontend-registry/package.json | 1 - elements/moar-sarcasm/package.json | 1 - elements/moment-element/package.json | 1 - elements/multiple-choice/package.json | 1 - elements/music-player/package.json | 1 - .../package.json | 1 - elements/oer-schema/package.json | 1 - elements/outline-player/package.json | 1 - elements/page-break/package.json | 1 - elements/page-flag/package.json | 1 - elements/page-scroll-position/package.json | 1 - elements/page-section/package.json | 1 - elements/paper-input-flagged/package.json | 1 - elements/paper-stepper/package.json | 1 - elements/parallax-image/package.json | 1 - elements/pdf-browser-viewer/package.json | 1 - elements/person-testimonial/package.json | 1 - elements/place-holder/package.json | 1 - elements/polaris-theme/package.json | 1 - elements/portal-launcher/package.json | 1 - elements/post-card/package.json | 1 - elements/pouch-db/package.json | 1 - elements/product-glance/package.json | 1 - elements/product-offering/package.json | 1 - elements/progress-donut/package.json | 1 - elements/promise-progress/package.json | 1 - elements/q-r/package.json | 1 - elements/radio-behaviors/package.json | 1 - elements/relative-heading/package.json | 1 - elements/replace-tag/package.json | 1 - elements/responsive-grid/package.json | 1 - elements/responsive-utility/package.json | 1 - elements/retro-card/package.json | 1 - elements/rpg-character/package.json | 1 - elements/runkit-embed/package.json | 1 - elements/scroll-button/package.json | 1 - elements/self-check/package.json | 1 - elements/shadow-style/package.json | 1 - elements/simple-blog/package.json | 1 - .../simple-colors-shared-styles/package.json | 1 - elements/simple-colors/package.json | 1 - elements/simple-datetime/package.json | 1 - elements/simple-emoji/package.json | 1 - elements/simple-filter/package.json | 1 - elements/simple-icon-picker/package.json | 1 - elements/simple-icon/package.json | 1 - elements/simple-img/package.json | 1 - elements/simple-login/package.json | 1 - elements/simple-modal/package.json | 1 - elements/simple-picker/package.json | 1 - elements/simple-popover/package.json | 1 - elements/simple-progress/package.json | 1 - elements/simple-range-input/package.json | 1 - elements/simple-search/package.json | 1 - elements/simple-toast/package.json | 1 - elements/social-share-link/package.json | 1 - elements/sorting-question/package.json | 1 - elements/spotify-embed/package.json | 1 - elements/star-rating/package.json | 1 - elements/super-daemon/package.json | 1 - elements/tagging-question/package.json | 1 - elements/terrible-themes/package.json | 1 - elements/training-theme/package.json | 1 - elements/twitter-embed/package.json | 1 - elements/type-writer/package.json | 1 - elements/undo-manager/package.json | 1 - elements/unity-webgl/package.json | 1 - elements/user-action/package.json | 1 - elements/user-scaffold/package.json | 1 - elements/vocab-term/package.json | 1 - elements/voice-recorder/package.json | 1 - elements/wc-autoload/package.json | 1 - elements/wikipedia-query/package.json | 1 - elements/word-count/package.json | 1 - elements/wysiwyg-hax/package.json | 1 - find-double-utils.sh | 38 ----------- fix-double-utils.sh | 60 ----------------- package.json | 16 ++--- update-devdeps-simple.sh | 33 ---------- update-devdeps.sh | 66 ------------------- 176 files changed, 10 insertions(+), 376 deletions(-) mode change 100755 => 100644 elements/a11y-behaviors/package.json mode change 100755 => 100644 elements/a11y-carousel/package.json mode change 100755 => 100644 elements/a11y-collapse/package.json mode change 100755 => 100644 elements/a11y-compare-image/package.json mode change 100755 => 100644 elements/a11y-gif-player/package.json mode change 100755 => 100644 elements/a11y-tabs/package.json mode change 100755 => 100644 elements/absolute-position-behavior/package.json mode change 100755 => 100644 elements/accent-card/package.json mode change 100755 => 100644 elements/aframe-player/package.json mode change 100755 => 100644 elements/air-horn/package.json mode change 100755 => 100644 elements/anchor-behaviors/package.json mode change 100755 => 100644 elements/awesome-explosion/package.json mode change 100755 => 100644 elements/baseline-build-hax/package.json mode change 100755 => 100644 elements/beaker-broker/package.json mode change 100755 => 100644 elements/chat-agent/package.json mode change 100755 => 100644 elements/cms-hax/package.json mode change 100755 => 100644 elements/code-sample/package.json mode change 100755 => 100644 elements/count-up/package.json mode change 100755 => 100644 elements/csv-render/package.json mode change 100755 => 100644 elements/data-viz/package.json mode change 100755 => 100644 elements/dl-behavior/package.json mode change 100755 => 100644 elements/dynamic-import-registry/package.json mode change 100755 => 100644 elements/elmsln-loading/package.json mode change 100755 => 100644 elements/figure-label/package.json mode change 100755 => 100644 elements/fluid-type/package.json mode change 100755 => 100644 elements/full-width-image/package.json mode change 100755 => 100644 elements/fullscreen-behaviors/package.json mode change 100755 => 100644 elements/git-corner/package.json mode change 100755 => 100644 elements/h-a-x/package.json mode change 100755 => 100644 elements/h5p-element/package.json mode change 100755 => 100644 elements/hal-9000/package.json mode change 100755 => 100644 elements/hax-body-behaviors/package.json mode change 100755 => 100644 elements/hax-bookmarklet/package.json mode change 100755 => 100644 elements/hax-iconset/package.json mode change 100755 => 100644 elements/hax-logo/package.json mode change 100755 => 100644 elements/haxcms-elements/package.json mode change 100755 => 100644 elements/haxor-slevin/package.json mode change 100755 => 100644 elements/hexagon-loader/package.json mode change 100755 => 100644 elements/html-block/package.json mode change 100755 => 100644 elements/image-compare-slider/package.json mode change 100755 => 100644 elements/image-inspector/package.json mode change 100755 => 100644 elements/img-pan-zoom/package.json mode change 100755 => 100644 elements/json-outline-schema/package.json mode change 100755 => 100644 elements/jwt-login/package.json mode change 100755 => 100644 elements/lazy-import-discover/package.json mode change 100755 => 100644 elements/learn-two-theme/package.json mode change 100755 => 100644 elements/license-element/package.json mode change 100755 => 100644 elements/lorem-data/package.json mode change 100755 => 100644 elements/lrn-gitgraph/package.json mode change 100755 => 100644 elements/lrn-math/package.json mode change 100755 => 100644 elements/lrn-table/package.json mode change 100755 => 100644 elements/lrn-vocab/package.json mode change 100755 => 100644 elements/lrndesign-chart/package.json mode change 100755 => 100644 elements/lrndesign-imagemap/package.json mode change 100755 => 100644 elements/lrndesign-timeline/package.json mode change 100755 => 100644 elements/lunr-search/package.json mode change 100755 => 100644 elements/map-menu/package.json mode change 100755 => 100644 elements/md-block/package.json mode change 100755 => 100644 elements/media-behaviors/package.json mode change 100755 => 100644 elements/media-image/package.json mode change 100755 => 100644 elements/meme-maker/package.json mode change 100755 => 100644 elements/moment-element/package.json mode change 100755 => 100644 elements/multiple-choice/package.json mode change 100755 => 100644 elements/mutation-observer-import-mixin/package.json mode change 100755 => 100644 elements/oer-schema/package.json mode change 100755 => 100644 elements/outline-player/package.json mode change 100755 => 100644 elements/page-scroll-position/package.json mode change 100755 => 100644 elements/paper-input-flagged/package.json mode change 100755 => 100644 elements/paper-stepper/package.json mode change 100755 => 100644 elements/parallax-image/package.json mode change 100755 => 100644 elements/pdf-browser-viewer/package.json mode change 100755 => 100644 elements/person-testimonial/package.json mode change 100755 => 100644 elements/place-holder/package.json mode change 100755 => 100644 elements/portal-launcher/package.json mode change 100755 => 100644 elements/pouch-db/package.json mode change 100755 => 100644 elements/progress-donut/package.json mode change 100755 => 100644 elements/q-r/package.json mode change 100755 => 100644 elements/radio-behaviors/package.json mode change 100755 => 100644 elements/relative-heading/package.json mode change 100755 => 100644 elements/responsive-grid/package.json mode change 100755 => 100644 elements/responsive-utility/package.json mode change 100755 => 100644 elements/retro-card/package.json mode change 100755 => 100644 elements/scroll-button/package.json mode change 100755 => 100644 elements/self-check/package.json mode change 100755 => 100644 elements/simple-blog/package.json mode change 100755 => 100644 elements/simple-colors-shared-styles/package.json mode change 100755 => 100644 elements/simple-colors/package.json mode change 100755 => 100644 elements/simple-datetime/package.json mode change 100755 => 100644 elements/simple-icon-picker/package.json mode change 100755 => 100644 elements/simple-login/package.json mode change 100755 => 100644 elements/simple-modal/package.json mode change 100755 => 100644 elements/simple-picker/package.json mode change 100755 => 100644 elements/simple-popover/package.json mode change 100755 => 100644 elements/simple-search/package.json mode change 100755 => 100644 elements/simple-toast/package.json mode change 100755 => 100644 elements/social-share-link/package.json mode change 100755 => 100644 elements/type-writer/package.json mode change 100755 => 100644 elements/undo-manager/package.json mode change 100755 => 100644 elements/user-action/package.json mode change 100755 => 100644 elements/voice-recorder/package.json mode change 100755 => 100644 elements/wc-autoload/package.json mode change 100755 => 100644 elements/wikipedia-query/package.json mode change 100755 => 100644 elements/word-count/package.json mode change 100755 => 100644 elements/wysiwyg-hax/package.json delete mode 100755 find-double-utils.sh delete mode 100755 fix-double-utils.sh delete mode 100755 update-devdeps-simple.sh delete mode 100755 update-devdeps.sh diff --git a/.wcflibcache.json b/.wcflibcache.json index cd8846d666..db4df544ea 100644 --- a/.wcflibcache.json +++ b/.wcflibcache.json @@ -51,7 +51,7 @@ "lighthouse": "gulp lighthouse --gulpfile=gulpfile.cjs" }, "dependencies": { - "lit": "^3.3.0" + "lit": "^3.3.1" }, "devDependencies": { "@haxtheweb/deduping-fix": "^9.0.0-alpha.0", diff --git a/api/package.json b/api/package.json index 1df55e252a..70e34aace9 100644 --- a/api/package.json +++ b/api/package.json @@ -6,7 +6,7 @@ }, "dependencies": { "patch-package": "^8.0.0", - "lit-html": "3.3.0", + "lit-html": "3.3.1", "@lit-labs/ssr": "^3.3.1", "lit": "3.3.1", "node-html-parser": "^6.1.13", diff --git a/elements/a11y-behaviors/package.json b/elements/a11y-behaviors/package.json old mode 100755 new mode 100644 index 8cb022258e..b0b24bf88f --- a/elements/a11y-behaviors/package.json +++ b/elements/a11y-behaviors/package.json @@ -40,7 +40,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/a11y-carousel/package.json b/elements/a11y-carousel/package.json old mode 100755 new mode 100644 index 25dd2a01e8..0c5d96e2da --- a/elements/a11y-carousel/package.json +++ b/elements/a11y-carousel/package.json @@ -50,7 +50,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/a11y-collapse/package.json b/elements/a11y-collapse/package.json old mode 100755 new mode 100644 index 4833f62750..cdc55e2d7b --- a/elements/a11y-collapse/package.json +++ b/elements/a11y-collapse/package.json @@ -50,7 +50,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/a11y-compare-image/package.json b/elements/a11y-compare-image/package.json old mode 100755 new mode 100644 index f411279c74..d602193548 --- a/elements/a11y-compare-image/package.json +++ b/elements/a11y-compare-image/package.json @@ -49,7 +49,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/a11y-details/package.json b/elements/a11y-details/package.json index ea8fa68cc6..31f60370d6 100644 --- a/elements/a11y-details/package.json +++ b/elements/a11y-details/package.json @@ -47,7 +47,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/a11y-figure/package.json b/elements/a11y-figure/package.json index 961bbf6de7..c38c4aa30c 100644 --- a/elements/a11y-figure/package.json +++ b/elements/a11y-figure/package.json @@ -43,7 +43,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/a11y-gif-player/package.json b/elements/a11y-gif-player/package.json old mode 100755 new mode 100644 index 954db311fe..fb0d12c463 --- a/elements/a11y-gif-player/package.json +++ b/elements/a11y-gif-player/package.json @@ -50,7 +50,6 @@ "@haxtheweb/deduping-fix": "^11.0.0", "@haxtheweb/simple-img": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/a11y-tabs/package.json b/elements/a11y-tabs/package.json old mode 100755 new mode 100644 index 50da762365..7fe6954982 --- a/elements/a11y-tabs/package.json +++ b/elements/a11y-tabs/package.json @@ -50,7 +50,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/a11y-utils/package.json b/elements/a11y-utils/package.json index d4eb2b31e6..cb98219d25 100644 --- a/elements/a11y-utils/package.json +++ b/elements/a11y-utils/package.json @@ -45,7 +45,6 @@ "devDependencies": { "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", - "@haxtheweb/utils": "^11.0.0", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" }, diff --git a/elements/absolute-position-behavior/package.json b/elements/absolute-position-behavior/package.json old mode 100755 new mode 100644 index d2416f44fa..b548d2b5b4 --- a/elements/absolute-position-behavior/package.json +++ b/elements/absolute-position-behavior/package.json @@ -47,7 +47,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/accent-card/package.json b/elements/accent-card/package.json old mode 100755 new mode 100644 index 1d6787d9f8..25bba37e19 --- a/elements/accent-card/package.json +++ b/elements/accent-card/package.json @@ -51,7 +51,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/aframe-player/package.json b/elements/aframe-player/package.json old mode 100755 new mode 100644 index b457ec9d3a..477d7b60e7 --- a/elements/aframe-player/package.json +++ b/elements/aframe-player/package.json @@ -45,7 +45,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/air-horn/package.json b/elements/air-horn/package.json old mode 100755 new mode 100644 index b4976a847b..720edcf7ff --- a/elements/air-horn/package.json +++ b/elements/air-horn/package.json @@ -44,7 +44,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/anchor-behaviors/package.json b/elements/anchor-behaviors/package.json old mode 100755 new mode 100644 index d5be5e0506..e2c8e0a5a8 --- a/elements/anchor-behaviors/package.json +++ b/elements/anchor-behaviors/package.json @@ -44,7 +44,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/audio-player/package.json b/elements/audio-player/package.json index 5dec2cb15a..d466fe1f93 100644 --- a/elements/audio-player/package.json +++ b/elements/audio-player/package.json @@ -50,7 +50,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/awesome-explosion/package.json b/elements/awesome-explosion/package.json old mode 100755 new mode 100644 index 76b3162691..92205afc99 --- a/elements/awesome-explosion/package.json +++ b/elements/awesome-explosion/package.json @@ -43,7 +43,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/b-r/package.json b/elements/b-r/package.json index bf70b5e296..92b2da9bac 100644 --- a/elements/b-r/package.json +++ b/elements/b-r/package.json @@ -49,7 +49,6 @@ "devDependencies": { "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/barcode-reader/package.json b/elements/barcode-reader/package.json index a3d32a7c74..9831e6f6a4 100644 --- a/elements/barcode-reader/package.json +++ b/elements/barcode-reader/package.json @@ -56,7 +56,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "gulp-babel": "8.0.0", diff --git a/elements/baseline-build-hax/package.json b/elements/baseline-build-hax/package.json old mode 100755 new mode 100644 index c2e80ffdbc..a356356525 --- a/elements/baseline-build-hax/package.json +++ b/elements/baseline-build-hax/package.json @@ -74,7 +74,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/beaker-broker/package.json b/elements/beaker-broker/package.json old mode 100755 new mode 100644 index e0590cb62e..efeb5cdda9 --- a/elements/beaker-broker/package.json +++ b/elements/beaker-broker/package.json @@ -47,7 +47,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/chat-agent/package.json b/elements/chat-agent/package.json old mode 100755 new mode 100644 index 1d84bdede9..c267197702 --- a/elements/chat-agent/package.json +++ b/elements/chat-agent/package.json @@ -53,7 +53,6 @@ "devDependencies": { "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "gulp-babel": "8.0.0", diff --git a/elements/check-it-out/package.json b/elements/check-it-out/package.json index 33ebe03c0c..002314c98c 100644 --- a/elements/check-it-out/package.json +++ b/elements/check-it-out/package.json @@ -55,7 +55,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/cms-hax/package.json b/elements/cms-hax/package.json old mode 100755 new mode 100644 index bdcd257ac4..9410092aa4 --- a/elements/cms-hax/package.json +++ b/elements/cms-hax/package.json @@ -47,7 +47,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/code-sample/package.json b/elements/code-sample/package.json old mode 100755 new mode 100644 index 607ed94a91..8b31095a01 --- a/elements/code-sample/package.json +++ b/elements/code-sample/package.json @@ -49,7 +49,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/collection-list/package.json b/elements/collection-list/package.json index b5491ee7e7..21385352a6 100644 --- a/elements/collection-list/package.json +++ b/elements/collection-list/package.json @@ -56,7 +56,6 @@ "@haxtheweb/deduping-fix": "^11.0.0", "@haxtheweb/hax-iconset": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "gulp-babel": "8.0.0", diff --git a/elements/count-up/package.json b/elements/count-up/package.json old mode 100755 new mode 100644 index da7ae8b94f..6b0b585781 --- a/elements/count-up/package.json +++ b/elements/count-up/package.json @@ -48,7 +48,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/course-design/package.json b/elements/course-design/package.json index 8f4e669b72..d01b6a45e1 100644 --- a/elements/course-design/package.json +++ b/elements/course-design/package.json @@ -57,7 +57,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/course-model/package.json b/elements/course-model/package.json index f26a8085ab..4a6e0e7f45 100644 --- a/elements/course-model/package.json +++ b/elements/course-model/package.json @@ -52,7 +52,6 @@ "@haxtheweb/media-image": "^11.0.5", "@haxtheweb/video-player": "^11.0.5", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "gulp-babel": "8.0.0", diff --git a/elements/csv-render/package.json b/elements/csv-render/package.json old mode 100755 new mode 100644 index 6c4b6e4ce9..c8cc7308de --- a/elements/csv-render/package.json +++ b/elements/csv-render/package.json @@ -48,7 +48,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/d-d-d/package.json b/elements/d-d-d/package.json index 6b63ed0da8..06fbfda3be 100644 --- a/elements/d-d-d/package.json +++ b/elements/d-d-d/package.json @@ -53,7 +53,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/d-d-docs": "^11.0.5", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "gulp-babel": "8.0.0", diff --git a/elements/data-viz/package.json b/elements/data-viz/package.json old mode 100755 new mode 100644 index 81e0097c13..1f993a9a72 --- a/elements/data-viz/package.json +++ b/elements/data-viz/package.json @@ -49,7 +49,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/date-card/package.json b/elements/date-card/package.json index 813fbc335e..1754905a42 100644 --- a/elements/date-card/package.json +++ b/elements/date-card/package.json @@ -50,7 +50,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/discord-embed/package.json b/elements/discord-embed/package.json index e92c02a465..39869f54e6 100644 --- a/elements/discord-embed/package.json +++ b/elements/discord-embed/package.json @@ -50,7 +50,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "gulp-babel": "8.0.0", diff --git a/elements/disqus-embed/package.json b/elements/disqus-embed/package.json index ac86486018..4029dafde3 100644 --- a/elements/disqus-embed/package.json +++ b/elements/disqus-embed/package.json @@ -49,7 +49,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "gulp-babel": "8.0.0", diff --git a/elements/dl-behavior/package.json b/elements/dl-behavior/package.json old mode 100755 new mode 100644 index c7ca01ae08..625d40a2ad --- a/elements/dl-behavior/package.json +++ b/elements/dl-behavior/package.json @@ -40,7 +40,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/dynamic-import-registry/package.json b/elements/dynamic-import-registry/package.json old mode 100755 new mode 100644 index df583e77fb..00dd8eb7a1 --- a/elements/dynamic-import-registry/package.json +++ b/elements/dynamic-import-registry/package.json @@ -43,7 +43,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/elmsln-loading/package.json b/elements/elmsln-loading/package.json old mode 100755 new mode 100644 index 9e6dad400d..45bfa84277 --- a/elements/elmsln-loading/package.json +++ b/elements/elmsln-loading/package.json @@ -46,7 +46,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/enhanced-text/package.json b/elements/enhanced-text/package.json index 72ed7d0cae..72534724d7 100644 --- a/elements/enhanced-text/package.json +++ b/elements/enhanced-text/package.json @@ -52,7 +52,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/event-badge/package.json b/elements/event-badge/package.json index f461edfc37..a64664daf5 100644 --- a/elements/event-badge/package.json +++ b/elements/event-badge/package.json @@ -51,7 +51,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/figure-label/package.json b/elements/figure-label/package.json old mode 100755 new mode 100644 index 0d32c94b97..7c52f59083 --- a/elements/figure-label/package.json +++ b/elements/figure-label/package.json @@ -47,7 +47,6 @@ "devDependencies": { "@custom-elements-manifest/analyzer": "0.10.4", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/file-system-broker/package.json b/elements/file-system-broker/package.json index 01bbb85caf..2c7d9790a0 100644 --- a/elements/file-system-broker/package.json +++ b/elements/file-system-broker/package.json @@ -50,7 +50,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/fill-in-the-blanks/package.json b/elements/fill-in-the-blanks/package.json index 88180c45e4..bac5922640 100644 --- a/elements/fill-in-the-blanks/package.json +++ b/elements/fill-in-the-blanks/package.json @@ -34,7 +34,6 @@ "devDependencies": { "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "gulp-babel": "8.0.0", diff --git a/elements/flash-card/package.json b/elements/flash-card/package.json index e718bde583..a87fdb7ee3 100644 --- a/elements/flash-card/package.json +++ b/elements/flash-card/package.json @@ -54,7 +54,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/fluid-type/package.json b/elements/fluid-type/package.json old mode 100755 new mode 100644 index a32f2f50e8..301d853e36 --- a/elements/fluid-type/package.json +++ b/elements/fluid-type/package.json @@ -44,7 +44,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/full-width-image/package.json b/elements/full-width-image/package.json old mode 100755 new mode 100644 index 890e6211b6..db4c123223 --- a/elements/full-width-image/package.json +++ b/elements/full-width-image/package.json @@ -43,7 +43,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/fullscreen-behaviors/package.json b/elements/fullscreen-behaviors/package.json old mode 100755 new mode 100644 index 8cec74a2e2..51d092aef5 --- a/elements/fullscreen-behaviors/package.json +++ b/elements/fullscreen-behaviors/package.json @@ -44,7 +44,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/future-terminal-text/package.json b/elements/future-terminal-text/package.json index bc0533680b..dd74d8ce34 100644 --- a/elements/future-terminal-text/package.json +++ b/elements/future-terminal-text/package.json @@ -50,7 +50,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/git-corner/package.json b/elements/git-corner/package.json old mode 100755 new mode 100644 index 5131741109..50004fe060 --- a/elements/git-corner/package.json +++ b/elements/git-corner/package.json @@ -47,7 +47,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/github-preview/package.json b/elements/github-preview/package.json index 3644f3c2df..4be4e13192 100644 --- a/elements/github-preview/package.json +++ b/elements/github-preview/package.json @@ -53,7 +53,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/h-a-x/package.json b/elements/h-a-x/package.json old mode 100755 new mode 100644 index 125685f2bf..d27290303a --- a/elements/h-a-x/package.json +++ b/elements/h-a-x/package.json @@ -48,7 +48,6 @@ "@haxtheweb/deduping-fix": "^11.0.0", "@haxtheweb/editable-table": "^11.0.5", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/h5p-element/package.json b/elements/h5p-element/package.json old mode 100755 new mode 100644 index a631555762..0010f07776 --- a/elements/h5p-element/package.json +++ b/elements/h5p-element/package.json @@ -49,7 +49,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/hal-9000/package.json b/elements/hal-9000/package.json old mode 100755 new mode 100644 index beafbd9a00..87f2991509 --- a/elements/hal-9000/package.json +++ b/elements/hal-9000/package.json @@ -50,7 +50,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/hax-body-behaviors/package.json b/elements/hax-body-behaviors/package.json old mode 100755 new mode 100644 index 5bb4d9bd14..cfb5451cce --- a/elements/hax-body-behaviors/package.json +++ b/elements/hax-body-behaviors/package.json @@ -40,7 +40,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/hax-bookmarklet/package.json b/elements/hax-bookmarklet/package.json old mode 100755 new mode 100644 index c67005ee48..fc47aad2ca --- a/elements/hax-bookmarklet/package.json +++ b/elements/hax-bookmarklet/package.json @@ -49,7 +49,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/hax-cloud/package.json b/elements/hax-cloud/package.json index e1ad4655df..e79e84d13d 100644 --- a/elements/hax-cloud/package.json +++ b/elements/hax-cloud/package.json @@ -53,7 +53,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "gulp-babel": "8.0.0", diff --git a/elements/hax-iconset/package.json b/elements/hax-iconset/package.json old mode 100755 new mode 100644 index a229d125cd..71a9034310 --- a/elements/hax-iconset/package.json +++ b/elements/hax-iconset/package.json @@ -53,7 +53,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/hax-logo/package.json b/elements/hax-logo/package.json old mode 100755 new mode 100644 index 2697463f30..785974990d --- a/elements/hax-logo/package.json +++ b/elements/hax-logo/package.json @@ -40,7 +40,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/haxcms-elements/package.json b/elements/haxcms-elements/package.json old mode 100755 new mode 100644 index 827bbeb071..7fd90a2c1c --- a/elements/haxcms-elements/package.json +++ b/elements/haxcms-elements/package.json @@ -115,7 +115,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "@web/dev-server-esbuild": "1.0.2", "concurrently": "9.1.2", diff --git a/elements/haxor-slevin/package.json b/elements/haxor-slevin/package.json old mode 100755 new mode 100644 index 7fb61a882a..80679fc3cd --- a/elements/haxor-slevin/package.json +++ b/elements/haxor-slevin/package.json @@ -53,7 +53,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/hex-picker/package.json b/elements/hex-picker/package.json index 5fb373370e..1095fa2c47 100644 --- a/elements/hex-picker/package.json +++ b/elements/hex-picker/package.json @@ -50,7 +50,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/hexagon-loader/package.json b/elements/hexagon-loader/package.json old mode 100755 new mode 100644 index d96f81da25..02f22fb280 --- a/elements/hexagon-loader/package.json +++ b/elements/hexagon-loader/package.json @@ -47,7 +47,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/html-block/package.json b/elements/html-block/package.json old mode 100755 new mode 100644 index a2632c4e60..36b6fed4f1 --- a/elements/html-block/package.json +++ b/elements/html-block/package.json @@ -40,7 +40,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/i18n-manager/package.json b/elements/i18n-manager/package.json index 101c6ea431..c6dd836d4b 100644 --- a/elements/i18n-manager/package.json +++ b/elements/i18n-manager/package.json @@ -43,7 +43,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/iframe-loader/package.json b/elements/iframe-loader/package.json index bc17b05082..3309a97a2f 100644 --- a/elements/iframe-loader/package.json +++ b/elements/iframe-loader/package.json @@ -42,7 +42,6 @@ "devDependencies": { "@custom-elements-manifest/analyzer": "0.10.4", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/image-compare-slider/package.json b/elements/image-compare-slider/package.json old mode 100755 new mode 100644 index 320583f9db..04b9dcc8e7 --- a/elements/image-compare-slider/package.json +++ b/elements/image-compare-slider/package.json @@ -54,7 +54,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/image-inspector/package.json b/elements/image-inspector/package.json old mode 100755 new mode 100644 index 738dbe0c01..26a3f5ce9c --- a/elements/image-inspector/package.json +++ b/elements/image-inspector/package.json @@ -49,7 +49,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/img-pan-zoom/package.json b/elements/img-pan-zoom/package.json old mode 100755 new mode 100644 index 1ed9052e54..094282cc52 --- a/elements/img-pan-zoom/package.json +++ b/elements/img-pan-zoom/package.json @@ -49,7 +49,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/inline-audio/package.json b/elements/inline-audio/package.json index 4636b056a3..348d1a319f 100644 --- a/elements/inline-audio/package.json +++ b/elements/inline-audio/package.json @@ -54,7 +54,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/json-outline-schema/package.json b/elements/json-outline-schema/package.json old mode 100755 new mode 100644 index 08154f75cb..c07dfb350c --- a/elements/json-outline-schema/package.json +++ b/elements/json-outline-schema/package.json @@ -44,7 +44,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/jwt-login/package.json b/elements/jwt-login/package.json old mode 100755 new mode 100644 index 16972ca7cb..5b9ce986e6 --- a/elements/jwt-login/package.json +++ b/elements/jwt-login/package.json @@ -47,7 +47,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/la-tex/package.json b/elements/la-tex/package.json index 530d3cbfaa..1a5e9aee6c 100644 --- a/elements/la-tex/package.json +++ b/elements/la-tex/package.json @@ -49,7 +49,6 @@ "devDependencies": { "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "gulp-babel": "8.0.0", diff --git a/elements/lazy-image-helpers/package.json b/elements/lazy-image-helpers/package.json index 1881f29dae..4dd9cbb625 100644 --- a/elements/lazy-image-helpers/package.json +++ b/elements/lazy-image-helpers/package.json @@ -52,7 +52,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/lazy-import-discover/package.json b/elements/lazy-import-discover/package.json old mode 100755 new mode 100644 index c39f9b2bb5..3f853216ff --- a/elements/lazy-import-discover/package.json +++ b/elements/lazy-import-discover/package.json @@ -44,7 +44,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/learn-two-theme/package.json b/elements/learn-two-theme/package.json old mode 100755 new mode 100644 index d71e77e8a5..c362332b2a --- a/elements/learn-two-theme/package.json +++ b/elements/learn-two-theme/package.json @@ -54,7 +54,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/lesson-overview/package.json b/elements/lesson-overview/package.json index f9e031d375..602ab1b919 100644 --- a/elements/lesson-overview/package.json +++ b/elements/lesson-overview/package.json @@ -58,7 +58,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/license-element/package.json b/elements/license-element/package.json old mode 100755 new mode 100644 index 22884e6428..08d846a8bd --- a/elements/license-element/package.json +++ b/elements/license-element/package.json @@ -49,7 +49,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/lorem-data/package.json b/elements/lorem-data/package.json old mode 100755 new mode 100644 index 2af8dbab8e..be9cd8d420 --- a/elements/lorem-data/package.json +++ b/elements/lorem-data/package.json @@ -51,7 +51,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/lrn-gitgraph/package.json b/elements/lrn-gitgraph/package.json old mode 100755 new mode 100644 index 7ef4d2386b..5b7daf3478 --- a/elements/lrn-gitgraph/package.json +++ b/elements/lrn-gitgraph/package.json @@ -48,7 +48,6 @@ "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", "@polymer/iron-ajax": "3.0.1", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/lrn-math/package.json b/elements/lrn-math/package.json old mode 100755 new mode 100644 index 7e1e2f2e20..fafd278b5d --- a/elements/lrn-math/package.json +++ b/elements/lrn-math/package.json @@ -42,7 +42,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/lrn-table/package.json b/elements/lrn-table/package.json old mode 100755 new mode 100644 index 21a88eb804..7b944d5972 --- a/elements/lrn-table/package.json +++ b/elements/lrn-table/package.json @@ -45,7 +45,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/lrn-vocab/package.json b/elements/lrn-vocab/package.json old mode 100755 new mode 100644 index 2da464dd39..d289513114 --- a/elements/lrn-vocab/package.json +++ b/elements/lrn-vocab/package.json @@ -50,7 +50,6 @@ "@haxtheweb/deduping-fix": "^11.0.0", "@haxtheweb/video-player": "^11.0.5", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/lrndesign-chart/package.json b/elements/lrndesign-chart/package.json old mode 100755 new mode 100644 index 85679a2357..0cd2fc0d29 --- a/elements/lrndesign-chart/package.json +++ b/elements/lrndesign-chart/package.json @@ -52,7 +52,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/lrndesign-imagemap/package.json b/elements/lrndesign-imagemap/package.json old mode 100755 new mode 100644 index 16a65b1731..42f26bf805 --- a/elements/lrndesign-imagemap/package.json +++ b/elements/lrndesign-imagemap/package.json @@ -52,7 +52,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/lrndesign-timeline/package.json b/elements/lrndesign-timeline/package.json old mode 100755 new mode 100644 index ae49f08abc..c52c85120f --- a/elements/lrndesign-timeline/package.json +++ b/elements/lrndesign-timeline/package.json @@ -55,7 +55,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/lunr-search/package.json b/elements/lunr-search/package.json old mode 100755 new mode 100644 index ceca492361..2ce7fdb113 --- a/elements/lunr-search/package.json +++ b/elements/lunr-search/package.json @@ -45,7 +45,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/map-menu/package.json b/elements/map-menu/package.json old mode 100755 new mode 100644 index 2f518946ad..93391d48df --- a/elements/map-menu/package.json +++ b/elements/map-menu/package.json @@ -49,7 +49,6 @@ }, "devDependencies": { "@custom-elements-manifest/analyzer": "0.10.4", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/mark-the-words/package.json b/elements/mark-the-words/package.json index 9c57639183..48596bdd89 100644 --- a/elements/mark-the-words/package.json +++ b/elements/mark-the-words/package.json @@ -51,7 +51,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/matching-question/package.json b/elements/matching-question/package.json index 6a940859c3..d0819f782a 100644 --- a/elements/matching-question/package.json +++ b/elements/matching-question/package.json @@ -34,7 +34,6 @@ "devDependencies": { "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "gulp-babel": "8.0.0", diff --git a/elements/md-block/package.json b/elements/md-block/package.json old mode 100755 new mode 100644 index bb5291271c..c003f47768 --- a/elements/md-block/package.json +++ b/elements/md-block/package.json @@ -50,7 +50,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/media-behaviors/package.json b/elements/media-behaviors/package.json old mode 100755 new mode 100644 index 0d1c1ae46a..bb6644138f --- a/elements/media-behaviors/package.json +++ b/elements/media-behaviors/package.json @@ -40,7 +40,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/media-image/package.json b/elements/media-image/package.json old mode 100755 new mode 100644 index 2ade6a4212..d4b08de92a --- a/elements/media-image/package.json +++ b/elements/media-image/package.json @@ -54,7 +54,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/media-quote/package.json b/elements/media-quote/package.json index 499aaa0dc4..820be62107 100644 --- a/elements/media-quote/package.json +++ b/elements/media-quote/package.json @@ -34,7 +34,6 @@ "devDependencies": { "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "gulp-babel": "8.0.0", diff --git a/elements/meme-maker/package.json b/elements/meme-maker/package.json old mode 100755 new mode 100644 index 4b0831d717..f9e3f30be9 --- a/elements/meme-maker/package.json +++ b/elements/meme-maker/package.json @@ -47,7 +47,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/merit-badge/package.json b/elements/merit-badge/package.json index d160659373..0a53cf9e69 100644 --- a/elements/merit-badge/package.json +++ b/elements/merit-badge/package.json @@ -52,7 +52,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/micro-frontend-registry/package.json b/elements/micro-frontend-registry/package.json index 1802a82fc3..582ace39c4 100644 --- a/elements/micro-frontend-registry/package.json +++ b/elements/micro-frontend-registry/package.json @@ -47,7 +47,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/moar-sarcasm/package.json b/elements/moar-sarcasm/package.json index 321e9719a3..63574eec55 100644 --- a/elements/moar-sarcasm/package.json +++ b/elements/moar-sarcasm/package.json @@ -46,7 +46,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/moment-element/package.json b/elements/moment-element/package.json old mode 100755 new mode 100644 index 7d7b3d1f27..e762312b0e --- a/elements/moment-element/package.json +++ b/elements/moment-element/package.json @@ -48,7 +48,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/multiple-choice/package.json b/elements/multiple-choice/package.json old mode 100755 new mode 100644 index 6a7a922022..f6c306e7bc --- a/elements/multiple-choice/package.json +++ b/elements/multiple-choice/package.json @@ -55,7 +55,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/music-player/package.json b/elements/music-player/package.json index edb01e8659..ac82fb70ad 100644 --- a/elements/music-player/package.json +++ b/elements/music-player/package.json @@ -45,7 +45,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/mutation-observer-import-mixin/package.json b/elements/mutation-observer-import-mixin/package.json old mode 100755 new mode 100644 index fcdba8e3a8..17eda6c2d7 --- a/elements/mutation-observer-import-mixin/package.json +++ b/elements/mutation-observer-import-mixin/package.json @@ -46,7 +46,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/oer-schema/package.json b/elements/oer-schema/package.json old mode 100755 new mode 100644 index a1328bd34a..ecb8b4c444 --- a/elements/oer-schema/package.json +++ b/elements/oer-schema/package.json @@ -48,7 +48,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/outline-player/package.json b/elements/outline-player/package.json old mode 100755 new mode 100644 index 7f4bad9cd9..88d8492c38 --- a/elements/outline-player/package.json +++ b/elements/outline-player/package.json @@ -55,7 +55,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/page-break/package.json b/elements/page-break/package.json index 0783347722..aa291226e3 100644 --- a/elements/page-break/package.json +++ b/elements/page-break/package.json @@ -54,7 +54,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/page-flag/package.json b/elements/page-flag/package.json index 19e0eb6b2e..be3c18e7f4 100644 --- a/elements/page-flag/package.json +++ b/elements/page-flag/package.json @@ -58,7 +58,6 @@ "@haxtheweb/deduping-fix": "^11.0.0", "@haxtheweb/grid-plate": "^11.0.5", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/page-scroll-position/package.json b/elements/page-scroll-position/package.json old mode 100755 new mode 100644 index 58b32a3af6..9aba3268be --- a/elements/page-scroll-position/package.json +++ b/elements/page-scroll-position/package.json @@ -47,7 +47,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/page-section/package.json b/elements/page-section/package.json index 5221efd153..f9bf1a8e6e 100644 --- a/elements/page-section/package.json +++ b/elements/page-section/package.json @@ -57,7 +57,6 @@ "@haxtheweb/simple-cta": "^11.0.0", "@haxtheweb/video-player": "^11.0.5", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "gulp-babel": "8.0.0", diff --git a/elements/paper-input-flagged/package.json b/elements/paper-input-flagged/package.json old mode 100755 new mode 100644 index 14aa4b892a..757fc2d47c --- a/elements/paper-input-flagged/package.json +++ b/elements/paper-input-flagged/package.json @@ -51,7 +51,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/paper-stepper/package.json b/elements/paper-stepper/package.json old mode 100755 new mode 100644 index 9d0eb6a3f8..a02ae8236c --- a/elements/paper-stepper/package.json +++ b/elements/paper-stepper/package.json @@ -49,7 +49,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/parallax-image/package.json b/elements/parallax-image/package.json old mode 100755 new mode 100644 index a01dbc22e1..282b32ea2b --- a/elements/parallax-image/package.json +++ b/elements/parallax-image/package.json @@ -48,7 +48,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/pdf-browser-viewer/package.json b/elements/pdf-browser-viewer/package.json old mode 100755 new mode 100644 index 58902b1616..572d3d4606 --- a/elements/pdf-browser-viewer/package.json +++ b/elements/pdf-browser-viewer/package.json @@ -48,7 +48,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/person-testimonial/package.json b/elements/person-testimonial/package.json old mode 100755 new mode 100644 index 439dcf9b60..4c3b3cd829 --- a/elements/person-testimonial/package.json +++ b/elements/person-testimonial/package.json @@ -44,7 +44,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/place-holder/package.json b/elements/place-holder/package.json old mode 100755 new mode 100644 index e55e9deb32..fc56733911 --- a/elements/place-holder/package.json +++ b/elements/place-holder/package.json @@ -49,7 +49,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/polaris-theme/package.json b/elements/polaris-theme/package.json index 87e4d83a7e..f8b8e74185 100644 --- a/elements/polaris-theme/package.json +++ b/elements/polaris-theme/package.json @@ -51,7 +51,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "gulp-babel": "8.0.0", diff --git a/elements/portal-launcher/package.json b/elements/portal-launcher/package.json old mode 100755 new mode 100644 index 5095b75f42..555b6dbfb5 --- a/elements/portal-launcher/package.json +++ b/elements/portal-launcher/package.json @@ -44,7 +44,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/post-card/package.json b/elements/post-card/package.json index e97c91a71f..bdbc69cbc2 100644 --- a/elements/post-card/package.json +++ b/elements/post-card/package.json @@ -51,7 +51,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/pouch-db/package.json b/elements/pouch-db/package.json old mode 100755 new mode 100644 index a0dfc94aac..e9599d58cc --- a/elements/pouch-db/package.json +++ b/elements/pouch-db/package.json @@ -46,7 +46,6 @@ "@haxtheweb/deduping-fix": "^11.0.0", "@haxtheweb/multiple-choice": "^11.0.5", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/product-glance/package.json b/elements/product-glance/package.json index c8628f99c9..a1edfac366 100644 --- a/elements/product-glance/package.json +++ b/elements/product-glance/package.json @@ -52,7 +52,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/product-offering/package.json b/elements/product-offering/package.json index 5ad5716536..4cb2696638 100644 --- a/elements/product-offering/package.json +++ b/elements/product-offering/package.json @@ -52,7 +52,6 @@ "devDependencies": { "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/progress-donut/package.json b/elements/progress-donut/package.json old mode 100755 new mode 100644 index 6a293f16c5..b6609f072f --- a/elements/progress-donut/package.json +++ b/elements/progress-donut/package.json @@ -53,7 +53,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/promise-progress/package.json b/elements/promise-progress/package.json index cb35238a64..ef180c7621 100644 --- a/elements/promise-progress/package.json +++ b/elements/promise-progress/package.json @@ -52,7 +52,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/q-r/package.json b/elements/q-r/package.json old mode 100755 new mode 100644 index 4690c29fa0..9cffe7e5c7 --- a/elements/q-r/package.json +++ b/elements/q-r/package.json @@ -48,7 +48,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/radio-behaviors/package.json b/elements/radio-behaviors/package.json old mode 100755 new mode 100644 index 9be4f6d269..76641e6829 --- a/elements/radio-behaviors/package.json +++ b/elements/radio-behaviors/package.json @@ -40,7 +40,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/relative-heading/package.json b/elements/relative-heading/package.json old mode 100755 new mode 100644 index 96039630ad..a16e99dbb1 --- a/elements/relative-heading/package.json +++ b/elements/relative-heading/package.json @@ -51,7 +51,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/replace-tag/package.json b/elements/replace-tag/package.json index 96a966f550..8259cffcfb 100644 --- a/elements/replace-tag/package.json +++ b/elements/replace-tag/package.json @@ -50,7 +50,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/responsive-grid/package.json b/elements/responsive-grid/package.json old mode 100755 new mode 100644 index f1f40eeb23..73cad1ddac --- a/elements/responsive-grid/package.json +++ b/elements/responsive-grid/package.json @@ -48,7 +48,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/responsive-utility/package.json b/elements/responsive-utility/package.json old mode 100755 new mode 100644 index 1f85b26065..c64cac4ae6 --- a/elements/responsive-utility/package.json +++ b/elements/responsive-utility/package.json @@ -44,7 +44,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/retro-card/package.json b/elements/retro-card/package.json old mode 100755 new mode 100644 index 1009c2dcde..aafd0a5bc2 --- a/elements/retro-card/package.json +++ b/elements/retro-card/package.json @@ -50,7 +50,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/rpg-character/package.json b/elements/rpg-character/package.json index 6893ae5372..362c02fbb4 100644 --- a/elements/rpg-character/package.json +++ b/elements/rpg-character/package.json @@ -51,7 +51,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/runkit-embed/package.json b/elements/runkit-embed/package.json index 8e389399cd..336838a5a4 100644 --- a/elements/runkit-embed/package.json +++ b/elements/runkit-embed/package.json @@ -36,7 +36,6 @@ "devDependencies": { "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "gulp-babel": "8.0.0", diff --git a/elements/scroll-button/package.json b/elements/scroll-button/package.json old mode 100755 new mode 100644 index 961dde0174..4749ea9690 --- a/elements/scroll-button/package.json +++ b/elements/scroll-button/package.json @@ -46,7 +46,6 @@ "@haxtheweb/deduping-fix": "^11.0.0", "@haxtheweb/i18n-manager": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/self-check/package.json b/elements/self-check/package.json old mode 100755 new mode 100644 index 78fed4080e..22a3aa51ac --- a/elements/self-check/package.json +++ b/elements/self-check/package.json @@ -57,7 +57,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/shadow-style/package.json b/elements/shadow-style/package.json index 7945805d50..01e79907b1 100644 --- a/elements/shadow-style/package.json +++ b/elements/shadow-style/package.json @@ -48,7 +48,6 @@ "@haxtheweb/deduping-fix": "^11.0.0", "@haxtheweb/meme-maker": "^11.0.5", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/simple-blog/package.json b/elements/simple-blog/package.json old mode 100755 new mode 100644 index 35bd986299..6063f6ef1e --- a/elements/simple-blog/package.json +++ b/elements/simple-blog/package.json @@ -54,7 +54,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/simple-colors-shared-styles/package.json b/elements/simple-colors-shared-styles/package.json old mode 100755 new mode 100644 index 77b012dbe7..7d6feac0a7 --- a/elements/simple-colors-shared-styles/package.json +++ b/elements/simple-colors-shared-styles/package.json @@ -43,7 +43,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/simple-colors/package.json b/elements/simple-colors/package.json old mode 100755 new mode 100644 index 10b9ed714c..a7d79d0d97 --- a/elements/simple-colors/package.json +++ b/elements/simple-colors/package.json @@ -52,7 +52,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/simple-datetime/package.json b/elements/simple-datetime/package.json old mode 100755 new mode 100644 index fb47e6c1bf..10209cb4d6 --- a/elements/simple-datetime/package.json +++ b/elements/simple-datetime/package.json @@ -47,7 +47,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/simple-emoji/package.json b/elements/simple-emoji/package.json index 8b86991cea..425b771213 100644 --- a/elements/simple-emoji/package.json +++ b/elements/simple-emoji/package.json @@ -50,7 +50,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/simple-filter/package.json b/elements/simple-filter/package.json index b70eae7973..6b39347243 100644 --- a/elements/simple-filter/package.json +++ b/elements/simple-filter/package.json @@ -49,7 +49,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/simple-icon-picker/package.json b/elements/simple-icon-picker/package.json old mode 100755 new mode 100644 index dc33974fb0..c910b5fbd7 --- a/elements/simple-icon-picker/package.json +++ b/elements/simple-icon-picker/package.json @@ -50,7 +50,6 @@ "@haxtheweb/deduping-fix": "^11.0.0", "@haxtheweb/hax-iconset": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/simple-icon/package.json b/elements/simple-icon/package.json index 8335db259d..82c0f74f3a 100644 --- a/elements/simple-icon/package.json +++ b/elements/simple-icon/package.json @@ -55,7 +55,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/simple-img/package.json b/elements/simple-img/package.json index a3f24617f0..d57fe5c22a 100644 --- a/elements/simple-img/package.json +++ b/elements/simple-img/package.json @@ -50,7 +50,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/simple-login/package.json b/elements/simple-login/package.json old mode 100755 new mode 100644 index 5ae569b04f..43562631ca --- a/elements/simple-login/package.json +++ b/elements/simple-login/package.json @@ -54,7 +54,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/simple-modal/package.json b/elements/simple-modal/package.json old mode 100755 new mode 100644 index 05dfb6c9e4..02db45275f --- a/elements/simple-modal/package.json +++ b/elements/simple-modal/package.json @@ -51,7 +51,6 @@ "@haxtheweb/deduping-fix": "^11.0.0", "@haxtheweb/simple-fields": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/simple-picker/package.json b/elements/simple-picker/package.json old mode 100755 new mode 100644 index 067ce5d56b..6efd3f112e --- a/elements/simple-picker/package.json +++ b/elements/simple-picker/package.json @@ -49,7 +49,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/simple-popover/package.json b/elements/simple-popover/package.json old mode 100755 new mode 100644 index fcd3d22227..85ded15dd7 --- a/elements/simple-popover/package.json +++ b/elements/simple-popover/package.json @@ -53,7 +53,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/simple-progress/package.json b/elements/simple-progress/package.json index 23675a2ec6..a571f3e2ed 100644 --- a/elements/simple-progress/package.json +++ b/elements/simple-progress/package.json @@ -46,7 +46,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/simple-range-input/package.json b/elements/simple-range-input/package.json index 5be0becc93..79bc327337 100644 --- a/elements/simple-range-input/package.json +++ b/elements/simple-range-input/package.json @@ -50,7 +50,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/simple-search/package.json b/elements/simple-search/package.json old mode 100755 new mode 100644 index abae80a4cb..0303f0c1e6 --- a/elements/simple-search/package.json +++ b/elements/simple-search/package.json @@ -49,7 +49,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/simple-toast/package.json b/elements/simple-toast/package.json old mode 100755 new mode 100644 index 6414ab0174..49eddbf18e --- a/elements/simple-toast/package.json +++ b/elements/simple-toast/package.json @@ -50,7 +50,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/social-share-link/package.json b/elements/social-share-link/package.json old mode 100755 new mode 100644 index 7bd878703e..a3e579eec6 --- a/elements/social-share-link/package.json +++ b/elements/social-share-link/package.json @@ -49,7 +49,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/sorting-question/package.json b/elements/sorting-question/package.json index 901fc485e1..1c9c5dc252 100644 --- a/elements/sorting-question/package.json +++ b/elements/sorting-question/package.json @@ -56,7 +56,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/spotify-embed/package.json b/elements/spotify-embed/package.json index add98edfdf..c21dc88e04 100644 --- a/elements/spotify-embed/package.json +++ b/elements/spotify-embed/package.json @@ -49,7 +49,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/star-rating/package.json b/elements/star-rating/package.json index 33312fae5f..43c7f7644c 100644 --- a/elements/star-rating/package.json +++ b/elements/star-rating/package.json @@ -52,7 +52,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/super-daemon/package.json b/elements/super-daemon/package.json index 19954b1707..293c583f2e 100644 --- a/elements/super-daemon/package.json +++ b/elements/super-daemon/package.json @@ -60,7 +60,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/tagging-question/package.json b/elements/tagging-question/package.json index 3398f2bc8b..b827441c9c 100644 --- a/elements/tagging-question/package.json +++ b/elements/tagging-question/package.json @@ -35,7 +35,6 @@ "devDependencies": { "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "gulp-babel": "8.0.0", diff --git a/elements/terrible-themes/package.json b/elements/terrible-themes/package.json index 02718ccc35..ddb387e2ea 100644 --- a/elements/terrible-themes/package.json +++ b/elements/terrible-themes/package.json @@ -51,7 +51,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/training-theme/package.json b/elements/training-theme/package.json index b1ca8b8494..626752efcd 100644 --- a/elements/training-theme/package.json +++ b/elements/training-theme/package.json @@ -51,7 +51,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "gulp-babel": "8.0.0", diff --git a/elements/twitter-embed/package.json b/elements/twitter-embed/package.json index e7c0504927..6748994eb6 100644 --- a/elements/twitter-embed/package.json +++ b/elements/twitter-embed/package.json @@ -45,7 +45,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/type-writer/package.json b/elements/type-writer/package.json old mode 100755 new mode 100644 index b793bcac3c..0ae8329933 --- a/elements/type-writer/package.json +++ b/elements/type-writer/package.json @@ -47,7 +47,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/undo-manager/package.json b/elements/undo-manager/package.json old mode 100755 new mode 100644 index a3ea5a9b0c..ba297fc7eb --- a/elements/undo-manager/package.json +++ b/elements/undo-manager/package.json @@ -46,7 +46,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/unity-webgl/package.json b/elements/unity-webgl/package.json index 0667087616..6fcb96f3e1 100644 --- a/elements/unity-webgl/package.json +++ b/elements/unity-webgl/package.json @@ -47,7 +47,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/user-action/package.json b/elements/user-action/package.json old mode 100755 new mode 100644 index 299ada532a..4aaecf2044 --- a/elements/user-action/package.json +++ b/elements/user-action/package.json @@ -44,7 +44,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/user-scaffold/package.json b/elements/user-scaffold/package.json index 186a4939ad..c82531503c 100644 --- a/elements/user-scaffold/package.json +++ b/elements/user-scaffold/package.json @@ -51,7 +51,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "gulp-babel": "8.0.0", diff --git a/elements/vocab-term/package.json b/elements/vocab-term/package.json index 7c9177740e..1f42a64145 100644 --- a/elements/vocab-term/package.json +++ b/elements/vocab-term/package.json @@ -52,7 +52,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/voice-recorder/package.json b/elements/voice-recorder/package.json old mode 100755 new mode 100644 index e791a8b932..0d02b22626 --- a/elements/voice-recorder/package.json +++ b/elements/voice-recorder/package.json @@ -48,7 +48,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/wc-autoload/package.json b/elements/wc-autoload/package.json old mode 100755 new mode 100644 index cc5ecf8210..2a1ad9700d --- a/elements/wc-autoload/package.json +++ b/elements/wc-autoload/package.json @@ -46,7 +46,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/wikipedia-query/package.json b/elements/wikipedia-query/package.json old mode 100755 new mode 100644 index 62f971665e..b35e72e42f --- a/elements/wikipedia-query/package.json +++ b/elements/wikipedia-query/package.json @@ -50,7 +50,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/word-count/package.json b/elements/word-count/package.json old mode 100755 new mode 100644 index ecc9c5a08f..89a2126f54 --- a/elements/word-count/package.json +++ b/elements/word-count/package.json @@ -48,7 +48,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/elements/wysiwyg-hax/package.json b/elements/wysiwyg-hax/package.json old mode 100755 new mode 100644 index 0f6ecba495..8150a3aca9 --- a/elements/wysiwyg-hax/package.json +++ b/elements/wysiwyg-hax/package.json @@ -48,7 +48,6 @@ "@custom-elements-manifest/analyzer": "0.10.4", "@haxtheweb/deduping-fix": "^11.0.0", "@open-wc/testing": "4.0.0", - "@haxtheweb/utils": "^11.0.0", "@web/dev-server": "0.4.6", "concurrently": "9.1.2", "wct-browser-legacy": "1.0.2" diff --git a/find-double-utils.sh b/find-double-utils.sh deleted file mode 100755 index ad6f319b34..0000000000 --- a/find-double-utils.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash - -# Script to find package.json files that have @haxtheweb/utils in BOTH dependencies and devDependencies -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -ELEMENTS_DIR="${SCRIPT_DIR}/elements" - -echo "🔍 Finding files with @haxtheweb/utils in BOTH dependencies AND devDependencies" -echo "📂 Working in: $ELEMENTS_DIR" -echo "" - -count=0 -echo "Files with BOTH regular dependencies AND devDependencies on @haxtheweb/utils:" -echo "=================================================================" - -find "$ELEMENTS_DIR" -name "package.json" -not -path "*/node_modules/*" | while read -r file; do - # Check if file has utils in regular dependencies using jq - has_dependency=$(jq -r '.dependencies."@haxtheweb/utils" // empty' "$file") - # Check if file has utils in devDependencies using jq - has_devdependency=$(jq -r '.devDependencies."@haxtheweb/utils" // empty' "$file") - - if [[ -n "$has_dependency" && -n "$has_devdependency" ]]; then - echo "📦 $file" - echo " - Has utils in dependencies: ✓ ($has_dependency)" - echo " - Has utils in devDependencies: ✓ ($has_devdependency)" - echo "" - count=$((count + 1)) - fi -done - -if [ $count -eq 0 ]; then - echo "✅ No files found with utils in BOTH dependencies and devDependencies" - echo " This means there are no conflicts to resolve!" -else - echo "📊 Total files with both: $count" - echo "" - echo "💡 These are the ONLY files where devDependencies should be changed" - echo " because they have a legitimate dependency conflict." -fi \ No newline at end of file diff --git a/fix-double-utils.sh b/fix-double-utils.sh deleted file mode 100755 index 9264687b4b..0000000000 --- a/fix-double-utils.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/bash - -# Script to fix @haxtheweb/utils conflicts by removing devDependencies entries -# while preserving the runtime dependencies entries - -echo "🔧 Fixing @haxtheweb/utils conflicts by removing devDependencies entries" -echo "📂 Working in: $(pwd)/elements" -echo "" - -# Keep track of changes -changes_made=0 -backup_dir="backup_$(date +%Y%m%d_%H%M%S)" - -# Function to fix a single package.json file -fix_package_json() { - local file="$1" - - echo "🔍 Checking: $file" - - # Check if file has utils in both dependencies and devDependencies - has_deps=$(jq -r '.dependencies."@haxtheweb/utils" // empty' "$file") - has_dev_deps=$(jq -r '.devDependencies."@haxtheweb/utils" // empty' "$file") - - if [[ -n "$has_deps" && -n "$has_dev_deps" ]]; then - echo " ✅ Found conflict - has utils in both sections" - echo " 📋 Runtime dependency: $has_deps" - echo " 📋 Dev dependency: $has_dev_deps" - - # Create backup - mkdir -p "$backup_dir/$(dirname "$file")" - cp "$file" "$backup_dir/$file" - - # Remove the devDependencies entry for @haxtheweb/utils - jq 'del(.devDependencies."@haxtheweb/utils")' "$file" > "${file}.tmp" && mv "${file}.tmp" "$file" - - echo " 🔧 Removed devDependencies entry, kept runtime dependency" - ((changes_made++)) - echo "" - else - echo " ⏭️ No conflict found" - echo "" - fi -} - -# Find all package.json files in elements/ and process them -find elements/ -name "package.json" -type f | while read -r file; do - fix_package_json "$file" -done - -echo "==================================================" -echo "✅ Processing complete!" -echo "📊 Files modified: $changes_made" -echo "💾 Backups created in: $backup_dir" -echo "" -echo "🔍 To verify changes:" -echo " ./find-double-utils.sh" -echo "" -echo "🔄 To restore all changes:" -echo " cp -r $backup_dir/* ./" -echo " rm -rf $backup_dir" \ No newline at end of file diff --git a/package.json b/package.json index a2701a3c99..9fab4069bc 100644 --- a/package.json +++ b/package.json @@ -76,8 +76,6 @@ "@haxtheweb/lrn-math": "^11.0.5", "@haxtheweb/media-image": "^11.0.5", "@haxtheweb/video-player": "^11.0.5", - "@lit-labs/ssr": "3.2.2", - "@lit-labs/virtualizer": "2.1.0", "@open-wc/building-utils": "2.18.4", "@open-wc/demoing-storybook": "2.4.7", "@open-wc/storybook": "0.2.8", @@ -88,9 +86,11 @@ "@webcomponents/webcomponentsjs": "^2.8.0", "concurrently": "9.1.2", "depcheck": "^1.4.7", + "@lit-labs/ssr": "3.3.1", + "@lit-labs/virtualizer": "2.1.1", + "@lit/reactive-element": "2.1.1", "lit": "3.3.1", - "lit-html": "3.3.0", - "@lit/reactive-element": "2.1.0", + "lit-html": "3.3.1", "lunr": "2.3.9", "node-html-parser": "^6.1.13", "patch-package": "8.0.0", @@ -189,10 +189,10 @@ "@rollup/plugin-node-resolve": "16.0.1", "roughjs": "4.4.5", "lit": "3.3.1", - "lit-html": "3.3.0", - "lit-element": "4.2.0", - "@lit/reactive-element": "2.1.0", - "@lit-labs/virtualizer": "2.1.0", + "lit-html": "3.3.1", + "lit-element": "4.2.1", + "@lit-labs/virtualizer": "2.1.1", + "@lit/reactive-element": "2.1.1", "polymer-cli": "1.9.11", "polymer-build": "3.1.4" }, diff --git a/update-devdeps-simple.sh b/update-devdeps-simple.sh deleted file mode 100755 index 272455e4f2..0000000000 --- a/update-devdeps-simple.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash - -# Simple script to replace @haxtheweb/utils with @haxtheweb/demo-snippet in devDependencies -# Get the directory where this script is located -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -ELEMENTS_DIR="${SCRIPT_DIR}/elements" - -echo "🔧 Simple replacement of @haxtheweb/utils with @haxtheweb/demo-snippet in devDependencies" -echo "📂 Working in: $ELEMENTS_DIR" -echo "" - -count=0 -# Find all package.json files and process them -find "$ELEMENTS_DIR" -name "package.json" -not -path "*/node_modules/*" | while read -r file; do - # Check if file contains @haxtheweb/utils in devDependencies section - if grep -A 10 '"devDependencies"' "$file" | grep -q '"@haxtheweb/utils"'; then - echo "📝 Updating: $file" - # Create backup - cp "$file" "${file}.simple_backup" - - # Use sed to replace the specific line - sed -i 's/"@haxtheweb\/utils": "\^11\.0\.0"/"@haxtheweb\/demo-snippet": "^11.0.5"/g' "$file" - - count=$((count + 1)) - fi -done - -echo "" -echo "✅ Processing complete!" -echo "📊 Files processed: Check the output above" -echo "" -echo "🔍 To verify changes:" -echo " find \"$ELEMENTS_DIR\" -name 'package.json' -exec grep -l '@haxtheweb/demo-snippet' {} \\;" \ No newline at end of file diff --git a/update-devdeps.sh b/update-devdeps.sh deleted file mode 100755 index 26ef2010a3..0000000000 --- a/update-devdeps.sh +++ /dev/null @@ -1,66 +0,0 @@ -#!/bin/bash - -# Script to replace @haxtheweb/utils with @haxtheweb/demo-snippet in devDependencies sections only -# This preserves legitimate dependencies on utils while updating devDependencies - -# Get the directory where this script is located -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -ELEMENTS_DIR="${SCRIPT_DIR}/elements" - -echo "🔍 Searching for package.json files with @haxtheweb/utils in devDependencies..." -echo "📂 Working in: $ELEMENTS_DIR" -echo "" - -# Find all package.json files in the elements directory -find "$ELEMENTS_DIR" -name "package.json" -type f | while read -r file; do - echo "📋 Checking: $file" - - # Check if the file contains @haxtheweb/utils in devDependencies section - if grep -A 20 '"devDependencies"' "$file" | grep -q '"@haxtheweb/utils"'; then - echo "✅ Found @haxtheweb/utils in devDependencies of $file" - - # Create a backup - cp "$file" "${file}.backup" - echo "💾 Created backup: ${file}.backup" - - # Use perl for more precise replacement within devDependencies section only - perl -i -pe ' - BEGIN { $in_devdeps = 0; } - - # Track when we enter devDependencies section - if (/"devDependencies"\s*:\s*\{/) { - $in_devdeps = 1; - } - - # Track when we exit devDependencies (end of object) - if ($in_devdeps && /^\s*\}/) { - $in_devdeps = 0; - } - - # Only replace if we are in devDependencies section - if ($in_devdeps && /"@haxtheweb\/utils"/) { - s/"@haxtheweb\/utils":\s*"\^11\.0\.0"/"@haxtheweb\/demo-snippet": "^11.0.5"/g; - print STDERR " 🔄 Replaced utils with demo-snippet in devDependencies\n"; - } - ' "$file" - - echo "✅ Updated $file" - echo "" - else - echo "⏭️ No @haxtheweb/utils in devDependencies found in $file" - fi -done - -echo "" -echo "🎉 Script completed!" -echo "" -echo "📝 Summary of changes:" -echo " - Only devDependencies sections were modified" -echo " - Regular dependencies on @haxtheweb/utils were preserved" -echo " - Backup files created with .backup extension" -echo "" -echo "🔍 To verify changes, you can run:" -echo " find \"$ELEMENTS_DIR\" -name 'package.json' -exec grep -l '@haxtheweb/demo-snippet' {} \;" -echo "" -echo "🔙 To restore from backups if needed:" -echo " find \"$ELEMENTS_DIR\" -name 'package.json.backup' -exec sh -c 'mv \"\$1\" \"\${1%.backup}\"' _ {} \;" From 037c3f6eb5e63ee6da41ac6ea825df8cbf67fc4e Mon Sep 17 00:00:00 2001 From: btopro Date: Thu, 16 Oct 2025 15:00:38 -0400 Subject: [PATCH 133/166] formatting on build --- component-gallery.html | 18 +- .../fill-in-the-blanks/custom-elements.json | 134 +++ elements/github-preview/custom-elements.json | 1036 ----------------- .../matching-question/custom-elements.json | 298 +++++ .../test/matching-question.test.js | 4 +- elements/media-quote/custom-elements.json | 192 +++ .../tagging-question/custom-elements.json | 253 ++++ 7 files changed, 884 insertions(+), 1051 deletions(-) create mode 100644 elements/fill-in-the-blanks/custom-elements.json create mode 100644 elements/matching-question/custom-elements.json create mode 100644 elements/media-quote/custom-elements.json create mode 100644 elements/tagging-question/custom-elements.json diff --git a/component-gallery.html b/component-gallery.html index bb2b910410..4ab614c6eb 100644 --- a/component-gallery.html +++ b/component-gallery.html @@ -370,12 +370,12 @@