commit 22072f825e11cc176bf79a14685e82b54f208e89
parent 9868bde250bc427fb129970e47f9faf1287fa0c3
Author: triesap <137732411+triesap@users.noreply.github.com>
Date: Wed, 11 Sep 2024 11:30:46 +0000
apps-lib: add input select and notify glyph components, edit input form, edit trellis, add trade locale, add client stores, edit types, edit utils
Diffstat:
14 files changed, 259 insertions(+), 43 deletions(-)
diff --git a/apps-lib/src/lib/components/input_form.svelte b/apps-lib/src/lib/components/input_form.svelte
@@ -1,42 +1,77 @@
<script lang="ts">
- import { kv, type IInputFormBasis } from "$lib";
- import type { ThemeLayer } from "@radroots/theme";
+ import { fmt_cl, Glyph, kv, parse_layer, type IInputFormBasis } from "$lib";
import { onMount } from "svelte";
+ let el: HTMLInputElement | null;
+
export let basis: IInputFormBasis;
$: basis = basis;
- let layer: ThemeLayer = 0;
- $: layer = basis.layer;
-
- let el: HTMLInputElement | null;
-
+ $: layer =
+ typeof basis.layer === `boolean` ? false : parse_layer(basis.layer, 1);
+ $: classes_layer =
+ typeof layer === `boolean`
+ ? `bg-transparent`
+ : `bg-layer-${layer}-surface`;
+ $: classes_wrap = `px-4`;
onMount(async () => {
try {
- if (basis.sync) await $kv.set(basis.id, "");
+ if (basis.sync) {
+ const kv_val = await kv.get(basis.id);
+ if (kv_val) el.value = kv_val;
+ await kv.set(basis.id, kv_val || "");
+ }
} catch (e) {
console.log(`e `, e);
}
});
</script>
-<input
- bind:this={el}
- type="text"
- class={`form-input text-layer-${layer}-glyph placeholder:text-layer-${layer}-glyph_pl placeholder:font-[300] caret-layer-${layer}-glyph`}
- id={basis.id}
- placeholder={basis.placeholder || ""}
- on:input={async ({ currentTarget: el }) => {
- const val = el.value
- .split("")
- .filter((char) => basis.field.charset.test(char))
- .join("");
- if (!basis.field.validate.test(val) && basis.field.validateKeypress)
- el.classList.add(`form-input-invalid`);
- else el.classList.remove("form-entry-invalid");
- el.value = val;
- if (basis.sync) {
- await $kv.set(basis.id, val);
- }
- }}
-/>
+<div
+ class={`${fmt_cl(basis.classes_wrap)} relative form-line-wrap ${classes_wrap} ${classes_layer} transition-all`}
+>
+ <input
+ bind:this={el}
+ type="text"
+ id={basis.id}
+ class={`${fmt_cl(basis.classes)} form-input h-full text-layer-${layer}-glyph placeholder:text-layer-${layer}-glyph_pl caret-layer-${layer}-glyph`}
+ placeholder={basis.placeholder || ""}
+ on:input={async ({ currentTarget: el }) => {
+ let pass = true;
+ const val = el.value
+ .split("")
+ .filter((char) => basis.field.charset.test(char))
+ .join("");
+ if (
+ !basis.field.validate.test(val) &&
+ basis.field.validate_keypress
+ ) {
+ //el.classList.add(`form-invalid-layer-${layer}`);
+ pass = false;
+ } else {
+ //el.classList.remove(`form-invalid-layer-${layer}`);
+ }
+ el.value = val;
+ if (basis.sync) await kv.set(basis.id, val);
+ if (basis.callback) await basis.callback({ val, pass });
+ }}
+ />
+ {#if basis.notify_inline}
+ {#if `glyph` in basis.notify_inline}
+ <div
+ class={`z-5 absolute right-0 top-0 flex flex-row h-full pr-3 justify-end items-center translate-x-[34px] fade-in transition-all`}
+ >
+ <Glyph
+ basis={typeof basis.notify_inline.glyph === `string`
+ ? {
+ key: basis.notify_inline.glyph,
+ dim: `xs+`,
+ weight: `bold`,
+ classes: `text-layer-${layer}-glyph`,
+ }
+ : basis.notify_inline.glyph}
+ />
+ </div>
+ {/if}
+ {/if}
+</div>
diff --git a/apps-lib/src/lib/components/input_select.svelte b/apps-lib/src/lib/components/input_select.svelte
@@ -0,0 +1,78 @@
+<script lang="ts">
+ import {
+ fmt_cl,
+ type IInputSelectBasis,
+ kv,
+ Loading,
+ parse_layer,
+ } from "$lib";
+ import Glyph from "$lib/ui/glyph.svelte";
+ import { onMount } from "svelte";
+
+ let el: HTMLSelectElement | null;
+
+ export let value: string;
+ export let basis: IInputSelectBasis;
+ $: basis = basis;
+
+ $: layer =
+ typeof basis.layer === `boolean` ? false : parse_layer(basis.layer, 1);
+ $: classes_layer =
+ typeof layer === `boolean`
+ ? `bg-transparent`
+ : `bg-layer-${layer}-surface`;
+ $: classes_wrap = typeof layer === `boolean` ? `` : `px-4`;
+
+ onMount(async () => {
+ try {
+ if (basis.sync) await kv.set(basis.id, basis.options[0].value);
+ } catch (e) {
+ console.log(`e `, e);
+ }
+ });
+</script>
+
+<div
+ class={`${fmt_cl(basis.classes_wrap)} relative form-line-wrap ${classes_wrap} ${classes_layer} transition-all`}
+>
+ {#if basis.loading}
+ <div class={`flex flex-row w-full justify-center items-center`}>
+ <Loading basis={{ dim: `xs-` }} />
+ </div>
+ {:else}
+ <select
+ bind:this={el}
+ bind:value
+ class={`${fmt_cl(basis.classes)} z-10 form-select form-line-select text-layer-${layer}-glyph`}
+ on:change={async ({ currentTarget: el }) => {
+ const val = el.value;
+ if (basis.sync) await kv.set(basis.id, val);
+ if (basis.callback) await basis.callback(val);
+ }}
+ >
+ {#each basis.options as opt}
+ <option
+ value={opt.value}
+ disabled={!!opt.disabled}
+ selected={!!opt.selected}
+ >
+ {opt.label || opt.value}
+ </option>
+ {/each}
+ </select>
+ {/if}
+ {#if !basis.hide_arrows}
+ <div
+ class={`z-5 absolute right-0 top-0 flex flex-row h-full pr-3 justify-end items-center`}
+ >
+ <Glyph
+ basis={{
+ key: `caret-up-down`,
+ dim: `xs`,
+ weight: `bold`,
+ classes: `text-layer-${layer}-glyph`,
+ }}
+ />
+ </div>
+ {/if}
+</div>
diff --git a/apps-lib/src/lib/components/notify_glyph.svelte b/apps-lib/src/lib/components/notify_glyph.svelte
@@ -0,0 +1,24 @@
+<script lang="ts">
+ import { Glyph, type GlyphKey, type IGlyph } from "$lib";
+ import type { ThemeLayer } from "@radroots/theme";
+
+ export let basis: {
+ glyph: GlyphKey | IGlyph;
+ layer: ThemeLayer;
+ };
+</script>
+
+<div
+ class={`z-5 absolute right-0 top-0 flex flex-row h-full pr-3 justify-end items-center translate-x-[34px] fade-in transition-all`}
+>
+ <Glyph
+ basis={typeof basis.glyph === `string`
+ ? {
+ key: basis.glyph,
+ dim: `xs+`,
+ weight: `bold`,
+ classes: `text-layer-${basis.layer}-glyph`,
+ }
+ : basis.glyph}
+ />
+</div>
diff --git a/apps-lib/src/lib/components/trellis.svelte b/apps-lib/src/lib/components/trellis.svelte
@@ -5,7 +5,7 @@
import TrellisTitle from "./trellis_title.svelte";
import TrellisTouch from "./trellis_touch.svelte";
- const class_rounded = `xl`;
+ const class_rounded = `2xl`;
export let basis: { args: ITrellis };
$: ({ args } = basis);
@@ -96,4 +96,4 @@
</div>
{/if}
</div>
-<div class={`hidden rounded-xl first:rounded-t-xl last:rounded-b-xl`}></div>
+<div class={`hidden rounded-2xl first:rounded-t-2xl last:rounded-b-2xl`}></div>
diff --git a/apps-lib/src/lib/components/trellis_touch.svelte b/apps-lib/src/lib/components/trellis_touch.svelte
@@ -14,7 +14,7 @@
<div class={`flex flex-row flex-grow overflow-x-hidden`}>
<div
- class={`${fmt_trellis(hide_border_b, hide_border_t)} flex flex-row h-full w-full justify-center items-center border-t-line border-layer-${layer}-surface-edge transition-all`}
+ class={`${fmt_trellis(hide_border_b, hide_border_t)} flex flex-row h-full w-full justify-center items-center border-t-line border-layer-${layer}-surface-edge/40 transition-all`}
>
<button
class={`relative group flex flex-row h-line w-full pr-[2px] justify-between items-center transition-all`}
diff --git a/apps-lib/src/lib/index.ts b/apps-lib/src/lib/index.ts
@@ -2,8 +2,10 @@ export * from "./locales/i18n"
export { default as Envelope } from "./components/envelope.svelte"
export { default as EnvelopeTitled } from "./components/envelope_titled.svelte"
export { default as InputForm } from "./components/input_form.svelte"
+export { default as InputSelect } from "./components/input_select.svelte"
export { default as LoadingView } from "./components/loading_view.svelte"
export { default as Nav } from "./components/nav.svelte"
+export { default as NotifyGlyph } from "./components/notify_glyph.svelte"
export { default as Tabs } from "./components/tabs.svelte"
export { default as Trellis } from "./components/trellis.svelte"
export { default as TrellisDefaultLabel } from "./components/trellis_default_label.svelte"
diff --git a/apps-lib/src/lib/locales/en/common.json b/apps-lib/src/lib/locales/en/common.json
@@ -1,4 +1,7 @@
{
+ "other": "Other",
+ "add_new_location": "Add new location",
+ "no_locations_saved": "No locations saved",
"no_items_to_display": "No items to display",
"cancel": "Cancel",
"add": "Add"
diff --git a/apps-lib/src/lib/locales/en/trade.json b/apps-lib/src/lib/locales/en/trade.json
@@ -0,0 +1,37 @@
+{
+ "quantity": {
+ "mass_unit": {
+ "g": "Gram",
+ "g_pl": "Grams",
+ "g_ab": "g.",
+ "hg": "100 Gram",
+ "hg_pl": "100 Grams",
+ "hg_ab": "100g.",
+ "kg": "Kilogram",
+ "kg_pl": "Kilograms",
+ "kg_ab": "kg.",
+ "lb": "Pound",
+ "lb_pl": "Pounds",
+ "lb_ab": "lb."
+ }
+ },
+ "currency": {
+ "usd": {
+ "symbol": "$",
+ "name": "United States Dollar",
+ "name_short": "U.S. Dollar"
+ },
+ "eur": {
+ "symbol": "€",
+ "name": "Euro",
+ "name_short": "Euro"
+ }
+ },
+ "product": {
+ "key": {
+ "coffee": "Coffee",
+ "cacao": "Cacao",
+ "maca": "Maca"
+ }
+ }
+}
+\ No newline at end of file
diff --git a/apps-lib/src/lib/locales/i18n.ts b/apps-lib/src/lib/locales/i18n.ts
@@ -7,7 +7,7 @@ type LanguageConfig = {
default?: string;
};
-const locales_files = [`app`, `common`] as const;
+const locales_files = [`app`, `common`, `trade`] as const;
const translations_keys: Record<Locale, any> = {
en: { locales_keys },
};
diff --git a/apps-lib/src/lib/stores/client.ts b/apps-lib/src/lib/stores/client.ts
@@ -4,8 +4,11 @@ import { writable } from "svelte/store";
export const app_qp = queryParameters();
-export const kv = writable<Keyva>();
-if (typeof window !== 'undefined') kv.set(new Keyva({ name: 'app-kv' }));
+//export const kv = writable<Keyva>();
+//if (typeof window !== 'undefined') kv.set(new Keyva({ name: 'app-kv' }));
+
+export let kv: Keyva;
+if (typeof window !== 'undefined') kv = new Keyva({ name: 'app-kv' });
export const app_layout = writable<AppLayoutKey>(`base`);
diff --git a/apps-lib/src/lib/types/client.ts b/apps-lib/src/lib/types/client.ts
@@ -27,7 +27,9 @@ export type GeometryGlyphDimension =
| `${GeometryDimension}+`;
+//export type CallbackPromiseGenericReturn<T1, T2> = (value: T1) => Promise<T2>;
export type CallbackPromiseGeneric<T> = (value: T) => Promise<void>;
+//export type CallbackPromiseReturn<T> = () => Promise<T>;
export type CallbackPromise = () => Promise<void>;
export type NavigationRoute = string; //@todo
@@ -72,6 +74,14 @@ export type ILyOpt = {
layer?: ThemeLayer;
};
+export type ILyTs = {
+ layer: ThemeLayer | false;
+};
+
+export type ILyOptTs = {
+ layer?: ThemeLayer | false;
+};
+
export type IGl = {
glyph: IGlyph;
}
diff --git a/apps-lib/src/lib/types/components.ts b/apps-lib/src/lib/types/components.ts
@@ -1,5 +1,5 @@
-import type { CallbackPromise, CallbackPromiseGeneric, ICb, IClOpt, IGl, IGlOpt, ILabelFieldsOpt, ILabelOpt, ILabelOptFieldsOpt, ILy, ILyOpt } from "./client";
-import type { GlyphKey, GlyphWeight } from "./ui";
+import type { CallbackPromise, CallbackPromiseGeneric, ICb, ICbGOpt, IClOpt, IGl, IGlOpt, ILabelFieldsOpt, ILabelOpt, ILabelOptFieldsOpt, ILyOpt, ILyOptTs } from "./client";
+import type { GlyphKey, GlyphWeight, IGlyph } from "./ui";
export type ITabsBasisList = {
icon: GlyphKey;
@@ -19,19 +19,42 @@ export type ITabsBasis = {
export type IFormField = {
validate: RegExp;
charset: RegExp;
- validateKeypress?: boolean;
+ validate_keypress?: boolean;
};
-export type IInputFormBasis = IClOpt & ILy & {
+export type IInputFormBasis = IClOpt & ILyOptTs & ICbGOpt<{ val: string; pass: boolean; }> & {
+ classes_wrap?: string;
id: string;
placeholder?: string;
label?: string;
hidden?: boolean;
validate?: RegExp;
sync?: boolean;
- field: IFormField
+ field: IFormField;
+ notify_inline?: {
+ glyph: GlyphKey | IGlyph;
+ };
+};
+
+export type IInputSelectBasisOption = {
+ value: string;
+ label?: string;
+ disabled?: boolean;
+ selected?: boolean;
};
+export type IInputSelectBasis = IClOpt & ILyOptTs & ICbGOpt<string> & {
+ classes_wrap?: string;
+ id: string;
+ label?: string;
+ hidden?: boolean;
+ hide_arrows?: boolean;
+ sync?: boolean;
+ loading?: boolean;
+ options: IInputSelectBasisOption[];
+};
+
+
export type IEnvelopeBasis = ILyOpt &
IClOpt & IEnvelopeKind & {
visible: boolean;
diff --git a/apps-lib/src/lib/ui/css_static.svelte b/apps-lib/src/lib/ui/css_static.svelte
@@ -1 +1 @@
-<div class="hidden bg-layer-0-surface active:bg-layer-0-surface group-active:bg-layer-0-surface focus:bg-layer-0-surface group-focus:bg-layer-0-surface border-layer-0-surface active:border-layer-0-surface group-active:border-layer-0-surface focus:border-layer-0-surface group-focus:border-layer-0-surface bg-layer-0-surface_a active:bg-layer-0-surface_a group-active:bg-layer-0-surface_a focus:bg-layer-0-surface_a group-focus:bg-layer-0-surface_a border-layer-0-surface_a active:border-layer-0-surface_a group-active:border-layer-0-surface_a focus:border-layer-0-surface_a group-focus:border-layer-0-surface_a bg-layer-0-surface-edge active:bg-layer-0-surface-edge group-active:bg-layer-0-surface-edge focus:bg-layer-0-surface-edge group-focus:bg-layer-0-surface-edge border-layer-0-surface-edge active:border-layer-0-surface-edge group-active:border-layer-0-surface-edge focus:border-layer-0-surface-edge group-focus:border-layer-0-surface-edge bg-layer-0-surface-blur active:bg-layer-0-surface-blur group-active:bg-layer-0-surface-blur focus:bg-layer-0-surface-blur group-focus:bg-layer-0-surface-blur border-layer-0-surface-blur active:border-layer-0-surface-blur group-active:border-layer-0-surface-blur focus:border-layer-0-surface-blur group-focus:border-layer-0-surface-blur bg-layer-1-surface active:bg-layer-1-surface group-active:bg-layer-1-surface focus:bg-layer-1-surface group-focus:bg-layer-1-surface border-layer-1-surface active:border-layer-1-surface group-active:border-layer-1-surface focus:border-layer-1-surface group-focus:border-layer-1-surface bg-layer-1-surface_a active:bg-layer-1-surface_a group-active:bg-layer-1-surface_a focus:bg-layer-1-surface_a group-focus:bg-layer-1-surface_a border-layer-1-surface_a active:border-layer-1-surface_a group-active:border-layer-1-surface_a focus:border-layer-1-surface_a group-focus:border-layer-1-surface_a bg-layer-1-surface-edge active:bg-layer-1-surface-edge group-active:bg-layer-1-surface-edge focus:bg-layer-1-surface-edge group-focus:bg-layer-1-surface-edge border-layer-1-surface-edge active:border-layer-1-surface-edge group-active:border-layer-1-surface-edge focus:border-layer-1-surface-edge group-focus:border-layer-1-surface-edge bg-layer-2-surface active:bg-layer-2-surface group-active:bg-layer-2-surface focus:bg-layer-2-surface group-focus:bg-layer-2-surface border-layer-2-surface active:border-layer-2-surface group-active:border-layer-2-surface focus:border-layer-2-surface group-focus:border-layer-2-surface bg-layer-2-surface_a active:bg-layer-2-surface_a group-active:bg-layer-2-surface_a focus:bg-layer-2-surface_a group-focus:bg-layer-2-surface_a border-layer-2-surface_a active:border-layer-2-surface_a group-active:border-layer-2-surface_a focus:border-layer-2-surface_a group-focus:border-layer-2-surface_a bg-layer-2-surface-edge active:bg-layer-2-surface-edge group-active:bg-layer-2-surface-edge focus:bg-layer-2-surface-edge group-focus:bg-layer-2-surface-edge border-layer-2-surface-edge active:border-layer-2-surface-edge group-active:border-layer-2-surface-edge focus:border-layer-2-surface-edge group-focus:border-layer-2-surface-edge text-layer-0-glyph active:text-layer-0-glyph group-active:text-layer-0-glyph focus:text-layer-0-glyph group-focus:text-layer-0-glyph text-layer-0-glyph_a active:text-layer-0-glyph_a group-active:text-layer-0-glyph_a focus:text-layer-0-glyph_a group-focus:text-layer-0-glyph_a text-layer-0-glyph-hl active:text-layer-0-glyph-hl group-active:text-layer-0-glyph-hl focus:text-layer-0-glyph-hl group-focus:text-layer-0-glyph-hl text-layer-0-glyph-hl_a active:text-layer-0-glyph-hl_a group-active:text-layer-0-glyph-hl_a focus:text-layer-0-glyph-hl_a group-focus:text-layer-0-glyph-hl_a text-layer-0-glyph-shade active:text-layer-0-glyph-shade group-active:text-layer-0-glyph-shade focus:text-layer-0-glyph-shade group-focus:text-layer-0-glyph-shade text-layer-0-glyph-label active:text-layer-0-glyph-label group-active:text-layer-0-glyph-label focus:text-layer-0-glyph-label group-focus:text-layer-0-glyph-label text-layer-1-glyph active:text-layer-1-glyph group-active:text-layer-1-glyph focus:text-layer-1-glyph group-focus:text-layer-1-glyph text-layer-1-glyph_a active:text-layer-1-glyph_a group-active:text-layer-1-glyph_a focus:text-layer-1-glyph_a group-focus:text-layer-1-glyph_a text-layer-1-glyph_pl active:text-layer-1-glyph_pl group-active:text-layer-1-glyph_pl focus:text-layer-1-glyph_pl group-focus:text-layer-1-glyph_pl text-layer-1-glyph-hl active:text-layer-1-glyph-hl group-active:text-layer-1-glyph-hl focus:text-layer-1-glyph-hl group-focus:text-layer-1-glyph-hl text-layer-1-glyph-hl_a active:text-layer-1-glyph-hl_a group-active:text-layer-1-glyph-hl_a focus:text-layer-1-glyph-hl_a group-focus:text-layer-1-glyph-hl_a text-layer-1-glyph-shade active:text-layer-1-glyph-shade group-active:text-layer-1-glyph-shade focus:text-layer-1-glyph-shade group-focus:text-layer-1-glyph-shade text-layer-1-glyph-label active:text-layer-1-glyph-label group-active:text-layer-1-glyph-label focus:text-layer-1-glyph-label group-focus:text-layer-1-glyph-label text-layer-2-glyph active:text-layer-2-glyph group-active:text-layer-2-glyph focus:text-layer-2-glyph group-focus:text-layer-2-glyph text-layer-2-glyph_a active:text-layer-2-glyph_a group-active:text-layer-2-glyph_a focus:text-layer-2-glyph_a group-focus:text-layer-2-glyph_a text-layer-2-glyph_pl active:text-layer-2-glyph_pl group-active:text-layer-2-glyph_pl focus:text-layer-2-glyph_pl group-focus:text-layer-2-glyph_pl text-layer-2-glyph-hl active:text-layer-2-glyph-hl group-active:text-layer-2-glyph-hl focus:text-layer-2-glyph-hl group-focus:text-layer-2-glyph-hl text-layer-2-glyph-hl_a active:text-layer-2-glyph-hl_a group-active:text-layer-2-glyph-hl_a focus:text-layer-2-glyph-hl_a group-focus:text-layer-2-glyph-hl_a text-layer-2-glyph-shade active:text-layer-2-glyph-shade group-active:text-layer-2-glyph-shade focus:text-layer-2-glyph-shade group-focus:text-layer-2-glyph-shade"></div>
+<div class="hidden bg-layer-0-surface active:bg-layer-0-surface group-active:bg-layer-0-surface focus:bg-layer-0-surface group-focus:bg-layer-0-surface border-layer-0-surface active:border-layer-0-surface group-active:border-layer-0-surface focus:border-layer-0-surface group-focus:border-layer-0-surface bg-layer-0-surface_a active:bg-layer-0-surface_a group-active:bg-layer-0-surface_a focus:bg-layer-0-surface_a group-focus:bg-layer-0-surface_a border-layer-0-surface_a active:border-layer-0-surface_a group-active:border-layer-0-surface_a focus:border-layer-0-surface_a group-focus:border-layer-0-surface_a bg-layer-0-surface-edge active:bg-layer-0-surface-edge group-active:bg-layer-0-surface-edge focus:bg-layer-0-surface-edge group-focus:bg-layer-0-surface-edge border-layer-0-surface-edge active:border-layer-0-surface-edge group-active:border-layer-0-surface-edge focus:border-layer-0-surface-edge group-focus:border-layer-0-surface-edge bg-layer-0-surface-blur active:bg-layer-0-surface-blur group-active:bg-layer-0-surface-blur focus:bg-layer-0-surface-blur group-focus:bg-layer-0-surface-blur border-layer-0-surface-blur active:border-layer-0-surface-blur group-active:border-layer-0-surface-blur focus:border-layer-0-surface-blur group-focus:border-layer-0-surface-blur bg-layer-1-surface active:bg-layer-1-surface group-active:bg-layer-1-surface focus:bg-layer-1-surface group-focus:bg-layer-1-surface border-layer-1-surface active:border-layer-1-surface group-active:border-layer-1-surface focus:border-layer-1-surface group-focus:border-layer-1-surface bg-layer-1-surface_a active:bg-layer-1-surface_a group-active:bg-layer-1-surface_a focus:bg-layer-1-surface_a group-focus:bg-layer-1-surface_a border-layer-1-surface_a active:border-layer-1-surface_a group-active:border-layer-1-surface_a focus:border-layer-1-surface_a group-focus:border-layer-1-surface_a bg-layer-1-surface-edge active:bg-layer-1-surface-edge group-active:bg-layer-1-surface-edge focus:bg-layer-1-surface-edge group-focus:bg-layer-1-surface-edge border-layer-1-surface-edge active:border-layer-1-surface-edge group-active:border-layer-1-surface-edge focus:border-layer-1-surface-edge group-focus:border-layer-1-surface-edge bg-layer-1-surface-err active:bg-layer-1-surface-err group-active:bg-layer-1-surface-err focus:bg-layer-1-surface-err group-focus:bg-layer-1-surface-err border-layer-1-surface-err active:border-layer-1-surface-err group-active:border-layer-1-surface-err focus:border-layer-1-surface-err group-focus:border-layer-1-surface-err bg-layer-2-surface active:bg-layer-2-surface group-active:bg-layer-2-surface focus:bg-layer-2-surface group-focus:bg-layer-2-surface border-layer-2-surface active:border-layer-2-surface group-active:border-layer-2-surface focus:border-layer-2-surface group-focus:border-layer-2-surface bg-layer-2-surface_a active:bg-layer-2-surface_a group-active:bg-layer-2-surface_a focus:bg-layer-2-surface_a group-focus:bg-layer-2-surface_a border-layer-2-surface_a active:border-layer-2-surface_a group-active:border-layer-2-surface_a focus:border-layer-2-surface_a group-focus:border-layer-2-surface_a bg-layer-2-surface-edge active:bg-layer-2-surface-edge group-active:bg-layer-2-surface-edge focus:bg-layer-2-surface-edge group-focus:bg-layer-2-surface-edge border-layer-2-surface-edge active:border-layer-2-surface-edge group-active:border-layer-2-surface-edge focus:border-layer-2-surface-edge group-focus:border-layer-2-surface-edge text-layer-0-glyph active:text-layer-0-glyph group-active:text-layer-0-glyph focus:text-layer-0-glyph group-focus:text-layer-0-glyph text-layer-0-glyph_a active:text-layer-0-glyph_a group-active:text-layer-0-glyph_a focus:text-layer-0-glyph_a group-focus:text-layer-0-glyph_a text-layer-0-glyph-hl active:text-layer-0-glyph-hl group-active:text-layer-0-glyph-hl focus:text-layer-0-glyph-hl group-focus:text-layer-0-glyph-hl text-layer-0-glyph-hl_a active:text-layer-0-glyph-hl_a group-active:text-layer-0-glyph-hl_a focus:text-layer-0-glyph-hl_a group-focus:text-layer-0-glyph-hl_a text-layer-0-glyph-shade active:text-layer-0-glyph-shade group-active:text-layer-0-glyph-shade focus:text-layer-0-glyph-shade group-focus:text-layer-0-glyph-shade text-layer-0-glyph-label active:text-layer-0-glyph-label group-active:text-layer-0-glyph-label focus:text-layer-0-glyph-label group-focus:text-layer-0-glyph-label text-layer-1-glyph active:text-layer-1-glyph group-active:text-layer-1-glyph focus:text-layer-1-glyph group-focus:text-layer-1-glyph text-layer-1-glyph_a active:text-layer-1-glyph_a group-active:text-layer-1-glyph_a focus:text-layer-1-glyph_a group-focus:text-layer-1-glyph_a text-layer-1-glyph_pl active:text-layer-1-glyph_pl group-active:text-layer-1-glyph_pl focus:text-layer-1-glyph_pl group-focus:text-layer-1-glyph_pl text-layer-1-glyph-hl active:text-layer-1-glyph-hl group-active:text-layer-1-glyph-hl focus:text-layer-1-glyph-hl group-focus:text-layer-1-glyph-hl text-layer-1-glyph-hl_a active:text-layer-1-glyph-hl_a group-active:text-layer-1-glyph-hl_a focus:text-layer-1-glyph-hl_a group-focus:text-layer-1-glyph-hl_a text-layer-1-glyph-shade active:text-layer-1-glyph-shade group-active:text-layer-1-glyph-shade focus:text-layer-1-glyph-shade group-focus:text-layer-1-glyph-shade text-layer-1-glyph-label active:text-layer-1-glyph-label group-active:text-layer-1-glyph-label focus:text-layer-1-glyph-label group-focus:text-layer-1-glyph-label text-layer-2-glyph active:text-layer-2-glyph group-active:text-layer-2-glyph focus:text-layer-2-glyph group-focus:text-layer-2-glyph text-layer-2-glyph_a active:text-layer-2-glyph_a group-active:text-layer-2-glyph_a focus:text-layer-2-glyph_a group-focus:text-layer-2-glyph_a text-layer-2-glyph_pl active:text-layer-2-glyph_pl group-active:text-layer-2-glyph_pl focus:text-layer-2-glyph_pl group-focus:text-layer-2-glyph_pl text-layer-2-glyph-hl active:text-layer-2-glyph-hl group-active:text-layer-2-glyph-hl focus:text-layer-2-glyph-hl group-focus:text-layer-2-glyph-hl text-layer-2-glyph-hl_a active:text-layer-2-glyph-hl_a group-active:text-layer-2-glyph-hl_a focus:text-layer-2-glyph-hl_a group-focus:text-layer-2-glyph-hl_a text-layer-2-glyph-shade active:text-layer-2-glyph-shade group-active:text-layer-2-glyph-shade focus:text-layer-2-glyph-shade group-focus:text-layer-2-glyph-shade"></div>
diff --git a/apps-lib/src/lib/utils/client.ts b/apps-lib/src/lib/utils/client.ts
@@ -65,9 +65,9 @@ export function time_now_ms(): number {
return Math.floor(new Date().getTime() / 1000);
};
-export const fmt_id = (id: string): string => {
- const pref = location.pathname.slice(1, -1).replaceAll(`-`, `_`).replaceAll(`/`, `-`).replaceAll(`--`, `-`)
- return `${pref}-${id}`
+export const fmt_id = (id?: string): string => {
+ const pref = location.pathname.slice(1, -1).replaceAll(`-`, `_`).replaceAll(`/`, `-`).replaceAll(`--`, `-`);
+ return `${pref}${id ? `-${id}` : ``}`
};
export const fmt_capitalize = (val: string): string => {