From 14dfdf0be5ac36c2cf20ee8839eeaf96d71fae55 Mon Sep 17 00:00:00 2001 From: izzabizz5 Date: Thu, 30 Jan 2025 14:51:19 -0500 Subject: [PATCH 01/97] 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 02/97] 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 03/97] 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 04/97] 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 05/97] 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 06/97] 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 07/97] 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 08/97] 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 09/97] 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 10/97] 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 11/97] 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 12/97] 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 13/97] 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 14/97] 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 15/97] 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 16/97] 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 17/97] 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 18/97] 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 19/97] 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 20/97] 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 21/97] 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 22/97] 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 23/97] 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 24/97] 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 25/97] 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 26/97] 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 27/97] 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 28/97] 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 29/97] 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 30/97] 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 31/97] 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 32/97] 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 33/97] 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 34/97] 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 35/97] 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 36/97] 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 37/97] 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 38/97] 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 39/97] 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 40/97] 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 41/97] 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 42/97] 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 43/97] 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 44/97] 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 45/97] 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 46/97] 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 47/97] 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 48/97] 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 49/97] 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 50/97] 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 51/97] 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 52/97] 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 53/97] 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 54/97] 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 55/97] 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 56/97] 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 57/97] 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 58/97] 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 59/97] 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 60/97] 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 61/97] 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 62/97] 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 63/97] 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 64/97] 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 65/97] 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 66/97] 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 67/97] 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 68/97] 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 69/97] 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 70/97] 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 71/97] 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 72/97] 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 73/97] 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 74/97] 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 75/97] 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 76/97] 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 77/97] 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 79/97] 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 80/97] 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 81/97] 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 82/97] 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 83/97] 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 84/97] 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 85/97] 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 86/97] 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 89/97] 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 90/97] 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 91/97] 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 92/97] 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 93/97] 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 96/97] 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 97/97] 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":