commit f1bb73fc7c3ffcfb51be7f987a043ef75c749257
parent d58bc3e68e4a5bf701c1a0bc07abbeb341b476fd
Author: triesap <137732411+triesap@users.noreply.github.com>
Date: Thu, 7 Aug 2025 17:11:20 +0000
apps-lib: restructure library modules
Diffstat:
137 files changed, 215 insertions(+), 8576 deletions(-)
diff --git a/apps-lib/.gitignore b/apps-lib/.gitignore
@@ -1,40 +1,37 @@
-# dependencies
node_modules
-.pnp
-.pnp.js
-
-# testing
-coverage
-
-# svelte
-.svelte-kit
-
-# misc
-.DS_Store
-*.pem
-
-# debug
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-
-# turbo
-.turbo
-
# Output
.output
+.vercel
+.netlify
+.wrangler
+/.svelte-kit
/build
dist
+.turbo
-# local env files
-.env*
-!.env.example
+# OS
+.DS_Store
+Thumbs.db
+# Env
+.env
+.env.*
+!.env.example
+!.env.test
# Vite
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
+vite.config.dev*
+
+# debug
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# secrets
+*.pem
# local
.tmp*
@@ -43,5 +40,6 @@ vite.config.ts.timestamp-*
.vscode
notes*.txt
notes*.md
-git-diff.txt
+notes*.json
+git-diff*.txt
justfile
diff --git a/apps-lib/package.json b/apps-lib/package.json
@@ -1,13 +1,14 @@
{
- "name": "@radroots/lib-app",
+ "name": "@radroots/apps-lib",
"version": "0.0.0",
"private": true,
"license": "GPLv3",
"scripts": {
"dev": "svelte-package -w",
- "prebuild": "npm run check",
+ "prebuild": "npm run clean && npm run check",
"build": "svelte-package",
"preview": "vite preview",
+ "clean": "rimraf dist && rimraf tsconfig.tsbuildinfo",
"prepare": "svelte-kit sync || echo ''",
"prepack": "svelte-kit sync && svelte-package && publint",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
@@ -31,33 +32,35 @@
}
},
"peerDependencies": {
- "@sveltejs/kit": "^2.16.0",
+ "@sveltejs/kit": "^2.22.0",
"svelte": "^5.0.0"
},
"devDependencies": {
"@sveltejs/adapter-auto": "^4.0.0",
- "@sveltejs/kit": "^2.16.0",
+ "@sveltejs/kit": "^2.22.0",
"@sveltejs/package": "^2.0.0",
- "@sveltejs/vite-plugin-svelte": "^5.0.0",
+ "@sveltejs/vite-plugin-svelte": "^6.0.0",
"@types/node": "^22.5.0",
"publint": "^0.3.2",
"svelte": "^5.0.0",
"svelte-check": "^4.0.0",
"typescript": "5.8.3",
- "vite": "^6.0.0"
+ "vite": "7.0.6"
},
"dependencies": {
- "@nostr-dev-kit/ndk": "^2.11.0",
- "@nostr-dev-kit/ndk-cache-dexie": "^2.5.9",
- "@nostr-dev-kit/ndk-svelte": "^2.4.0",
"@radroots/locales": "*",
+ "@radroots/utils": "*",
"@radroots/utils-nostr": "*",
"@radroots/radroots-common-bindings": "*",
- "@radroots/theme": "*",
- "@radroots/util": "*",
+ "@nostr-dev-kit/ndk": "2.14.33",
+ "@nostr-dev-kit/ndk-cache-dexie": "2.6.34",
+ "@nostr-dev-kit/ndk-svelte": "2.4.38",
+ "@sveltekit-i18n/base": "^1.3.7",
+ "@sveltekit-i18n/parser-icu": "^1.0.8",
"luxon": "^3.5.0",
- "svelte-maplibre": "1.0.0-next.12",
+ "sveltekit-i18n": "^2.4.2",
+ "svelte-maplibre": "1.2.0",
"sveltekit-search-params": "^3.0.0",
- "zod": "^3.23.8"
+ "zod": "^4.0.5"
}
}
\ No newline at end of file
diff --git a/apps-lib/src/lib/components/button/button-horizontal-pair-slide.svelte b/apps-lib/src/lib/components/button/button-horizontal-pair-slide.svelte
@@ -1,45 +0,0 @@
-<script lang="ts">
- import { Empty } from "$root";
-
- let {
- basis,
- toggle = $bindable(false),
- }: {
- basis: {
- label_l: string;
- label_r: string;
- };
- toggle: boolean;
- } = $props();
-</script>
-
-<button
- class={`group relative flex flex-row h-[38px] w-full justify-between items-center rounded-touch bg-layer-2-surface`}
- onclick={async () => {
- toggle = !toggle;
- }}
->
- <div
- class={`z-10 flex flex-row h-full basis-1/2 justify-center items-center bg-transparent`}
- >
- <p
- class={`font-sans font-[400] text-[16px] tracking-wide ${!toggle ? `text-white/60` : `text-layer-0-glyph`} el-re`}
- >
- {basis.label_l}
- </p>
- </div>
- <div
- class={`z-10 flex flex-row h-full basis-1/2 justify-center items-center bg-transparent`}
- >
- <p
- class={`font-sans font-[400] text-[16px] tracking-wide ${toggle ? `text-white/60` : `text-layer-0-glyph`} el-re`}
- >
- {basis.label_r}
- </p>
- </div>
- <div
- class={`z-5 absolute top-0 bottom-0 flex flex-row h-full w-[50%] justify-center items-center rounded-touch bg-th-black transition-all duration-[400ms] ${toggle ? `translate-x-full` : `translate-x-0`}`}
- >
- <Empty />
- </div>
-</button>
diff --git a/apps-lib/src/lib/components/button/button-label-dashed.svelte b/apps-lib/src/lib/components/button/button-label-dashed.svelte
@@ -1,24 +0,0 @@
-<script lang="ts">
- import { type ICb } from "$root";
-
- let {
- basis,
- }: {
- basis: ICb & {
- label: string;
- };
- } = $props();
-</script>
-
-<button
- class={`flex flex-row h-line_button w-full justify-center items-center`}
- onclick={async () => {
- await basis.callback();
- }}
->
- <p
- class={`font-sans font-[500] text-lg text-layer-0-glyph-hl tracking-wide`}
- >
- {`- ${basis.label} -`}
- </p>
-</button>
diff --git a/apps-lib/src/lib/components/button/button-label-glyph.svelte b/apps-lib/src/lib/components/button/button-label-glyph.svelte
@@ -1,42 +0,0 @@
-<script lang="ts">
- import { Glyph, type ICb } from "$root";
- import { type GlyphKey } from "@radroots/util";
- import type { Snippet } from "svelte";
-
- let {
- basis,
- children,
- }: {
- basis: ICb & {
- label: string;
- glyph?: GlyphKey;
- ring?: boolean;
- };
- children?: Snippet;
- } = $props();
-</script>
-
-<div class={`flex flex-col w-full gap-1 justify-center items-center`}>
- <button
- class={`flex flex-row h-12 w-12 p-2 justify-center items-center rounded-2xl bg-layer-1-surface ${basis.ring ? `ring-[4px] ring-layer-2-surface/40` : ``} el-re`}
- onclick={async () => {
- await basis.callback();
- }}
- >
- {#if basis.glyph}
- <Glyph
- basis={{
- classes: `text-layer-0-glyph/80`,
- dim: `sm`,
-
- key: basis.glyph,
- }}
- />
- {:else if children}
- {@render children()}
- {/if}
- </button>
- <p class={`font-sans font-[400] text-sm text-layer-0-glyph el-re`}>
- {basis.label}
- </p>
-</div>
diff --git a/apps-lib/src/lib/components/button/button-layout-pair.svelte b/apps-lib/src/lib/components/button/button-layout-pair.svelte
@@ -1,65 +0,0 @@
-<script lang="ts">
- import {
- app_lo,
- ButtonLayout,
- Empty,
- type IClOpt,
- type IDisabledOpt,
- type ILoadingOpt,
- } from "$root";
- import { fmt_cl, type CallbackPromise } from "@radroots/util";
-
- let {
- basis,
- }: {
- basis: IClOpt & {
- continue: IDisabledOpt &
- ILoadingOpt & {
- label: string;
- callback: CallbackPromise;
- };
- back?: IDisabledOpt & {
- visible: boolean;
- label?: string;
- callback: CallbackPromise;
- };
- };
- } = $props();
-</script>
-
-<div
- class={`${fmt_cl(basis.classes)} flex flex-col gap-1 justify-center items-center ${basis?.back?.visible ? `-translate-y-8` : ``} el-re`}
->
- <ButtonLayout
- basis={{
- disabled: basis.continue.disabled,
- label: basis.continue.label,
- callback: basis.continue.callback,
- }}
- />
- {#if basis.back}
- <div class={`flex flex-col justify-center items-center el-re`}>
- {#if basis.back.visible}
- <button
- class={`group flex flex-row h-12 w-lo_${$app_lo} justify-center items-center fade-in el-re`}
- onclick={async (ev) => {
- ev.stopPropagation();
- if (!basis.back?.disabled) await basis.back?.callback();
- }}
- >
- <p
- class={`font-sans font-[600] tracking-wide text-layer-1-glyph-shade ${basis.back?.disabled ? `` : `group-active:text-layer-1-glyph/40`} el-re`}
- >
- {basis.back.label || ``}
- </p>
- </button>
- {:else}
- <div
- class={`flex flex-row h-4 w-full justify-start items-center`}
- >
- <Empty />
- </div>
- {/if}
- </div>
- {/if}
-</div>
diff --git a/apps-lib/src/lib/components/button/button-layout.svelte b/apps-lib/src/lib/components/button/button-layout.svelte
@@ -1,51 +0,0 @@
-<script lang="ts">
- import {
- app_lo,
- LoadSymbol,
- type IClOpt,
- type IDisabledOpt,
- type ILoadingOpt,
- type ILyOpt,
- } from "$root";
- import { fmt_cl, parse_layer, type CallbackPromise } from "@radroots/util";
-
- let {
- basis,
- }: {
- basis: ILyOpt &
- IClOpt &
- IDisabledOpt &
- ILoadingOpt & {
- classes_inner?: string;
- hide_active?: boolean;
- label: string;
- callback: CallbackPromise;
- };
- } = $props();
-
- const layer = $derived(parse_layer(basis.layer, 1));
-
- const classes_active = $derived(
- !basis.hide_active
- ? `layer-1-active-surface layer-1-active-raise-less layer-1-active-ring-less`
- : ``,
- );
-</script>
-
-<button
- class={`${fmt_cl(basis.classes)} group flex flex-row h-touch_guide w-lo_${$app_lo} justify-center items-center bg-layer-${layer}-surface rounded-touch ${basis.disabled ? `opacity-60` : classes_active} el-re`}
- onclick={async (ev) => {
- ev.stopPropagation();
- if (!basis.disabled) await basis.callback();
- }}
->
- {#if basis.loading}
- <LoadSymbol basis={{ dim: `md` }} />
- {:else}
- <p
- class={`${fmt_cl(basis.classes_inner)} font-sans font-[600] tracking-wide text-layer-${layer}-glyph-shade ${basis.disabled ? `` : `group-active:text-layer-${layer}-glyph/40 `} el-re`}
- >
- {basis.label || ``}
- </p>
- {/if}
-</button>
diff --git a/apps-lib/src/lib/components/button/button-round-nav.svelte b/apps-lib/src/lib/components/button/button-round-nav.svelte
@@ -1,24 +0,0 @@
-<script lang="ts">
- import { Glyph, LoadSymbol, type IButtonNavRound } from "$root";
-
- let { basis }: { basis: IButtonNavRound } = $props();
-</script>
-
-<button
- class={`flex flex-row h-12 w-12 justify-center items-center bg-layer-1-surface rounded-full el-re`}
- disabled={!!basis.disabled}
- onclick={basis.callback}
->
- {#if basis.loading}
- <LoadSymbol />
- {:else}
- <Glyph
- basis={{
- classes: `text-layer-0-glyph`,
- dim: `sm+`,
-
- key: basis.glyph,
- }}
- />
- {/if}
-</button>
diff --git a/apps-lib/src/lib/components/button/button-round.svelte b/apps-lib/src/lib/components/button/button-round.svelte
@@ -1,25 +0,0 @@
-<script lang="ts">
- import { LoadSymbol, type IButtonRound } from "$root";
- import { fmt_cl } from "@radroots/util";
-
- let {
- basis,
- }: {
- basis: IButtonRound;
- } = $props();
-</script>
-
-<button
- class={`${fmt_cl(basis.classes)} group flex flex-row h-touch_guide w-full justify-center items-center rounded-full el-re`}
- onclick={async () => {
- await basis.callback();
- }}
->
- {#if basis.loading}
- <LoadSymbol basis={{ dim: `md` }} />
- {:else}
- <p class={`font-sans font-[500] text-[16px]`}>
- {basis.label}
- </p>
- {/if}
-</button>
diff --git a/apps-lib/src/lib/components/button/button-simple-glyph.svelte b/apps-lib/src/lib/components/button/button-simple-glyph.svelte
@@ -1,30 +0,0 @@
-<script lang="ts">
- import { type ILyOpt } from "$root";
- import { parse_layer, type CallbackPromise } from "@radroots/util";
-
- let {
- basis,
- }: {
- basis: ILyOpt & {
- label: string;
- callback: CallbackPromise;
- allow_propogation?: boolean;
- };
- } = $props();
-
- const layer = $derived(parse_layer(basis?.layer ? basis.layer : 1));
-</script>
-
-<button
- class={`group flex flex-row h-[3.5rem] w-full justify-center items-center rounded-touch`}
- onclick={async (ev) => {
- if (!basis.allow_propogation) ev.stopPropagation();
- await basis.callback();
- }}
->
- <p
- class={`font-sans font-[700] text-xl text-layer-${layer}-glyph capitalize tracking-wider opacity-active`}
- >
- {basis.label}
- </p>
-</button>
diff --git a/apps-lib/src/lib/components/button/button-simple.svelte b/apps-lib/src/lib/components/button/button-simple.svelte
@@ -1,22 +0,0 @@
-<script lang="ts">
- import { type IButtonSimple } from "$root";
- import { parse_layer } from "@radroots/util";
-
- let { basis }: { basis: IButtonSimple } = $props();
-
- const layer = $derived(parse_layer(basis.layer || 1));
-</script>
-
-<button
- class={`group flex flex-row h-line_button w-full justify-center items-center rounded-touch bg-layer-${layer}-surface layer-${layer}-active-surface layer-${layer}-active-ring`}
- onclick={async (ev) => {
- if (!basis.allow_propogation) ev.stopPropagation();
- await basis.callback();
- }}
->
- <p
- class={`font-sans font-[600] text-xl text-layer-0-glyph capitalize tracking-wider opacity-active`}
- >
- {basis.label}
- </p>
-</button>
diff --git a/apps-lib/src/lib/components/button/glyph-button-simple.svelte b/apps-lib/src/lib/components/button/glyph-button-simple.svelte
@@ -1,46 +0,0 @@
-<script lang="ts">
- import { Glyph, type IClOpt } from "$root";
- import {
- fmt_cl,
- type CallbackPromise,
- type GlyphKey,
- } from "@radroots/util";
-
- let {
- basis,
- }: {
- basis: IClOpt & {
- kind?: `primary` | `neutral`;
- label: string;
- callback: CallbackPromise;
- glyph?: GlyphKey;
- };
- } = $props();
-
- const classes_kind = $derived(
- basis.kind === `neutral`
- ? `text-layer-0-glyph-shade`
- : `text-layer-0-glyph-hl`,
- );
-</script>
-
-<button
- class={`${fmt_cl(basis.classes)} group flex flex-row justify-center items-center`}
- onclick={basis.callback}
->
- {#if basis.glyph}
- <Glyph
- basis={{
- classes: `${classes_kind}`,
- dim: `sm+`,
-
- key: basis.glyph,
- }}
- />
- {/if}
- <p
- class={`font-sans font-[600] text-line_label ${classes_kind} opacity-active`}
- >
- {basis.label}
- </p>
-</button>
diff --git a/apps-lib/src/lib/components/button/glyph-button.svelte b/apps-lib/src/lib/components/button/glyph-button.svelte
@@ -1,19 +0,0 @@
-<script lang="ts">
- import { glyph_style_map, type IGlyph } from "$root";
- import { fmt_cl } from "@radroots/util";
-
- let { basis }: { basis: IGlyph } = $props();
- const styles = $derived(
- basis?.dim ? glyph_style_map.get(basis.dim) : glyph_style_map.get(`sm`),
- );
-</script>
-
-<!-- svelte-ignore a11y_consider_explicit_label -->
-<button
- class={`${fmt_cl(basis.classes)} flex flex-col justify-center items-center text-[${styles?.gl_1}px] el-re`}
- onclick={async () => {
- if (basis.callback) await basis.callback();
- }}
->
- <i class={`ph-bold ph-${basis.key}`}></i>
-</button>
diff --git a/apps-lib/src/lib/components/carousel/carousel-flow-item.svelte b/apps-lib/src/lib/components/carousel/carousel-flow-item.svelte
@@ -1,19 +0,0 @@
-<script lang="ts">
- import { type IClOpt } from "$root";
- import { fmt_cl } from "@radroots/util";
- import type { Snippet } from "svelte";
-
- let {
- basis,
- children,
- }: {
- basis?: IClOpt;
- children: Snippet;
- } = $props();
-</script>
-
-<div
- class={`${fmt_cl(basis?.classes)} flex flex-col flex-shrink-0 h-full w-full justify-start items-start`}
->
- {@render children()}
-</div>
diff --git a/apps-lib/src/lib/components/carousel/carousel-flow.svelte b/apps-lib/src/lib/components/carousel/carousel-flow.svelte
@@ -1,53 +0,0 @@
-<script lang="ts">
- import { browser } from "$app/environment";
- import { handle_err, type IClOpt } from "$root";
- import { fmt_cl } from "@radroots/util";
- import { onDestroy, onMount, type Snippet } from "svelte";
-
- let {
- basis,
- children,
- }: {
- basis: IClOpt & {
- index: number;
- slide_duration?: number;
- };
- children: Snippet;
- } = $props();
-
- let el_parent: HTMLDivElement | null = $state(null);
- let duration: number = $state(basis.slide_duration ?? 500);
- let offset_w: number = $state(0);
-
- onMount(async () => {
- try {
- handle_resize();
- if (browser) window.addEventListener(`resize`, handle_resize);
- } catch (e) {
- handle_err(e, `on_mount`);
- }
- });
-
- onDestroy(async () => {
- try {
- if (browser) window.removeEventListener(`resize`, handle_resize);
- } catch (e) {
- handle_err(e, `on_destroy`);
- }
- });
-
- const handle_resize = (): void => {
- if (el_parent && el_parent.children.length > 0)
- offset_w = (el_parent.children[0] as HTMLElement).offsetWidth;
- };
-</script>
-
-<div class={`${fmt_cl(basis?.classes)}relative flex flex-col w-full`}>
- <div
- bind:this={el_parent}
- class={`flex flex-grow transition-transform`}
- style={`transform: translateX(-${Math.max(basis?.index, 0) * offset_w}px); transition: transform ${duration}ms ease-out;`}
- >
- {@render children()}
- </div>
-</div>
diff --git a/apps-lib/src/lib/components/carousel/carousel-item.svelte b/apps-lib/src/lib/components/carousel/carousel-item.svelte
@@ -1,19 +0,0 @@
-<script lang="ts">
- import { type IBasisOpt, type IClOpt } from "$root";
- import { fmt_cl } from "@radroots/util";
- import type { Snippet } from "svelte";
-
- let {
- basis = undefined,
- children,
- }: {
- basis?: IBasisOpt<IClOpt>;
- children: Snippet;
- } = $props();
-</script>
-
-<div
- class={`${fmt_cl(basis?.classes)} flex flex-col flex-shrink-0 w-[100vw] justify-start items-center`}
->
- {@render children()}
-</div>
diff --git a/apps-lib/src/lib/components/carousel/carousel.svelte b/apps-lib/src/lib/components/carousel/carousel.svelte
@@ -1,24 +0,0 @@
-<script lang="ts">
- import { casl_i, type IBasisOpt, type IClOpt } from "$root";
- import { fmt_cl } from "@radroots/util";
- import type { Snippet } from "svelte";
-
- let {
- basis = undefined,
- children,
- }: {
- basis?: IBasisOpt<IClOpt>;
- children: Snippet;
- } = $props();
-</script>
-
-<div
- class={`${fmt_cl(basis?.classes)} relative flex flex-col w-full overflow-hidden`}
->
- <div
- class={`flex h-full transition-transform duration-500`}
- style={`transform: translateX(-${Math.max($casl_i, 0) * 100}vw)`}
- >
- {@render children()}
- </div>
-</div>
diff --git a/apps-lib/src/lib/components/envelope/envelope-lower-full.svelte b/apps-lib/src/lib/components/envelope/envelope-lower-full.svelte
@@ -1,29 +0,0 @@
-<script lang="ts">
- import type { Snippet } from "svelte";
- import { quintInOut } from "svelte/easing";
- import { fly } from "svelte/transition";
-
- let {
- basis,
- children,
- }: {
- basis: {
- visible: boolean;
- };
- children: Snippet;
- } = $props();
-</script>
-
-{#if basis.visible}
- <div
- in:fly={{ y: `100%`, easing: quintInOut }}
- out:fly={{ y: `100%`, easing: quintInOut }}
- class={`z-50 absolute bottom-0 left-0 flex flex-col h-[100vh] w-full justify-start items-start bg-transparent el-re`}
- >
- <div
- class={`z-[100] [flex flex-col h-full w-full justify-start items-center overflow-y-scroll overflow-x-hidden scroll-hide el-re`}
- >
- {@render children()}
- </div>
- </div>
-{/if}
diff --git a/apps-lib/src/lib/components/envelope/map-location-select-envelope.svelte b/apps-lib/src/lib/components/envelope/map-location-select-envelope.svelte
@@ -1,97 +0,0 @@
-<script lang="ts">
- import {
- ButtonLayoutPair,
- EnvelopeLowerFull,
- Map,
- MapMarkerArea,
- } from "$root";
- import {
- cfg_map,
- parse_geol_point_tup,
- type CallbackPromiseGeneric,
- type GeocoderReverseResult,
- type GeolocationPoint,
- } from "@radroots/util";
- import LayoutBottomButton from "../layout/layout-bottom-button.svelte";
-
- let {
- basis,
- map_geop = $bindable(undefined),
- map_geoc = $bindable(undefined),
- }: {
- basis: {
- visible: boolean;
- on_submit: CallbackPromiseGeneric<
- | {
- map_geop: GeolocationPoint | undefined;
- map_geoc: GeocoderReverseResult | undefined;
- }
- | undefined
- >;
- };
- map_geop?: GeolocationPoint;
- map_geoc?: GeocoderReverseResult;
- } = $props();
-
- let map: maplibregl.Map | undefined = $state(undefined);
- let map_init = $state(false);
-
- $effect(() => {
- if (basis.visible && map && map_geop && !map_init) {
- map.setCenter(parse_geol_point_tup(map_geop));
- map_init = true;
- }
- });
-
- $effect(() => {
- if (basis.visible === false) map_init = false; //@todo
- });
-</script>
-
-<EnvelopeLowerFull
- basis={{
- visible: basis.visible,
- }}
->
- <div
- class={`relative flex flex-col h-full w-full justify-center items-center bg-layer-1-surface`}
- >
- <Map
- bind:map
- basis={{
- zoom_click_off: true,
- }}
- >
- {#if map_geop}
- <MapMarkerArea
- bind:map_geop
- bind:map_geoc
- basis={{
- show_display: !!map_geop,
- }}
- />
- {/if}
- </Map>
- <LayoutBottomButton>
- <ButtonLayoutPair
- basis={{
- continue: {
- label: `Choose location`,
- disabled: false,
- callback: async () => {
- await basis.on_submit({ map_geoc, map_geop });
- if (map) map.setCenter(cfg_map.coords.default);
- },
- },
- back: {
- label: `Back`,
- visible: true,
- callback: async () => {
- await basis.on_submit(undefined);
- },
- },
- }}
- />
- </LayoutBottomButton>
- </div>
-</EnvelopeLowerFull>
diff --git a/apps-lib/src/lib/components/float/float-page.svelte b/apps-lib/src/lib/components/float/float-page.svelte
@@ -1,12 +0,0 @@
-<script lang="ts">
- import type { IFloatPage } from "$lib/types/component";
- import type { Snippet } from "svelte";
-
- let { basis, children }: { basis: IFloatPage; children: Snippet } =
- $props();
-</script>
-
-<div class={`absolute top-10 ${basis.posx}-6 flex flex-row`}>
- {@render children()}
-</div>
-<div class="hidden left-6 right-6"></div>
diff --git a/apps-lib/src/lib/components/form/entry-line-idb.svelte b/apps-lib/src/lib/components/form/entry-line-idb.svelte
@@ -1,68 +0,0 @@
-<script lang="ts">
- import {
- EntryWrap,
- Glyph,
- Input,
- LoadSymbol,
- type IEntryLineIdb,
- } from "$root";
- import { fmt_cl, parse_layer, type LoadingDimension } from "@radroots/util";
-
- let {
- basis,
- }: {
- basis: IEntryLineIdb;
- } = $props();
-
- const layer = $derived(
- parse_layer(
- typeof basis.wrap?.layer === `boolean` ? 0 : basis.wrap?.layer,
- ),
- );
-
- const classes_layer = $derived(
- typeof basis.wrap?.layer === `boolean`
- ? ``
- : `text-layer-${layer}-glyph`,
- );
-
- const loading_dim: LoadingDimension = $derived(
- basis.wrap?.style === `guide` ? `md` : `sm`,
- );
-</script>
-
-<EntryWrap basis={basis?.wrap}>
- <Input
- basis={{
- ...basis.el,
- classes: `h-entry_line ${fmt_cl(basis.el.classes)}`,
- }}
- />
- {#if basis.loading}
- <div
- class={`z-5 absolute right-0 top-0 flex flex-row h-full pr-4 justify-end items-center fade-in el-re`}
- >
- <LoadSymbol
- basis={{
- dim: loading_dim,
- }}
- />
- </div>
- {:else if basis.notify_inline}
- {#if `glyph` in basis.notify_inline}
- <div
- class={`z-5 absolute el-re right-0 top-0 flex flex-row h-full pr-3 justify-end items-center translate-x-[34px] fade-in`}
- >
- <Glyph
- basis={typeof basis.notify_inline.glyph === `string`
- ? {
- key: basis.notify_inline.glyph,
- dim: `xs+`,
- classes: `${classes_layer}`,
- }
- : basis.notify_inline.glyph}
- />
- </div>
- {/if}
- {/if}
-</EntryWrap>
diff --git a/apps-lib/src/lib/components/form/entry-line.svelte b/apps-lib/src/lib/components/form/entry-line.svelte
@@ -1,71 +0,0 @@
-<script lang="ts">
- import {
- EntryWrap,
- Glyph,
- InputValue,
- LoadSymbol,
- type IEntryLine,
- } from "$root";
- import { parse_layer, type LoadingDimension } from "@radroots/util";
-
- let {
- basis,
- value = $bindable(``),
- }: {
- basis: IEntryLine;
- value: string;
- } = $props();
-
- const layer = $derived(
- parse_layer(
- typeof basis.wrap?.layer === `boolean` ? 0 : basis.wrap?.layer,
- ),
- );
-
- const classes_layer = $derived(
- typeof basis.wrap?.layer === `boolean`
- ? ``
- : `text-layer-${layer}-glyph`,
- );
-
- const loading_dim: LoadingDimension = $derived(
- basis.wrap?.style === `guide` ? `md` : `sm`,
- );
-</script>
-
-<EntryWrap basis={basis?.wrap}>
- <InputValue
- bind:value
- basis={{
- ...basis.el,
- classes: `h-entry_line ${basis.el.classes}`,
- }}
- />
- {#if basis.loading}
- <div
- class={`z-5 absolute right-0 top-0 flex flex-row h-full pr-4 justify-end items-center fade-in el-re`}
- >
- <LoadSymbol
- basis={{
- dim: loading_dim,
- }}
- />
- </div>
- {:else if basis.notify_inline}
- {#if `glyph` in basis.notify_inline}
- <div
- class={`z-5 absolute el-re right-0 top-0 flex flex-row h-full pr-3 justify-end items-center translate-x-[34px] fade-in`}
- >
- <Glyph
- basis={typeof basis.notify_inline.glyph === `string`
- ? {
- key: basis.notify_inline.glyph,
- dim: `xs+`,
- classes: `${classes_layer}`,
- }
- : basis.notify_inline.glyph}
- />
- </div>
- {/if}
- {/if}
-</EntryWrap>
diff --git a/apps-lib/src/lib/components/form/entry-multiline.svelte b/apps-lib/src/lib/components/form/entry-multiline.svelte
@@ -1,49 +0,0 @@
-<script lang="ts">
- import { Glyph, TextArea, type IEntryMultiLine } from "$root";
- import { fmt_cl, parse_layer } from "@radroots/util";
-
- let {
- basis,
- value = $bindable(``),
- }: {
- basis: IEntryMultiLine;
- value: string;
- } = $props();
-
- const layer = $derived(
- parse_layer(
- typeof basis.wrap?.layer === `boolean` ? 0 : basis.wrap?.layer,
- ),
- );
-
- const classes_layer = $derived(
- typeof layer === `boolean`
- ? `bg-transparent`
- : `bg-layer-${layer}-surface`,
- );
-</script>
-
-<div
- id={basis.wrap?.id || null}
- class={`${fmt_cl(basis.wrap?.classes)} relative el-re entry-textarea-wrap ${classes_layer}`}
->
- <TextArea bind:value basis={basis.el} />
- {#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 `}
- >
- <Glyph
- basis={typeof basis.notify_inline.glyph === `string`
- ? {
- key: basis.notify_inline.glyph,
- dim: `xs+`,
-
- classes: `text-layer-${layer}-glyph`,
- }
- : basis.notify_inline.glyph}
- />
- </div>
- {/if}
- {/if}
-</div>
diff --git a/apps-lib/src/lib/components/form/entry-select.svelte b/apps-lib/src/lib/components/form/entry-select.svelte
@@ -1,54 +0,0 @@
-<script lang="ts">
- import {
- EntryWrap,
- Glyph,
- LoadSymbol,
- Select,
- type IEntrySelect,
- } from "$root";
- import { fmt_cl, parse_layer } from "@radroots/util";
-
- let {
- basis,
- value = $bindable(``),
- }: {
- basis: IEntrySelect;
- value: string;
- } = $props();
-
- const layer = $derived(
- typeof basis?.wrap.layer === `boolean`
- ? parse_layer(0)
- : parse_layer(basis?.wrap.layer, 1),
- );
-</script>
-
-<EntryWrap basis={basis?.wrap}>
- {#if basis?.loading}
- <div class={`flex flex-row w-full justify-center items-center`}>
- <LoadSymbol basis={{ dim: `sm`, blades: 8 }} />
- </div>
- {:else}
- <Select
- bind:value
- basis={{
- ...basis.el,
- classes: `${fmt_cl(basis.el.classes)} w-full`,
- }}
- />
- {/if}
- {#if !basis?.hide_arrows}
- <div
- class={`z-5 absolute right-0 top-0 flex flex-row h-full pr-4 justify-end items-center`}
- >
- <Glyph
- basis={{
- key: `caret-up-down`,
- dim: `xs`,
-
- classes: `text-layer-${layer}-glyph_d`,
- }}
- />
- </div>
- {/if}
-</EntryWrap>
diff --git a/apps-lib/src/lib/components/form/entry-wrap.svelte b/apps-lib/src/lib/components/form/entry-wrap.svelte
@@ -1,32 +0,0 @@
-<script lang="ts">
- import { type IBasisOpt, type IEntryWrap } from "$root";
- import { fmt_cl, parse_layer } from "@radroots/util";
- import type { Snippet } from "svelte";
-
- let {
- basis = undefined,
- children,
- }: {
- basis?: IBasisOpt<IEntryWrap>;
- children: Snippet;
- } = $props();
-
- const layer = $derived(
- typeof basis?.layer === `boolean`
- ? parse_layer(0)
- : parse_layer(basis?.layer),
- );
-
- const classes_layer = $derived(
- typeof basis?.layer === `boolean`
- ? `bg-transparent`
- : `bg-layer-${layer}-surface ${basis?.style_a ? `active:bg-layer-${layer}-surface_a` : ``}`,
- );
-</script>
-
-<button
- id={basis?.id || null}
- class={`${fmt_cl(basis?.classes)} relative entry-line-wrap ${!basis?.no_pad ? ` pl-6 pr-4` : ``} h-entry_${basis?.style ? basis.style : `line`} rounded-touch ${classes_layer} el-re`}
->
- {@render children()}
-</button>
diff --git a/apps-lib/src/lib/components/form/form-entry-input.svelte b/apps-lib/src/lib/components/form/form-entry-input.svelte
@@ -1,44 +0,0 @@
-<script lang="ts">
- import { EntryLine, fmt_id, LayoutTrellisLine, type IIdOpt } from "$root";
- import { type FormField } from "@radroots/util";
-
- let {
- basis,
- val = $bindable(``),
- }: {
- basis: IIdOpt & {
- entry_label: string;
- input_placeholder?: string;
- input_field?: FormField;
- };
- val: string;
- } = $props();
-
- const id = $derived(basis.id || ``);
-</script>
-
-<LayoutTrellisLine
- basis={{
- label: {
- value: basis.entry_label || ``,
- },
- }}
->
- <EntryLine
- bind:value={val}
- basis={{
- wrap: {
- id: id ? fmt_id(`${id}_wrap`) : undefined,
- layer: 1,
- },
- el: {
- id: id ? fmt_id(id) : undefined,
- layer: 1,
- classes: `fade-in`,
- placeholder: basis.input_placeholder || ``,
- field: basis.input_field || undefined,
- field_constrain: !!basis.input_field,
- },
- }}
- />
-</LayoutTrellisLine>
diff --git a/apps-lib/src/lib/components/form/form-entry-price-quantity.svelte b/apps-lib/src/lib/components/form/form-entry-price-quantity.svelte
@@ -1,117 +0,0 @@
-<script lang="ts">
- import {
- EntryWrap,
- fmt_id,
- get_context,
- Input,
- LayoutTrellisLine,
- lib_fmt_price,
- lib_parse_currency_marker,
- Select,
- } from "$root";
- import {
- fiat_currencies,
- mass_units,
- num_str,
- type ElementCallbackValue,
- type FormField,
- } from "@radroots/util";
-
- const { ls, locale } = get_context(`lib`);
-
- let {
- basis,
- val_input_price = $bindable(``),
- val_sel_currency = $bindable(``),
- val_sel_qty_unit = $bindable(``),
- }: {
- basis: {
- id?: string;
- input_field?: FormField;
- callback_input: ElementCallbackValue;
- };
- val_input_price: string;
- val_sel_currency: string;
- val_sel_qty_unit: string;
- } = $props();
-
- const id = $derived(basis.id ? basis.id : ``);
-</script>
-
-<LayoutTrellisLine
- basis={{
- label: {
- value: `${$ls(`icu.*_price`, { value: `${$ls(`common.product`)}` })} (${val_sel_currency}/${`${$ls(`units.mass.unit.${val_sel_qty_unit}_ab`)}`})`,
- },
- }}
->
- <EntryWrap
- basis={{
- id: id ? fmt_id(`${id}_wrap`) : undefined,
- layer: 1,
- }}
- >
- <div class={`flex flex-row justify-start pr-1 items-center`}>
- <Select
- bind:value={val_sel_currency}
- basis={{
- id: id ? fmt_id(`${id}_sel_currency`) : undefined,
- layer: 1,
- sync: true,
- classes: `w-fit font-sans font-[400] ${val_input_price ? `text-layer-1-glyph_d` : `text-layer-1-glyph_pl`} el-re`,
- options: [
- {
- entries: fiat_currencies.map((i) => ({
- value: `${i}`,
- label: lib_parse_currency_marker($locale, i),
- })),
- },
- ],
- }}
- />
- </div>
- <Input
- bind:value={val_input_price}
- basis={{
- id: id ? fmt_id(`${id}_input_price`) : undefined,
- layer: 1,
- sync: true,
- placeholder: `${$ls(`icu.enter_the_*`, { value: `${$ls(`common.price`)}`.toLowerCase() })}`,
- field: basis.input_field,
- callback: basis.callback_input,
- callback_blur: async ({ el }) => {
- if (!el.value) return;
- el.value = lib_fmt_price(
- $locale,
- el.value,
- val_sel_currency,
- ).slice(1);
- //@todo fmt handles 'en' only
- },
- }}
- />
- <div class={`flex flex-row gap-2 justify-end items-center`}>
- <p class={`font-sans font-[400] text-layer-1-glyph_d lowercase`}>
- {num_str(1)}
- </p>
- <Select
- bind:value={val_sel_qty_unit}
- basis={{
- id: id ? fmt_id(`${id}_sel_qty_unit`) : undefined,
- sync: true,
- layer: 1,
- classes: `w-fit font-sans font-[400]`,
- show_arrows: `r`,
- options: [
- {
- entries: mass_units.map((i) => ({
- value: i,
- label: `${$ls(`units.mass.unit.${i}_ab`)}`.toLowerCase(),
- })),
- },
- ],
- }}
- />
- </div>
- </EntryWrap>
-</LayoutTrellisLine>
diff --git a/apps-lib/src/lib/components/form/form-entry-price.svelte b/apps-lib/src/lib/components/form/form-entry-price.svelte
@@ -1,122 +0,0 @@
-<script lang="ts">
- import {
- EntryWrap,
- fmt_id,
- get_context,
- Input,
- LayoutTrellisLine,
- lib_fmt_price,
- lib_parse_currency_marker,
- Select,
- type IIdOpt,
- } from "$root";
- import {
- fiat_currencies,
- form_fields,
- mass_units,
- type ElementCallbackValue,
- } from "@radroots/util";
-
- const { ls, locale } = get_context(`lib`);
-
- let {
- basis,
- val_input_price = $bindable(``),
- val_sel_currency = $bindable(``),
- val_sel_quantity_unit = $bindable(``),
- }: {
- basis: IIdOpt & {
- display_symbol?: boolean;
- entry_label?: string;
- input_placeholder?: string;
- callback_input?: ElementCallbackValue;
- };
- val_input_price: string;
- val_sel_currency: string;
- val_sel_quantity_unit: string;
- } = $props();
-
- const id = $derived(basis.id ? basis.id : ``);
-</script>
-
-<LayoutTrellisLine
- basis={{
- label: {
- value: basis.entry_label || ``,
- },
- }}
->
- <EntryWrap
- basis={{
- id: id ? fmt_id(`${id}_wrap`) : undefined,
- layer: 1,
- }}
- >
- <Input
- bind:value={val_input_price}
- basis={{
- id: id ? fmt_id(`${id}_input_price`) : undefined,
- layer: 1,
- sync: true,
- placeholder: basis.input_placeholder,
- field: form_fields.price,
- callback: basis.callback_input,
- callback_blur: async ({ el }) => {
- if (!el.value) return;
- el.value = lib_fmt_price(
- $locale,
- el.value,
- val_sel_currency,
- ).slice(1);
- //@todo fmt handles 'en' only
- },
- }}
- />
- <div
- class={`absolute right-4 flex flex-row justify-start items-center`}
- >
- <Select
- bind:value={val_sel_currency}
- basis={{
- id: id ? fmt_id(`${id}_sel_currency`) : undefined,
- layer: 1,
- sync: true,
- classes: `w-fitfont-sans font-[400] el-re`,
- options: [
- {
- entries: fiat_currencies.map((i) => ({
- value: i,
- label: basis.display_symbol
- ? lib_parse_currency_marker($locale, i)
- : i.toUpperCase(),
- })),
- },
- ],
- }}
- />
- <div class={`flex flex-row px-2 justify-start items-center`}>
- <p class={`font-sans font-[400] text-layer-0-glyph`}>
- {`/`}
- </p>
- </div>
- <Select
- bind:value={val_sel_quantity_unit}
- basis={{
- id: id ? fmt_id(`${id}_sel_qty_unit`) : undefined,
- sync: true,
- layer: 1,
- classes: `w-fit font-sans font-[400]`,
- show_arrows: `r`,
- options: [
- {
- entries: mass_units.map((i) => ({
- value: i,
- label: `${$ls(`units.mass.unit.${i}_ab`)}`.toLowerCase(),
- })),
- },
- ],
- }}
- />
- </div>
- </EntryWrap>
-</LayoutTrellisLine>
diff --git a/apps-lib/src/lib/components/form/form-entry-quantity.svelte b/apps-lib/src/lib/components/form/form-entry-quantity.svelte
@@ -1,105 +0,0 @@
-<script lang="ts">
- import {
- EntryWrap,
- fmt_id,
- get_context,
- Input,
- LayoutTrellisLine,
- Select,
- type IIdOpt,
- } from "$root";
- import {
- form_fields,
- mass_units,
- type ElementCallbackValue,
- } from "@radroots/util";
-
- const { ls } = get_context(`lib`);
-
- let {
- basis,
- val_input_quantity = $bindable(``),
- val_sel_quantity_unit = $bindable(``),
- val_sel_quantity_label = $bindable(``),
- }: {
- basis: IIdOpt & {
- display_symbol?: boolean;
- entry_label?: string;
- input_placeholder?: string;
- callback_input?: ElementCallbackValue;
- };
- val_input_quantity: string;
- val_sel_quantity_unit: string;
- val_sel_quantity_label: string;
- } = $props();
-
- const id = $derived(basis.id ? basis.id : ``);
-</script>
-
-<LayoutTrellisLine
- basis={{
- label: {
- value: basis.entry_label || ``,
- },
- }}
->
- <EntryWrap
- basis={{
- id: id ? fmt_id(`${id}_wrap`) : undefined,
- layer: 1,
- }}
- >
- <Input
- bind:value={val_input_quantity}
- basis={{
- id: id ? fmt_id(`${id}_input_quantity`) : undefined,
- layer: 1,
- sync: true,
- placeholder: basis.input_placeholder,
- field: form_fields.quantity,
- callback: basis.callback_input,
- }}
- />
- <div
- class={`absolute right-4 flex flex-row gap-1 justify-start items-center`}
- >
- <Select
- bind:value={val_sel_quantity_unit}
- basis={{
- id: id ? fmt_id(`${id}_sel_quantity_unit`) : undefined,
- layer: 1,
- sync: true,
- classes: `w-fit font-sans font-[400] el-re`,
- options: [
- {
- entries: mass_units.map((i) => ({
- value: i,
- label: `${$ls(`units.mass.unit.${i}_ab`)}`.toLowerCase(),
- })),
- },
- ],
- }}
- />
- <Select
- bind:value={val_sel_quantity_label}
- basis={{
- id: id ? fmt_id(`${id}_sel_quantity_label`) : undefined,
- sync: true,
- layer: 1,
- classes: `w-fit font-sans font-[400] pr-2`,
- show_arrows: `r`,
- options: [
- {
- entries: [
- {
- value: `bag`,
- label: `${$ls(`common.bag`)}`.toLowerCase(),
- },
- ],
- },
- ],
- }}
- />
- </div>
- </EntryWrap>
-</LayoutTrellisLine>
diff --git a/apps-lib/src/lib/components/form/form-entry-select-input.svelte b/apps-lib/src/lib/components/form/form-entry-select-input.svelte
@@ -1,94 +0,0 @@
-<script lang="ts">
- import {
- EntryLine,
- EntrySelect,
- fmt_id,
- get_context,
- LayoutTrellisLine,
- type ISelectCallback,
- type ISelectOption,
- } from "$root";
- import {
- type CallbackPromiseGeneric,
- type FormField,
- } from "@radroots/util";
-
- const { ls } = get_context(`lib`);
-
- let {
- basis,
- val_sel = $bindable(``),
- val_sel_input = $bindable(``),
- }: {
- basis: {
- id: string;
- visible_input: boolean;
- callback_select: ISelectCallback;
- callback_visible: CallbackPromiseGeneric<boolean>;
- select_entries: ISelectOption<string>[];
- input_placeholder?: string;
- input_field?: FormField;
- entry_label?: string;
- };
- val_sel: string;
- val_sel_input: string;
- } = $props();
-</script>
-
-<LayoutTrellisLine
- basis={{
- label: {
- value: basis.entry_label || ``,
- },
- notify: basis.visible_input
- ? {
- label: {
- value: `${$ls(`common.close`)}`,
- },
- callback: async () => {
- await basis.callback_visible(false);
- },
- }
- : undefined,
- }}
->
- {#if !basis.visible_input}
- <EntrySelect
- bind:value={val_sel}
- basis={{
- wrap: {
- id: fmt_id(`${basis.id}_wrap`),
- layer: 1,
- },
- el: {
- id: fmt_id(basis.id),
- sync: true,
- layer: 1,
- options: [
- {
- entries: basis.select_entries,
- },
- ],
- callback: basis.callback_select,
- },
- }}
- />
- {:else}
- <EntryLine
- bind:value={val_sel_input}
- basis={{
- wrap: {
- id: fmt_id(`${basis.id}_wrap`),
- layer: 1,
- },
- el: {
- layer: 1,
- classes: `fade-in`,
- placeholder: basis.input_placeholder || ``,
- field: basis.input_field || undefined,
- field_constrain: !!basis.input_field,
- },
- }}
- />
- {/if}
-</LayoutTrellisLine>
diff --git a/apps-lib/src/lib/components/form/form-entry-select.svelte b/apps-lib/src/lib/components/form/form-entry-select.svelte
@@ -1,56 +0,0 @@
-<script lang="ts">
- import {
- EntrySelect,
- fmt_id,
- LayoutTrellisLine,
- type IClOpt,
- type IIdOpt,
- type ISelectCallback,
- type ISelectOption,
- } from "$root";
-
- let {
- basis,
- val = $bindable(``),
- }: {
- basis: IIdOpt &
- IClOpt & {
- callback?: ISelectCallback;
- entries: ISelectOption<string>[];
- entry_label?: string;
- };
- val: string;
- } = $props();
-
- const id = $derived(basis.id || ``);
-</script>
-
-<LayoutTrellisLine
- basis={{
- label: {
- value: basis.entry_label || ``,
- },
- }}
->
- <EntrySelect
- bind:value={val}
- basis={{
- wrap: {
- id: id ? fmt_id(`${id}_wrap`) : undefined,
- layer: 1,
- },
- el: {
- id: id ? fmt_id(id) : undefined,
- classes: basis.classes,
- sync: true,
- layer: 1,
- options: [
- {
- entries: basis.entries,
- },
- ],
- callback: basis.callback,
- },
- }}
- />
-</LayoutTrellisLine>
diff --git a/apps-lib/src/lib/components/form/form-entry-textarea.svelte b/apps-lib/src/lib/components/form/form-entry-textarea.svelte
@@ -1,55 +0,0 @@
-<script lang="ts">
- import {
- EntryMultiline,
- LayoutTrellisLine,
- fmt_id,
- type IIdOpt,
- } from "$root";
- import {
- type ElementCallbackValueKeydown,
- type FormField,
- } from "@radroots/util";
-
- let {
- basis,
- val = $bindable(``),
- }: {
- basis: IIdOpt & {
- entry_label?: string;
- placeholder?: string;
- field?: FormField;
- callback_keydown?: ElementCallbackValueKeydown<HTMLTextAreaElement>;
- };
- val: string;
- } = $props();
-
- const id = $derived(basis.id || ``);
-</script>
-
-<LayoutTrellisLine
- basis={{
- classes: `h-full`,
- label: {
- value: basis.entry_label || ``,
- },
- }}
->
- <EntryMultiline
- bind:value={val}
- basis={{
- wrap: {
- id: id ? fmt_id(`${id}_wrap`) : undefined,
- classes: `h-full`,
- },
- el: {
- classes: `h-full overflow-hidden`,
- id: id ? fmt_id(id) : undefined,
- sync: true,
- placeholder: basis.placeholder || ``,
- field: basis.field || undefined,
- field_constrain: !!basis.field,
- callback_keydown: basis.callback_keydown,
- },
- }}
- />
-</LayoutTrellisLine>
diff --git a/apps-lib/src/lib/components/form/form-line-ledger-label-select-label.svelte b/apps-lib/src/lib/components/form/form-line-ledger-label-select-label.svelte
@@ -1,36 +0,0 @@
-<script lang="ts">
- import { symbols } from "@radroots/util";
-
- let {
- basis,
- }: {
- basis: {
- label: string;
- };
- } = $props();
-</script>
-
-<div class={`flex flex-row justify-start items-center`}>
- <p
- class={`pr-[13px] font-sansd text-trellis_ti text-layer-0-glyph-label uppercase`}
- >
- {`(${basis.label}`}
- </p>
- <div
- class={`relative flex flex-row justify-start items-center -translate-x-[10px] -translate-y-[1px]`}
- >
- <p
- class={`absolute font-sansd text-trellis_ti text-layer-0-glyph-label uppercase scale-y-[70%] scale-x-[80%] -translate-y-[1px]`}
- >
- {`${symbols.up}`}
- </p>
- <p
- class={`absolute font-sansd text-trellis_ti text-layer-0-glyph-label uppercase scale-y-[70%] scale-x-[80%] translate-y-[2px]`}
- >
- {`${symbols.down}`}
- </p>
- </div>
- <p class={`font-sansd text-trellis_ti text-layer-0-glyph-label uppercase`}>
- {`)`}
- </p>
-</div>
diff --git a/apps-lib/src/lib/components/form/form-line-ledger-select.svelte b/apps-lib/src/lib/components/form/form-line-ledger-select.svelte
@@ -1,88 +0,0 @@
-<script lang="ts">
- import {
- fmt_id,
- Input,
- Select,
- type IIdOpt,
- type ISelectCallback,
- type ISelectOption,
- } from "$root";
- import { type ElementCallbackValueKeydown } from "@radroots/util";
-
- let {
- basis,
- value_input = $bindable(``),
- value_sel = $bindable(``),
- }: {
- basis: IIdOpt & {
- display_value?: string;
- label?: string;
- input: {
- placeholder?: string;
- callback_keydown?:
- | ElementCallbackValueKeydown<HTMLInputElement>
- | undefined;
- };
- select: {
- entries: ISelectOption<string>[];
- callback?: ISelectCallback;
- };
- };
- value_input?: string;
- value_sel?: string;
- } = $props();
-
- const id = $derived(basis.id || ``);
-</script>
-
-<div class={`flex flex-col w-full gap-2 justify-start items-start`}>
- {#if basis.label}
- <div class={`flex flex-row w-full justify-start items-center`}>
- <p
- class={`font-sansd text-trellis_ti text-layer-0-glyph-label uppercase`}
- >
- {basis.label}
- </p>
- </div>
- {/if}
- <div
- class={`relative flex flex-row h-12 w-full justify-start items-center border-y-line border-layer-0-surface-edge`}
- >
- {#if basis.display_value}
- <p class={`font-sans font-[400] text-layer-0-glyph text-form_base`}>
- {basis.display_value}
- </p>
- {:else}
- <Input
- bind:value={value_input}
- basis={{
- id: id ? fmt_id(`${id}_input`) : undefined,
- layer: 0,
- classes: `h-10 placeholder:text-[1.1rem]`,
- placeholder: basis.input.placeholder || ``,
- callback_keydown: basis.input.callback_keydown,
- }}
- />
- <div
- class={`absolute right-0 flex flex-row justify-center items-center`}
- >
- <Select
- bind:value={value_sel}
- basis={{
- classes: `w-fit text-layer-1-glyph`,
- id: id ? fmt_id(`${id}_sel`) : undefined,
- sync: true,
- layer: 1,
- show_arrows: `r`,
- options: [
- {
- entries: basis.select.entries,
- },
- ],
- callback: basis.select.callback,
- }}
- />
- </div>
- {/if}
- </div>
-</div>
diff --git a/apps-lib/src/lib/components/form/form-line-ledger.svelte b/apps-lib/src/lib/components/form/form-line-ledger.svelte
@@ -1,92 +0,0 @@
-<script lang="ts">
- import {
- fmt_id,
- Input,
- SelectMenu,
- type IIdOpt,
- type ISelectOption,
- } from "$root";
- import {
- type ElementCallbackValueKeydown,
- type FormField,
- } from "@radroots/util";
- import FormLineLedgerLabelSelectLabel from "./form-line-ledger-label-select-label.svelte";
-
- let {
- basis,
- value = $bindable(``),
- value_label_sel = $bindable(``),
- }: {
- basis: IIdOpt & {
- display_value?: string;
- label?: string;
- label_select?: {
- label: string;
- entries: ISelectOption<string>[];
- };
- input?: {
- placeholder?: string;
- field?: FormField;
- callback_keydown?:
- | ElementCallbackValueKeydown<HTMLInputElement>
- | undefined;
- };
- };
- value?: string;
- value_label_sel?: string;
- } = $props();
-
- const id = $derived(basis.id || ``);
-</script>
-
-<div class={`flex flex-col w-full gap-2 justify-start items-start`}>
- {#if basis.label}
- <div class={`flex flex-row w-full justify-start gap-1 items-center`}>
- <p
- class={`font-sansd text-trellis_ti text-layer-0-glyph-label uppercase`}
- >
- {basis.label}
- </p>
- {#if basis.label_select}
- <SelectMenu
- bind:value={value_label_sel}
- basis={{
- layer: 0,
- options: [
- {
- entries: basis.label_select.entries,
- },
- ],
- }}
- >
- <FormLineLedgerLabelSelectLabel
- basis={{
- label: basis.label_select.label,
- }}
- />
- </SelectMenu>
- {/if}
- </div>
- {/if}
- <div
- class={`flex flex-row h-12 w-full justify-start items-center border-y-line border-layer-0-surface-edge`}
- >
- {#if basis.display_value}
- <p class={`font-sans font-[400] text-layer-1-glyph text-form_base`}>
- {basis.display_value}
- </p>
- {:else if basis.input}
- <Input
- bind:value
- basis={{
- id: id ? fmt_id(id) : undefined,
- layer: 0,
- classes: `h-10 placeholder:text-[1.1rem]`,
- field: basis.input.field || undefined,
- placeholder: basis.input.placeholder || ``,
- callback_keydown: basis.input.callback_keydown,
- }}
- />
- {/if}
- </div>
-</div>
diff --git a/apps-lib/src/lib/components/form/form-review-display.svelte b/apps-lib/src/lib/components/form/form-review-display.svelte
@@ -1,43 +0,0 @@
-<script lang="ts">
- import { Glyph, type IClOpt, type IClOptWrap } from "$root";
- import { fmt_cl, type CallbackPromise } from "@radroots/util";
-
- let {
- basis,
- }: {
- basis: IClOpt &
- IClOptWrap & {
- label: string;
- value: string;
- value_pl?: string;
- handle_back: CallbackPromise;
- };
- } = $props();
-</script>
-
-<div
- class={`${fmt_cl(basis.classes_wr)} flex flex-row h-6 w-full justify-between items-start`}
->
- <p
- class={`font-sans font-[500] text-layer-1-glyph_d tracking-tight capitalize`}
- >
- {basis.label}
- </p>
- <button
- class={`flex flex-row max-w-[210px] gap-1 justify-end items-start`}
- onclick={async () => {}}
- >
- <p
- class={`${fmt_cl(basis.classes)} font-sans font-[400] text-[1.05rem] text-justify truncate text-layer-1-glyph_d`}
- >
- {basis.value || basis.value_pl || ``}
- </p>
- <Glyph
- basis={{
- classes: `text-layer-0-glyph pt-1`,
- dim: `xs`,
- key: `caret-right`,
- }}
- />
- </button>
-</div>
diff --git a/apps-lib/src/lib/components/form/trade_field_display_kv.svelte b/apps-lib/src/lib/components/form/trade_field_display_kv.svelte
@@ -1,81 +0,0 @@
-<script lang="ts">
- import { fmt_id, Glyph, idb, type IClOpt } from "$root";
- import { el_focus, fmt_cl, type CallbackPromise } from "@radroots/util";
-
- let {
- basis,
- }: {
- basis: IClOpt & {
- visible: boolean;
- label: string;
- display: IClOpt & {
- undef?: string;
- nostyle?: boolean;
- } & (
- | {
- kv: string;
- }
- | {
- value: string;
- }
- );
-
- kv_wrap?: string;
- handle_back: CallbackPromise;
- };
- } = $props();
-
- const classes_undef = $derived(
- basis.visible &&
- ((`kv` in basis.display && !idb.get(fmt_id(basis.display.kv))) ||
- (`value` in basis.display && !basis.display.value))
- ? `opacity-60`
- : ``,
- );
-</script>
-
-<div
- class={`${fmt_cl(basis.classes)} flex flex-row h-6 w-full justify-between items-start`}
->
- <p
- class={`font-sans font-[500] text-layer-1-glyph_d tracking-tight capitalize`}
- >
- {basis.label}
- </p>
- {#if basis.visible}
- <button
- class={`flex flex-row max-w-[210px] gap-1 justify-end items-start`}
- onclick={async () => {
- await el_focus(
- fmt_id(
- basis.kv_wrap
- ? basis.kv_wrap
- : `kv` in basis.display
- ? `${basis.display.kv}_wrap`
- : ``,
- ),
- async () => await basis.handle_back(),
- );
- }}
- >
- <p
- class={`${fmt_cl(basis.display.classes)} font-sans font-[400] text-[1.05rem] text-justify truncate text-layer-1-glyph_d ${classes_undef} ${basis.display.nostyle ? `` : `capitalize`}`}
- >
- {#if `kv` in basis.display}
- {#await idb.get(fmt_id(basis.display.kv)) then kv_val}
- {kv_val || basis.display.undef || ``}
- {/await}
- {:else}
- {basis.display.value || basis.display.undef || ``}
- {/if}
- </p>
- <Glyph
- basis={{
- classes: `text-layer-0-glyph ${classes_undef} pt-1`,
- dim: `xs`,
- key: `caret-right`,
- }}
- />
- </button>
- {/if}
-</div>
diff --git a/apps-lib/src/lib/components/glyph/glyph-circle.svelte b/apps-lib/src/lib/components/glyph/glyph-circle.svelte
@@ -1,20 +0,0 @@
-<script lang="ts">
- import { GlyphButton, glyph_style_map, type IGlyphCircle } from "$root";
- import { fmt_cl } from "@radroots/util";
-
- let { basis }: { basis: IGlyphCircle } = $props();
-
- const styles = $derived(
- basis?.glyph?.dim
- ? glyph_style_map.get(basis?.glyph?.dim)
- : glyph_style_map.get(`sm`),
- );
-</script>
-
-{#if styles?.dim_1}
- <div
- class={`${fmt_cl(basis?.classes_wrap)} flex flex-col h-[${styles?.dim_1}px] w-[${styles?.dim_1}px] justify-center items-center rounded-full el-re`}
- >
- <GlyphButton basis={basis?.glyph} />
- </div>
-{/if}
diff --git a/apps-lib/src/lib/components/glyph/glyph.svelte b/apps-lib/src/lib/components/glyph/glyph.svelte
@@ -1,19 +0,0 @@
-<script lang="ts">
- import { glyph_style_map, type IGlyph } from "$root";
- import { fmt_cl } from "@radroots/util";
-
- let { basis }: { basis: IGlyph } = $props();
-
- const styles = $derived(
- basis?.dim ? glyph_style_map.get(basis.dim) : glyph_style_map.get(`sm`),
- );
-
- const weight = $derived(basis.weight ? `-${basis.weight}` : `-bold`);
-</script>
-
-<div
- id={basis.id || null}
- class={`${fmt_cl(basis.classes)} flex flex-row text-[${styles?.gl_1}px] justify-center items-center`}
->
- <i class={`ph${weight} ph-${basis.key}`}></i>
-</div>
diff --git a/apps-lib/src/lib/components/label/label-display.svelte b/apps-lib/src/lib/components/label/label-display.svelte
@@ -1,31 +0,0 @@
-<script lang="ts">
- import { type ILabelDisplay } from "$root";
- import { fmt_cl, parse_layer } from "@radroots/util";
-
- let { basis }: { basis: ILabelDisplay } = $props();
-
- const layer = $derived(
- typeof basis?.layer === `boolean` ? 0 : parse_layer(basis?.layer, 1),
- );
-
- const classes_layer = $derived(
- typeof layer === `boolean`
- ? `bg-transparent`
- : `bg-layer-${layer}-surface`,
- );
-
- const clases_style = $derived(
- basis.style === `guide` ? `h-entry_guide rounded-touch` : ``,
- );
-</script>
-
-<div
- id={basis.id_wrap || null}
- class={`${fmt_cl(basis.classes)} relative el-re entry-line-wrap px-2 ${classes_layer} ${clases_style}`}
->
- <p
- class={`${fmt_cl(basis.label.classes)} font-sans font-[400] text-layer-0-glyph`}
- >
- {basis.label.value}
- </p>
-</div>
diff --git a/apps-lib/src/lib/components/layout/layout-bottom-button.svelte b/apps-lib/src/lib/components/layout/layout-bottom-button.svelte
@@ -1,22 +0,0 @@
-<script lang="ts">
- import { app_lo } from "$lib/store/app";
- import type { Snippet } from "svelte";
-
- let {
- basis,
- children,
- }: {
- basis?: {
- hidden: boolean;
- };
- children: Snippet;
- } = $props();
-</script>
-
-{#if !basis?.hidden}
- <div
- class={`z-10 absolute bottom-0 h-lo_bottom_button_${$app_lo} flex flex-col w-full px-4 gap-1 justify-start items-center`}
- >
- {@render children()}
- </div>
-{/if}
diff --git a/apps-lib/src/lib/components/layout/layout-page.svelte b/apps-lib/src/lib/components/layout/layout-page.svelte
@@ -1,19 +0,0 @@
-<script lang="ts">
- import { type IBasisOpt, type IClOpt } from "$root";
- import { fmt_cl } from "@radroots/util";
- import type { Snippet } from "svelte";
-
- let {
- basis = undefined,
- children,
- }: {
- basis?: IBasisOpt<IClOpt>;
- children: Snippet;
- } = $props();
-</script>
-
-<div
- class={`${fmt_cl(basis?.classes)} flex flex-col w-full pt-4 px-4 pb-24 gap-4 justify-center items-center`}
->
- {@render children()}
-</div>
diff --git a/apps-lib/src/lib/components/layout/layout-trellis-line.svelte b/apps-lib/src/lib/components/layout/layout-trellis-line.svelte
@@ -1,62 +0,0 @@
-<script lang="ts">
- import {
- app_lo,
- Glyph,
- type IBasisOpt,
- type ILayoutTrellisLine,
- } from "$root";
- import { fmt_cl } from "@radroots/util";
- import type { Snippet } from "svelte";
- import { fade } from "svelte/transition";
-
- let {
- basis = undefined,
- children,
- }: {
- basis?: IBasisOpt<ILayoutTrellisLine>;
- children: Snippet;
- } = $props();
-</script>
-
-<div
- class={`${fmt_cl(basis?.classes)} flex flex-col w-lo_line_entry_${$app_lo} gap-[6px] justify-start items-center`}
->
- {#if (basis?.label && `value` in basis?.label) || basis?.notify}
- <div
- class={`flex flex-row h-5 w-full px-2 gap-[6px] justify-start items-center`}
- >
- {#if basis?.label && `value` in basis?.label}
- <p
- class={`${fmt_cl(basis?.label.classes)} font-sans font-[400] uppercase text-layer-0-glyph text-sm`}
- >
- {basis?.label.value}
- </p>
- {/if}
- {#if basis?.notify}
- <button
- in:fade={{ duration: 200 }}
- out:fade={{ delay: 50, duration: 200 }}
- onclick={async () => {
- await basis?.notify?.callback();
- }}
- class={`${fmt_cl(basis?.notify.classes)} flex flex-row gap-1 justify-end items-center text-layer-0-glyph/80 el-re`}
- >
- {#if `glyph` in basis?.notify && basis?.notify?.glyph && basis.notify.glyph_first}
- <Glyph basis={basis.notify.glyph} />
- {/if}
- {#if `label` in basis?.notify && basis?.notify?.label && `value` in basis?.notify?.label}
- <p
- class={`${fmt_cl(basis?.notify.label.classes)} font-sans font-[500] uppercase text-xs`}
- >
- {basis?.notify.label.value}
- </p>
- {/if}
- {#if `glyph` in basis?.notify && basis?.notify?.glyph && !basis.notify.glyph_first}
- <Glyph basis={basis.notify.glyph} />
- {/if}
- </button>
- {/if}
- </div>
- {/if}
- {@render children()}
-</div>
diff --git a/apps-lib/src/lib/components/layout/layout-trellis.svelte b/apps-lib/src/lib/components/layout/layout-trellis.svelte
@@ -1,19 +0,0 @@
-<script lang="ts">
- import { type IBasisOpt, type IClOpt } from "$root";
- import { fmt_cl } from "@radroots/util";
- import type { Snippet } from "svelte";
-
- let {
- basis = undefined,
- children,
- }: {
- basis?: IBasisOpt<IClOpt>;
- children: Snippet;
- } = $props();
-</script>
-
-<div
- class={`${fmt_cl(basis?.classes)} flex flex-col pb-12 gap-6 justify-center items-center scroll-hide`}
->
- {@render children()}
-</div>
diff --git a/apps-lib/src/lib/components/layout/layout-view.svelte b/apps-lib/src/lib/components/layout/layout-view.svelte
@@ -1,54 +0,0 @@
-<script lang="ts">
- import {
- nav_blur,
- ph_blur,
- tabs_blur,
- type IBasisOpt,
- type IClOpt,
- } from "$root";
- import { fmt_cl } from "@radroots/util";
- import { onDestroy, onMount, type Snippet } from "svelte";
-
- let {
- basis = undefined,
- el = $bindable(null),
- children,
- }: {
- el?: HTMLDivElement | null;
- basis?: IBasisOpt<IClOpt & { fade?: boolean }>;
- children: Snippet;
- } = $props();
-
- onMount(async () => {
- try {
- el?.addEventListener("scroll", scrollChange);
- } catch (e) {
- } finally {
- }
- });
-
- onDestroy(async () => {
- try {
- el?.removeEventListener("scroll", scrollChange);
- } catch (e) {
- } finally {
- }
- });
-
- const scrollChange = (): void => {
- if (Math.max(el?.scrollTop || 0, 0) > 10) nav_blur.set(true);
- else nav_blur.set(false);
- if (Math.max(el?.scrollTop || 0, 0) > 10) tabs_blur.set(true);
- else tabs_blur.set(false);
- if (Math.max(el?.scrollTop || 0, 0) > 30) ph_blur.set(true);
- else ph_blur.set(false);
- };
-</script>
-
-<div
- bind:this={el}
- class={`${fmt_cl(basis?.classes)} absolute top-0 left-0 flex flex-col h-[100vh] w-full justify-start items-center scroll-hide overflow-auto`}
- class:fade-in={basis?.fade}
->
- {@render children()}
-</div>
diff --git a/apps-lib/src/lib/components/layout/layout-window.svelte b/apps-lib/src/lib/components/layout/layout-window.svelte
@@ -1,36 +0,0 @@
-<script lang="ts">
- import {
- app_lo,
- app_tilt,
- envelope_tilt,
- envelope_visible,
- handle_err,
- window_set,
- } from "$root";
- import { onMount } from "svelte";
-
- let { children } = $props();
-
- onMount(async () => {
- try {
- window_set();
- } catch (e) {
- handle_err(e, `on_mount`);
- }
- });
-
- envelope_visible.subscribe(async (_envelope_visible) => {
- if (_envelope_visible && $envelope_tilt) app_tilt.set(true);
- else app_tilt.set(false);
- });
-</script>
-
-<div
- class={`relative lg:hidden flex flex-col h-[100vh] w-full bg-layer-0-surface ${$app_tilt ? `scale-y-[96%] translate-y-4 rounded-t-[3rem]` : ``} overflow-x-hidden overflow-y-scroll scroll-hide delay-75 duration-200 el-re`}
->
- {#if $app_lo}
- <div class={`flex flex-col h-full w-full`}>
- {@render children()}
- </div>
- {/if}
-</div>
diff --git a/apps-lib/src/lib/components/lib/css.svelte b/apps-lib/src/lib/components/lib/css.svelte
@@ -1 +0,0 @@
-<div class="hidden -bottom-lo_bottom_button_ios0 -bottom-lo_bottom_button_ios1 -bottom-lo_bottom_button_webm0 -bottom-lo_bottom_button_webm1 -bottom-lo_view_main_ios0 -bottom-lo_view_main_ios1 -bottom-lo_view_main_webm0 -bottom-lo_view_main_webm1 -bottom-nav_page_header_ios0 -bottom-nav_page_header_ios1 -bottom-nav_page_header_webm0 -bottom-nav_page_header_webm1 -bottom-nav_page_toolbar_ios0 -bottom-nav_page_toolbar_ios1 -bottom-nav_page_toolbar_webm0 -bottom-nav_page_toolbar_webm1 -bottom-nav_tabs_ios0 -bottom-nav_tabs_ios1 -bottom-nav_tabs_webm0 -bottom-nav_tabs_webm1 -left-lo_ios0 -left-lo_ios1 -left-lo_line_entry_ios0 -left-lo_line_entry_ios1 -left-lo_line_entry_webm0 -left-lo_line_entry_webm1 -left-lo_textdesc_ios0 -left-lo_textdesc_ios1 -left-lo_textdesc_webm0 -left-lo_textdesc_webm1 -left-lo_webm0 -left-lo_webm1 -right-lo_ios0 -right-lo_ios1 -right-lo_line_entry_ios0 -right-lo_line_entry_ios1 -right-lo_line_entry_webm0 -right-lo_line_entry_webm1 -right-lo_textdesc_ios0 -right-lo_textdesc_ios1 -right-lo_textdesc_webm0 -right-lo_textdesc_webm1 -right-lo_webm0 -right-lo_webm1 -top-lo_bottom_button_ios0 -top-lo_bottom_button_ios1 -top-lo_bottom_button_webm0 -top-lo_bottom_button_webm1 -top-lo_view_main_ios0 -top-lo_view_main_ios1 -top-lo_view_main_webm0 -top-lo_view_main_webm1 -top-nav_page_header_ios0 -top-nav_page_header_ios1 -top-nav_page_header_webm0 -top-nav_page_header_webm1 -top-nav_page_toolbar_ios0 -top-nav_page_toolbar_ios1 -top-nav_page_toolbar_webm0 -top-nav_page_toolbar_webm1 -top-nav_tabs_ios0 -top-nav_tabs_ios1 -top-nav_tabs_webm0 -top-nav_tabs_webm1 -translate-x-w_lo_ios0 -translate-x-w_lo_ios1 -translate-x-w_lo_line_entry_ios0 -translate-x-w_lo_line_entry_ios1 -translate-x-w_lo_line_entry_webm0 -translate-x-w_lo_line_entry_webm1 -translate-x-w_lo_textdesc_ios0 -translate-x-w_lo_textdesc_ios1 -translate-x-w_lo_textdesc_webm0 -translate-x-w_lo_textdesc_webm1 -translate-x-w_lo_webm0 -translate-x-w_lo_webm1 -translate-y-h_lo_bottom_button_ios0 -translate-y-h_lo_bottom_button_ios1 -translate-y-h_lo_bottom_button_webm0 -translate-y-h_lo_bottom_button_webm1 -translate-y-h_lo_view_main_ios0 -translate-y-h_lo_view_main_ios1 -translate-y-h_lo_view_main_webm0 -translate-y-h_lo_view_main_webm1 -translate-y-h_nav_page_header_ios0 -translate-y-h_nav_page_header_ios1 -translate-y-h_nav_page_header_webm0 -translate-y-h_nav_page_header_webm1 -translate-y-h_nav_page_toolbar_ios0 -translate-y-h_nav_page_toolbar_ios1 -translate-y-h_nav_page_toolbar_webm0 -translate-y-h_nav_page_toolbar_webm1 -translate-y-h_nav_tabs_ios0 -translate-y-h_nav_tabs_ios1 -translate-y-h_nav_tabs_webm0 -translate-y-h_nav_tabs_webm1 active:bg-layer-0-glyph active:bg-layer-0-glyph-hl active:bg-layer-0-glyph-hl_a active:bg-layer-0-glyph-label active:bg-layer-0-glyph-shade active:bg-layer-0-glyph_a active:bg-layer-0-glyph_pl active:bg-layer-0-surface active:bg-layer-0-surface-blur active:bg-layer-0-surface-edge active:bg-layer-0-surface_a active:bg-layer-0-surface_w active:bg-layer-1-glyph active:bg-layer-1-glyph-hl active:bg-layer-1-glyph-hl_a active:bg-layer-1-glyph-label active:bg-layer-1-glyph-shade active:bg-layer-1-glyph_a active:bg-layer-1-glyph_d active:bg-layer-1-glyph_pl active:bg-layer-1-surface active:bg-layer-1-surface-edge active:bg-layer-1-surface-err active:bg-layer-1-surface-focus active:bg-layer-1-surface_a active:bg-layer-2-glyph active:bg-layer-2-glyph-hl active:bg-layer-2-glyph-hl_a active:bg-layer-2-glyph-shade active:bg-layer-2-glyph_a active:bg-layer-2-glyph_d active:bg-layer-2-glyph_pl active:bg-layer-2-surface active:bg-layer-2-surface-edge active:bg-layer-2-surface_a active:bg-radroots-accent-focus active:border-layer-0-glyph active:border-layer-0-glyph-hl active:border-layer-0-glyph-hl_a active:border-layer-0-glyph-label active:border-layer-0-glyph-shade active:border-layer-0-glyph_a active:border-layer-0-glyph_pl active:border-layer-0-surface active:border-layer-0-surface-blur active:border-layer-0-surface-edge active:border-layer-0-surface_a active:border-layer-0-surface_w active:border-layer-1-glyph active:border-layer-1-glyph-hl active:border-layer-1-glyph-hl_a active:border-layer-1-glyph-label active:border-layer-1-glyph-shade active:border-layer-1-glyph_a active:border-layer-1-glyph_d active:border-layer-1-glyph_pl active:border-layer-1-surface active:border-layer-1-surface-edge active:border-layer-1-surface-err active:border-layer-1-surface-focus active:border-layer-1-surface_a active:border-layer-2-glyph active:border-layer-2-glyph-hl active:border-layer-2-glyph-hl_a active:border-layer-2-glyph-shade active:border-layer-2-glyph_a active:border-layer-2-glyph_d active:border-layer-2-glyph_pl active:border-layer-2-surface active:border-layer-2-surface-edge active:border-layer-2-surface_a active:border-radroots-accent-focus active:text-layer-0-glyph active:text-layer-0-glyph-hl active:text-layer-0-glyph-hl_a active:text-layer-0-glyph-label active:text-layer-0-glyph-shade active:text-layer-0-glyph_a active:text-layer-0-glyph_pl active:text-layer-0-surface active:text-layer-0-surface-blur active:text-layer-0-surface-edge active:text-layer-0-surface_a active:text-layer-0-surface_w active:text-layer-1-glyph active:text-layer-1-glyph-hl active:text-layer-1-glyph-hl_a active:text-layer-1-glyph-label active:text-layer-1-glyph-shade active:text-layer-1-glyph_a active:text-layer-1-glyph_d active:text-layer-1-glyph_pl active:text-layer-1-surface active:text-layer-1-surface-edge active:text-layer-1-surface-err active:text-layer-1-surface-focus active:text-layer-1-surface_a active:text-layer-2-glyph active:text-layer-2-glyph-hl active:text-layer-2-glyph-hl_a active:text-layer-2-glyph-shade active:text-layer-2-glyph_a active:text-layer-2-glyph_d active:text-layer-2-glyph_pl active:text-layer-2-surface active:text-layer-2-surface-edge active:text-layer-2-surface_a active:text-radroots-accent-focus bg-layer-0-glyph bg-layer-0-glyph-hl bg-layer-0-glyph-hl_a bg-layer-0-glyph-label bg-layer-0-glyph-shade bg-layer-0-glyph_a bg-layer-0-glyph_pl bg-layer-0-surface bg-layer-0-surface-blur bg-layer-0-surface-edge bg-layer-0-surface_a bg-layer-0-surface_w bg-layer-1-glyph bg-layer-1-glyph-hl bg-layer-1-glyph-hl_a bg-layer-1-glyph-label bg-layer-1-glyph-shade bg-layer-1-glyph_a bg-layer-1-glyph_d bg-layer-1-glyph_pl bg-layer-1-surface bg-layer-1-surface-edge bg-layer-1-surface-err bg-layer-1-surface-focus bg-layer-1-surface_a bg-layer-2-glyph bg-layer-2-glyph-hl bg-layer-2-glyph-hl_a bg-layer-2-glyph-shade bg-layer-2-glyph_a bg-layer-2-glyph_d bg-layer-2-glyph_pl bg-layer-2-surface bg-layer-2-surface-edge bg-layer-2-surface_a bg-radroots-accent-focus border-layer-0-glyph border-layer-0-glyph-hl border-layer-0-glyph-hl_a border-layer-0-glyph-label border-layer-0-glyph-shade border-layer-0-glyph_a border-layer-0-glyph_pl border-layer-0-surface border-layer-0-surface-blur border-layer-0-surface-edge border-layer-0-surface_a border-layer-0-surface_w border-layer-1-glyph border-layer-1-glyph-hl border-layer-1-glyph-hl_a border-layer-1-glyph-label border-layer-1-glyph-shade border-layer-1-glyph_a border-layer-1-glyph_d border-layer-1-glyph_pl border-layer-1-surface border-layer-1-surface-edge border-layer-1-surface-err border-layer-1-surface-focus border-layer-1-surface_a border-layer-2-glyph border-layer-2-glyph-hl border-layer-2-glyph-hl_a border-layer-2-glyph-shade border-layer-2-glyph_a border-layer-2-glyph_d border-layer-2-glyph_pl border-layer-2-surface border-layer-2-surface-edge border-layer-2-surface_a border-radroots-accent-focus bottom-lo_bottom_button_ios0 bottom-lo_bottom_button_ios1 bottom-lo_bottom_button_webm0 bottom-lo_bottom_button_webm1 bottom-lo_view_main_ios0 bottom-lo_view_main_ios1 bottom-lo_view_main_webm0 bottom-lo_view_main_webm1 bottom-nav_page_header_ios0 bottom-nav_page_header_ios1 bottom-nav_page_header_webm0 bottom-nav_page_header_webm1 bottom-nav_page_toolbar_ios0 bottom-nav_page_toolbar_ios1 bottom-nav_page_toolbar_webm0 bottom-nav_page_toolbar_webm1 bottom-nav_tabs_ios0 bottom-nav_tabs_ios1 bottom-nav_tabs_webm0 bottom-nav_tabs_webm1 focus:bg-layer-0-glyph focus:bg-layer-0-glyph-hl focus:bg-layer-0-glyph-hl_a focus:bg-layer-0-glyph-label focus:bg-layer-0-glyph-shade focus:bg-layer-0-glyph_a focus:bg-layer-0-glyph_pl focus:bg-layer-0-surface focus:bg-layer-0-surface-blur focus:bg-layer-0-surface-edge focus:bg-layer-0-surface_a focus:bg-layer-0-surface_w focus:bg-layer-1-glyph focus:bg-layer-1-glyph-hl focus:bg-layer-1-glyph-hl_a focus:bg-layer-1-glyph-label focus:bg-layer-1-glyph-shade focus:bg-layer-1-glyph_a focus:bg-layer-1-glyph_d focus:bg-layer-1-glyph_pl focus:bg-layer-1-surface focus:bg-layer-1-surface-edge focus:bg-layer-1-surface-err focus:bg-layer-1-surface-focus focus:bg-layer-1-surface_a focus:bg-layer-2-glyph focus:bg-layer-2-glyph-hl focus:bg-layer-2-glyph-hl_a focus:bg-layer-2-glyph-shade focus:bg-layer-2-glyph_a focus:bg-layer-2-glyph_d focus:bg-layer-2-glyph_pl focus:bg-layer-2-surface focus:bg-layer-2-surface-edge focus:bg-layer-2-surface_a focus:bg-radroots-accent-focus focus:border-layer-0-glyph focus:border-layer-0-glyph-hl focus:border-layer-0-glyph-hl_a focus:border-layer-0-glyph-label focus:border-layer-0-glyph-shade focus:border-layer-0-glyph_a focus:border-layer-0-glyph_pl focus:border-layer-0-surface focus:border-layer-0-surface-blur focus:border-layer-0-surface-edge focus:border-layer-0-surface_a focus:border-layer-0-surface_w focus:border-layer-1-glyph focus:border-layer-1-glyph-hl focus:border-layer-1-glyph-hl_a focus:border-layer-1-glyph-label focus:border-layer-1-glyph-shade focus:border-layer-1-glyph_a focus:border-layer-1-glyph_d focus:border-layer-1-glyph_pl focus:border-layer-1-surface focus:border-layer-1-surface-edge focus:border-layer-1-surface-err focus:border-layer-1-surface-focus focus:border-layer-1-surface_a focus:border-layer-2-glyph focus:border-layer-2-glyph-hl focus:border-layer-2-glyph-hl_a focus:border-layer-2-glyph-shade focus:border-layer-2-glyph_a focus:border-layer-2-glyph_d focus:border-layer-2-glyph_pl focus:border-layer-2-surface focus:border-layer-2-surface-edge focus:border-layer-2-surface_a focus:border-radroots-accent-focus focus:text-layer-0-glyph focus:text-layer-0-glyph-hl focus:text-layer-0-glyph-hl_a focus:text-layer-0-glyph-label focus:text-layer-0-glyph-shade focus:text-layer-0-glyph_a focus:text-layer-0-glyph_pl focus:text-layer-0-surface focus:text-layer-0-surface-blur focus:text-layer-0-surface-edge focus:text-layer-0-surface_a focus:text-layer-0-surface_w focus:text-layer-1-glyph focus:text-layer-1-glyph-hl focus:text-layer-1-glyph-hl_a focus:text-layer-1-glyph-label focus:text-layer-1-glyph-shade focus:text-layer-1-glyph_a focus:text-layer-1-glyph_d focus:text-layer-1-glyph_pl focus:text-layer-1-surface focus:text-layer-1-surface-edge focus:text-layer-1-surface-err focus:text-layer-1-surface-focus focus:text-layer-1-surface_a focus:text-layer-2-glyph focus:text-layer-2-glyph-hl focus:text-layer-2-glyph-hl_a focus:text-layer-2-glyph-shade focus:text-layer-2-glyph_a focus:text-layer-2-glyph_d focus:text-layer-2-glyph_pl focus:text-layer-2-surface focus:text-layer-2-surface-edge focus:text-layer-2-surface_a focus:text-radroots-accent-focus group-active:bg-layer-0-glyph group-active:bg-layer-0-glyph-hl group-active:bg-layer-0-glyph-hl_a group-active:bg-layer-0-glyph-label group-active:bg-layer-0-glyph-shade group-active:bg-layer-0-glyph_a group-active:bg-layer-0-glyph_pl group-active:bg-layer-0-surface group-active:bg-layer-0-surface-blur group-active:bg-layer-0-surface-edge group-active:bg-layer-0-surface_a group-active:bg-layer-0-surface_w group-active:bg-layer-1-glyph group-active:bg-layer-1-glyph-hl group-active:bg-layer-1-glyph-hl_a group-active:bg-layer-1-glyph-label group-active:bg-layer-1-glyph-shade group-active:bg-layer-1-glyph_a group-active:bg-layer-1-glyph_d group-active:bg-layer-1-glyph_pl group-active:bg-layer-1-surface group-active:bg-layer-1-surface-edge group-active:bg-layer-1-surface-err group-active:bg-layer-1-surface-focus group-active:bg-layer-1-surface_a group-active:bg-layer-2-glyph group-active:bg-layer-2-glyph-hl group-active:bg-layer-2-glyph-hl_a group-active:bg-layer-2-glyph-shade group-active:bg-layer-2-glyph_a group-active:bg-layer-2-glyph_d group-active:bg-layer-2-glyph_pl group-active:bg-layer-2-surface group-active:bg-layer-2-surface-edge group-active:bg-layer-2-surface_a group-active:bg-radroots-accent-focus group-active:border-layer-0-glyph group-active:border-layer-0-glyph-hl group-active:border-layer-0-glyph-hl_a group-active:border-layer-0-glyph-label group-active:border-layer-0-glyph-shade group-active:border-layer-0-glyph_a group-active:border-layer-0-glyph_pl group-active:border-layer-0-surface group-active:border-layer-0-surface-blur group-active:border-layer-0-surface-edge group-active:border-layer-0-surface_a group-active:border-layer-0-surface_w group-active:border-layer-1-glyph group-active:border-layer-1-glyph-hl group-active:border-layer-1-glyph-hl_a group-active:border-layer-1-glyph-label group-active:border-layer-1-glyph-shade group-active:border-layer-1-glyph_a group-active:border-layer-1-glyph_d group-active:border-layer-1-glyph_pl group-active:border-layer-1-surface group-active:border-layer-1-surface-edge group-active:border-layer-1-surface-err group-active:border-layer-1-surface-focus group-active:border-layer-1-surface_a group-active:border-layer-2-glyph group-active:border-layer-2-glyph-hl group-active:border-layer-2-glyph-hl_a group-active:border-layer-2-glyph-shade group-active:border-layer-2-glyph_a group-active:border-layer-2-glyph_d group-active:border-layer-2-glyph_pl group-active:border-layer-2-surface group-active:border-layer-2-surface-edge group-active:border-layer-2-surface_a group-active:border-radroots-accent-focus group-active:text-layer-0-glyph group-active:text-layer-0-glyph-hl group-active:text-layer-0-glyph-hl_a group-active:text-layer-0-glyph-label group-active:text-layer-0-glyph-shade group-active:text-layer-0-glyph_a group-active:text-layer-0-glyph_pl group-active:text-layer-0-surface group-active:text-layer-0-surface-blur group-active:text-layer-0-surface-edge group-active:text-layer-0-surface_a group-active:text-layer-0-surface_w group-active:text-layer-1-glyph group-active:text-layer-1-glyph-hl group-active:text-layer-1-glyph-hl_a group-active:text-layer-1-glyph-label group-active:text-layer-1-glyph-shade group-active:text-layer-1-glyph_a group-active:text-layer-1-glyph_d group-active:text-layer-1-glyph_pl group-active:text-layer-1-surface group-active:text-layer-1-surface-edge group-active:text-layer-1-surface-err group-active:text-layer-1-surface-focus group-active:text-layer-1-surface_a group-active:text-layer-2-glyph group-active:text-layer-2-glyph-hl group-active:text-layer-2-glyph-hl_a group-active:text-layer-2-glyph-shade group-active:text-layer-2-glyph_a group-active:text-layer-2-glyph_d group-active:text-layer-2-glyph_pl group-active:text-layer-2-surface group-active:text-layer-2-surface-edge group-active:text-layer-2-surface_a group-active:text-radroots-accent-focus group-focus:bg-layer-0-glyph group-focus:bg-layer-0-glyph-hl group-focus:bg-layer-0-glyph-hl_a group-focus:bg-layer-0-glyph-label group-focus:bg-layer-0-glyph-shade group-focus:bg-layer-0-glyph_a group-focus:bg-layer-0-glyph_pl group-focus:bg-layer-0-surface group-focus:bg-layer-0-surface-blur group-focus:bg-layer-0-surface-edge group-focus:bg-layer-0-surface_a group-focus:bg-layer-0-surface_w group-focus:bg-layer-1-glyph group-focus:bg-layer-1-glyph-hl group-focus:bg-layer-1-glyph-hl_a group-focus:bg-layer-1-glyph-label group-focus:bg-layer-1-glyph-shade group-focus:bg-layer-1-glyph_a group-focus:bg-layer-1-glyph_d group-focus:bg-layer-1-glyph_pl group-focus:bg-layer-1-surface group-focus:bg-layer-1-surface-edge group-focus:bg-layer-1-surface-err group-focus:bg-layer-1-surface-focus group-focus:bg-layer-1-surface_a group-focus:bg-layer-2-glyph group-focus:bg-layer-2-glyph-hl group-focus:bg-layer-2-glyph-hl_a group-focus:bg-layer-2-glyph-shade group-focus:bg-layer-2-glyph_a group-focus:bg-layer-2-glyph_d group-focus:bg-layer-2-glyph_pl group-focus:bg-layer-2-surface group-focus:bg-layer-2-surface-edge group-focus:bg-layer-2-surface_a group-focus:bg-radroots-accent-focus group-focus:border-layer-0-glyph group-focus:border-layer-0-glyph-hl group-focus:border-layer-0-glyph-hl_a group-focus:border-layer-0-glyph-label group-focus:border-layer-0-glyph-shade group-focus:border-layer-0-glyph_a group-focus:border-layer-0-glyph_pl group-focus:border-layer-0-surface group-focus:border-layer-0-surface-blur group-focus:border-layer-0-surface-edge group-focus:border-layer-0-surface_a group-focus:border-layer-0-surface_w group-focus:border-layer-1-glyph group-focus:border-layer-1-glyph-hl group-focus:border-layer-1-glyph-hl_a group-focus:border-layer-1-glyph-label group-focus:border-layer-1-glyph-shade group-focus:border-layer-1-glyph_a group-focus:border-layer-1-glyph_d group-focus:border-layer-1-glyph_pl group-focus:border-layer-1-surface group-focus:border-layer-1-surface-edge group-focus:border-layer-1-surface-err group-focus:border-layer-1-surface-focus group-focus:border-layer-1-surface_a group-focus:border-layer-2-glyph group-focus:border-layer-2-glyph-hl group-focus:border-layer-2-glyph-hl_a group-focus:border-layer-2-glyph-shade group-focus:border-layer-2-glyph_a group-focus:border-layer-2-glyph_d group-focus:border-layer-2-glyph_pl group-focus:border-layer-2-surface group-focus:border-layer-2-surface-edge group-focus:border-layer-2-surface_a group-focus:border-radroots-accent-focus group-focus:text-layer-0-glyph group-focus:text-layer-0-glyph-hl group-focus:text-layer-0-glyph-hl_a group-focus:text-layer-0-glyph-label group-focus:text-layer-0-glyph-shade group-focus:text-layer-0-glyph_a group-focus:text-layer-0-glyph_pl group-focus:text-layer-0-surface group-focus:text-layer-0-surface-blur group-focus:text-layer-0-surface-edge group-focus:text-layer-0-surface_a group-focus:text-layer-0-surface_w group-focus:text-layer-1-glyph group-focus:text-layer-1-glyph-hl group-focus:text-layer-1-glyph-hl_a group-focus:text-layer-1-glyph-label group-focus:text-layer-1-glyph-shade group-focus:text-layer-1-glyph_a group-focus:text-layer-1-glyph_d group-focus:text-layer-1-glyph_pl group-focus:text-layer-1-surface group-focus:text-layer-1-surface-edge group-focus:text-layer-1-surface-err group-focus:text-layer-1-surface-focus group-focus:text-layer-1-surface_a group-focus:text-layer-2-glyph group-focus:text-layer-2-glyph-hl group-focus:text-layer-2-glyph-hl_a group-focus:text-layer-2-glyph-shade group-focus:text-layer-2-glyph_a group-focus:text-layer-2-glyph_d group-focus:text-layer-2-glyph_pl group-focus:text-layer-2-surface group-focus:text-layer-2-surface-edge group-focus:text-layer-2-surface_a group-focus:text-radroots-accent-focus h-[12px] h-[16px] h-[17px] h-[18px] h-[20px] h-[22px] h-[24px] h-[28px] h-[36px] h-lo_bottom_button_ios0 h-lo_bottom_button_ios1 h-lo_bottom_button_webm0 h-lo_bottom_button_webm1 h-lo_view_main_ios0 h-lo_view_main_ios1 h-lo_view_main_webm0 h-lo_view_main_webm1 h-nav_page_header_ios0 h-nav_page_header_ios1 h-nav_page_header_webm0 h-nav_page_header_webm1 h-nav_page_toolbar_ios0 h-nav_page_toolbar_ios1 h-nav_page_toolbar_webm0 h-nav_page_toolbar_webm1 h-nav_tabs_ios0 h-nav_tabs_ios1 h-nav_tabs_webm0 h-nav_tabs_webm1 left-lo_ios0 left-lo_ios1 left-lo_line_entry_ios0 left-lo_line_entry_ios1 left-lo_line_entry_webm0 left-lo_line_entry_webm1 left-lo_textdesc_ios0 left-lo_textdesc_ios1 left-lo_textdesc_webm0 left-lo_textdesc_webm1 left-lo_webm0 left-lo_webm1 max-h-lo_bottom_button_ios0 max-h-lo_bottom_button_ios1 max-h-lo_bottom_button_webm0 max-h-lo_bottom_button_webm1 max-h-lo_view_main_ios0 max-h-lo_view_main_ios1 max-h-lo_view_main_webm0 max-h-lo_view_main_webm1 max-h-nav_page_header_ios0 max-h-nav_page_header_ios1 max-h-nav_page_header_webm0 max-h-nav_page_header_webm1 max-h-nav_page_toolbar_ios0 max-h-nav_page_toolbar_ios1 max-h-nav_page_toolbar_webm0 max-h-nav_page_toolbar_webm1 max-h-nav_tabs_ios0 max-h-nav_tabs_ios1 max-h-nav_tabs_webm0 max-h-nav_tabs_webm1 max-w-lo_ios0 max-w-lo_ios1 max-w-lo_line_entry_ios0 max-w-lo_line_entry_ios1 max-w-lo_line_entry_webm0 max-w-lo_line_entry_webm1 max-w-lo_textdesc_ios0 max-w-lo_textdesc_ios1 max-w-lo_textdesc_webm0 max-w-lo_textdesc_webm1 max-w-lo_webm0 max-w-lo_webm1 min-h-lo_bottom_button_ios0 min-h-lo_bottom_button_ios1 min-h-lo_bottom_button_webm0 min-h-lo_bottom_button_webm1 min-h-lo_view_main_ios0 min-h-lo_view_main_ios1 min-h-lo_view_main_webm0 min-h-lo_view_main_webm1 min-h-nav_page_header_ios0 min-h-nav_page_header_ios1 min-h-nav_page_header_webm0 min-h-nav_page_header_webm1 min-h-nav_page_toolbar_ios0 min-h-nav_page_toolbar_ios1 min-h-nav_page_toolbar_webm0 min-h-nav_page_toolbar_webm1 min-h-nav_tabs_ios0 min-h-nav_tabs_ios1 min-h-nav_tabs_webm0 min-h-nav_tabs_webm1 min-w-lo_ios0 min-w-lo_ios1 min-w-lo_line_entry_ios0 min-w-lo_line_entry_ios1 min-w-lo_line_entry_webm0 min-w-lo_line_entry_webm1 min-w-lo_textdesc_ios0 min-w-lo_textdesc_ios1 min-w-lo_textdesc_webm0 min-w-lo_textdesc_webm1 min-w-lo_webm0 min-w-lo_webm1 pb-h_lo_bottom_button_ios0 pb-h_lo_bottom_button_ios1 pb-h_lo_bottom_button_webm0 pb-h_lo_bottom_button_webm1 pb-h_lo_view_main_ios0 pb-h_lo_view_main_ios1 pb-h_lo_view_main_webm0 pb-h_lo_view_main_webm1 pb-h_nav_page_header_ios0 pb-h_nav_page_header_ios1 pb-h_nav_page_header_webm0 pb-h_nav_page_header_webm1 pb-h_nav_page_toolbar_ios0 pb-h_nav_page_toolbar_ios1 pb-h_nav_page_toolbar_webm0 pb-h_nav_page_toolbar_webm1 pb-h_nav_tabs_ios0 pb-h_nav_tabs_ios1 pb-h_nav_tabs_webm0 pb-h_nav_tabs_webm1 pl-w_lo_ios0 pl-w_lo_ios1 pl-w_lo_line_entry_ios0 pl-w_lo_line_entry_ios1 pl-w_lo_line_entry_webm0 pl-w_lo_line_entry_webm1 pl-w_lo_textdesc_ios0 pl-w_lo_textdesc_ios1 pl-w_lo_textdesc_webm0 pl-w_lo_textdesc_webm1 pl-w_lo_webm0 pl-w_lo_webm1 pr-w_lo_ios0 pr-w_lo_ios1 pr-w_lo_line_entry_ios0 pr-w_lo_line_entry_ios1 pr-w_lo_line_entry_webm0 pr-w_lo_line_entry_webm1 pr-w_lo_textdesc_ios0 pr-w_lo_textdesc_ios1 pr-w_lo_textdesc_webm0 pr-w_lo_textdesc_webm1 pr-w_lo_webm0 pr-w_lo_webm1 pt-h_lo_bottom_button_ios0 pt-h_lo_bottom_button_ios1 pt-h_lo_bottom_button_webm0 pt-h_lo_bottom_button_webm1 pt-h_lo_view_main_ios0 pt-h_lo_view_main_ios1 pt-h_lo_view_main_webm0 pt-h_lo_view_main_webm1 pt-h_nav_page_header_ios0 pt-h_nav_page_header_ios1 pt-h_nav_page_header_webm0 pt-h_nav_page_header_webm1 pt-h_nav_page_toolbar_ios0 pt-h_nav_page_toolbar_ios1 pt-h_nav_page_toolbar_webm0 pt-h_nav_page_toolbar_webm1 pt-h_nav_tabs_ios0 pt-h_nav_tabs_ios1 pt-h_nav_tabs_webm0 pt-h_nav_tabs_webm1 right-lo_ios0 right-lo_ios1 right-lo_line_entry_ios0 right-lo_line_entry_ios1 right-lo_line_entry_webm0 right-lo_line_entry_webm1 right-lo_textdesc_ios0 right-lo_textdesc_ios1 right-lo_textdesc_webm0 right-lo_textdesc_webm1 right-lo_webm0 right-lo_webm1 text-[12px] text-[15px] text-[16px] text-[18px] text-[19px] text-[20px] text-[21px] text-[23px] text-[24px] text-[26px] text-[27px] text-[28px] text-[30px] text-[36px] text-[40px] text-layer-0-glyph text-layer-0-glyph-hl text-layer-0-glyph-hl_a text-layer-0-glyph-label text-layer-0-glyph-shade text-layer-0-glyph_a text-layer-0-glyph_pl text-layer-0-surface text-layer-0-surface-blur text-layer-0-surface-edge text-layer-0-surface_a text-layer-0-surface_w text-layer-1-glyph text-layer-1-glyph-hl text-layer-1-glyph-hl_a text-layer-1-glyph-label text-layer-1-glyph-shade text-layer-1-glyph_a text-layer-1-glyph_d text-layer-1-glyph_pl text-layer-1-surface text-layer-1-surface-edge text-layer-1-surface-err text-layer-1-surface-focus text-layer-1-surface_a text-layer-2-glyph text-layer-2-glyph-hl text-layer-2-glyph-hl_a text-layer-2-glyph-shade text-layer-2-glyph_a text-layer-2-glyph_d text-layer-2-glyph_pl text-layer-2-surface text-layer-2-surface-edge text-layer-2-surface_a text-radroots-accent-focus top-lo_bottom_button_ios0 top-lo_bottom_button_ios1 top-lo_bottom_button_webm0 top-lo_bottom_button_webm1 top-lo_view_main_ios0 top-lo_view_main_ios1 top-lo_view_main_webm0 top-lo_view_main_webm1 top-nav_page_header_ios0 top-nav_page_header_ios1 top-nav_page_header_webm0 top-nav_page_header_webm1 top-nav_page_toolbar_ios0 top-nav_page_toolbar_ios1 top-nav_page_toolbar_webm0 top-nav_page_toolbar_webm1 top-nav_tabs_ios0 top-nav_tabs_ios1 top-nav_tabs_webm0 top-nav_tabs_webm1 translate-x-w_lo_ios0 translate-x-w_lo_ios1 translate-x-w_lo_line_entry_ios0 translate-x-w_lo_line_entry_ios1 translate-x-w_lo_line_entry_webm0 translate-x-w_lo_line_entry_webm1 translate-x-w_lo_textdesc_ios0 translate-x-w_lo_textdesc_ios1 translate-x-w_lo_textdesc_webm0 translate-x-w_lo_textdesc_webm1 translate-x-w_lo_webm0 translate-x-w_lo_webm1 translate-y-h_lo_bottom_button_ios0 translate-y-h_lo_bottom_button_ios1 translate-y-h_lo_bottom_button_webm0 translate-y-h_lo_bottom_button_webm1 translate-y-h_lo_view_main_ios0 translate-y-h_lo_view_main_ios1 translate-y-h_lo_view_main_webm0 translate-y-h_lo_view_main_webm1 translate-y-h_nav_page_header_ios0 translate-y-h_nav_page_header_ios1 translate-y-h_nav_page_header_webm0 translate-y-h_nav_page_header_webm1 translate-y-h_nav_page_toolbar_ios0 translate-y-h_nav_page_toolbar_ios1 translate-y-h_nav_page_toolbar_webm0 translate-y-h_nav_page_toolbar_webm1 translate-y-h_nav_tabs_ios0 translate-y-h_nav_tabs_ios1 translate-y-h_nav_tabs_webm0 translate-y-h_nav_tabs_webm1 w-[12px] w-[16px] w-[17px] w-[18px] w-[20px] w-[22px] w-[24px] w-[28px] w-[36px] w-lo_ios0 w-lo_ios1 w-lo_line_entry_ios0 w-lo_line_entry_ios1 w-lo_line_entry_webm0 w-lo_line_entry_webm1 w-lo_textdesc_ios0 w-lo_textdesc_ios1 w-lo_textdesc_webm0 w-lo_textdesc_webm1 w-lo_webm0 w-lo_webm1"></div>
-\ No newline at end of file
diff --git a/apps-lib/src/lib/components/lib/empty.svelte b/apps-lib/src/lib/components/lib/empty.svelte
@@ -1,3 +0,0 @@
-<div class={`flex flex-fill text-transparent bg-transparent`}>
- <p class={`font-sans`}>{`~`}</p>
-</div>
diff --git a/apps-lib/src/lib/components/lib/fade.svelte b/apps-lib/src/lib/components/lib/fade.svelte
@@ -1,22 +0,0 @@
-<script lang="ts">
- import { type IBasisOpt, type IClOpt } from "$root";
- import { fmt_cl } from "@radroots/util";
- import type { Snippet } from "svelte";
- import { fade, type FadeParams } from "svelte/transition";
-
- let {
- basis = undefined,
- children,
- }: {
- basis?: IBasisOpt<IClOpt> & { in?: FadeParams; out?: FadeParams };
- children: Snippet;
- } = $props();
-</script>
-
-<div
- in:fade={basis?.in || { duration: 200 }}
- out:fade={basis?.out || { delay: 50, duration: 200 }}
- class={`${fmt_cl(basis?.classes)} flex`}
->
- {@render children()}
-</div>
diff --git a/apps-lib/src/lib/components/lib/image-blob.svelte b/apps-lib/src/lib/components/lib/image-blob.svelte
@@ -1,26 +0,0 @@
-<script lang="ts">
- import { type IImageBlob } from "$root";
- import { fmt_cl } from "@radroots/util";
-
- let { basis }: { basis: IImageBlob } = $props();
-
- const img_src = $derived(
- basis.data
- ? URL.createObjectURL(
- new Blob([basis.data], {
- type: "image/jpeg",
- }),
- )
- : undefined,
- );
-</script>
-
-{#if img_src}
- <img
- id={basis?.id || null}
- class={`${fmt_cl(basis?.classes)}`}
- src={img_src || null}
- alt={basis?.alt || null}
- style={`height: 100%; width: 100%; object-fit: cover; display: block;`}
- />
-{/if}
diff --git a/apps-lib/src/lib/components/lib/image-path.svelte b/apps-lib/src/lib/components/lib/image-path.svelte
@@ -1,21 +0,0 @@
-<script lang="ts">
- import { get_context, ImageBlob, type IImagePath } from "$root";
- import ImageSrc from "./image-src.svelte";
-
- const { lc_img_bin } = get_context(`lib`);
- let { basis }: { basis: IImagePath } = $props();
-
- const img_path = $derived(basis.path);
-</script>
-
-{#if img_path}
- {@const is_bin = img_path.startsWith(`file:`)}
-
- {#if is_bin}
- {#await lc_img_bin(img_path) then data}
- <ImageBlob basis={{ data, ...basis }} />
- {/await}
- {:else}
- <ImageSrc basis={{ src: img_path, ...basis }} />
- {/if}
-{/if}
diff --git a/apps-lib/src/lib/components/lib/image-src.svelte b/apps-lib/src/lib/components/lib/image-src.svelte
@@ -1,18 +0,0 @@
-<script lang="ts">
- import { type IImageSource } from "$root";
- import { fmt_cl } from "@radroots/util";
-
- let { basis }: { basis: IImageSource } = $props();
-
- const img_src = $derived(basis.src);
-</script>
-
-{#if img_src}
- <img
- id={basis?.id || null}
- class={`${fmt_cl(basis?.classes)}`}
- src={img_src || null}
- alt={basis?.alt || null}
- style={`height: 100%; width: 100%; object-fit: cover; display: block;`}
- />
-{/if}
diff --git a/apps-lib/src/lib/components/lib/image.svelte b/apps-lib/src/lib/components/lib/image.svelte
@@ -1,16 +0,0 @@
-<script lang="ts">
- import { type IImage } from "$root";
- import { fmt_cl } from "@radroots/util";
-
- let { basis }: { basis: IImage } = $props();
-</script>
-
-{#if basis.src}
- <img
- id={basis?.id || null}
- class={`${fmt_cl(basis?.classes)}`}
- src={basis.src}
- alt={basis?.alt || null}
- style={`height: 100%; width: 100%; object-fit: cover; display: block;`}
- />
-{/if}
diff --git a/apps-lib/src/lib/components/lib/input-idb.svelte b/apps-lib/src/lib/components/lib/input-idb.svelte
@@ -1,120 +0,0 @@
-<script lang="ts">
- import { browser } from "$app/environment";
- import { handle_err, idb, type IInput } from "$root";
- import { fmt_cl, parse_layer, value_constrain } from "@radroots/util";
- import { onMount } from "svelte";
-
- let {
- basis,
- el = $bindable(null),
- value = $bindable(``),
- }: {
- basis: IInput<string>;
- el?: HTMLInputElement | null;
- value?: string;
- } = $props();
-
- const id = $derived(basis?.id ? basis.id : null);
- const layer = $derived(
- typeof basis?.layer === `boolean` ? 0 : parse_layer(basis?.layer),
- );
- const classes_layer = $derived(
- typeof basis?.layer === `boolean` || typeof basis?.layer === `undefined`
- ? ``
- : `bg-layer-${layer}-surface text-layer-${layer}-glyph_d placeholder:text-layer-${layer}-glyph_pl caret-layer-${layer}-glyph`,
- );
-
- let value_local = $state(value);
-
- const sync_from_idb = async (): Promise<void> => {
- if (!browser || !idb || !id) return;
- try {
- const kv_val = await idb.get(id);
- if (
- kv_val !== null &&
- kv_val !== undefined &&
- kv_val !== value_local
- ) {
- value_local = kv_val;
- } else if (kv_val === null || kv_val === undefined) {
- value_local = ``;
- await idb.set(id, ``);
- }
- } catch (e) {
- handle_err(e, `sync_from_idb`);
- }
- };
-
- const sync_to_idb = async (): Promise<void> => {
- if (!browser || !idb || !id) return;
- try {
- await idb.set(id, value_local || ``);
- } catch (e) {
- handle_err(e, `input_idb_sync`);
- }
- };
-
- onMount(async () => {
- await sync_from_idb();
- if (basis?.callback_mount && el) {
- try {
- await basis.callback_mount({ el });
- } catch (e) {
- handle_err(e, `callback_mount`);
- }
- }
- });
-
- $effect(() => {
- if (id && basis?.sync && browser && idb) {
- (async () => {
- await sync_to_idb();
- })();
- }
- });
-
- const handle_on_input = async (): Promise<void> => {
- try {
- let updatedVal = value_local;
- let pass = true;
- if (basis?.field) {
- updatedVal = value_constrain(basis.field.charset, updatedVal);
- if (updatedVal !== value_local) {
- value_local = updatedVal;
- }
- pass = basis.field.validate.test(updatedVal);
- }
- if (basis?.callback) {
- await basis.callback({ value: updatedVal, pass });
- }
- } catch (e) {
- handle_err(e, `handle_on_input`);
- }
- };
-</script>
-
-<input
- bind:this={el}
- bind:value={value_local}
- disabled={!!basis.disabled}
- oninput={async () => await handle_on_input()}
- onblur={async ({ currentTarget: el }) => {
- if (basis.callback_blur) await basis.callback_blur({ el });
- }}
- onfocus={async ({ currentTarget: el }) => {
- if (id && basis.sync && browser && idb) await sync_from_idb();
- if (basis.callback_focus) await basis.callback_focus({ el });
- }}
- onkeydown={async (ev) => {
- if (basis?.callback_keydown)
- await basis.callback_keydown({
- key: ev.key,
- key_s: ev.key === `Enter`,
- el: ev.currentTarget,
- });
- }}
- {id}
- type="text"
- class={`${fmt_cl(basis?.classes)} el-input ${classes_layer} el-re`}
- placeholder={basis?.placeholder || ``}
-/>
diff --git a/apps-lib/src/lib/components/lib/input-value.svelte b/apps-lib/src/lib/components/lib/input-value.svelte
@@ -1,67 +0,0 @@
-<script lang="ts">
- import { type IInputValue } from "$root";
- import { fmt_cl, parse_layer, value_constrain } from "@radroots/util";
-
- let {
- basis,
- el = $bindable(null),
- value = $bindable(``),
- }: {
- basis: IInputValue<string>;
- el?: HTMLInputElement | null;
- value: string;
- } = $props();
-
- const id = $derived(basis?.id ? basis.id : null);
- const layer = $derived(
- typeof basis?.layer === `boolean`
- ? parse_layer(0)
- : parse_layer(basis?.layer),
- );
-
- const classes_layer = $derived(
- typeof basis?.layer === `boolean` || typeof basis?.layer === `undefined`
- ? ``
- : `bg-layer-${layer}-surface text-layer-${layer}-glyph placeholder:text-layer-${layer}-glyph_pl caret-layer-${layer}-glyph`,
- );
-
- const handle_on_input = async (): Promise<void> => {
- try {
- let val_cur = value;
- let pass = true;
- if (basis?.field) {
- val_cur = value_constrain(basis.field.charset, val_cur);
- if (val_cur !== value) value = val_cur;
- pass = basis.field.validate.test(val_cur);
- }
- if (basis?.callback) await basis.callback({ value: val_cur, pass });
- } catch (e) {
- console.error(`(error) handle_on_input`, e);
- }
- };
-</script>
-
-<input
- bind:this={el}
- bind:value
- disabled={!!basis.disabled}
- oninput={handle_on_input}
- onblur={async ({ currentTarget: el }) => {
- if (basis.callback_blur) await basis.callback_blur({ el });
- }}
- onfocus={async ({ currentTarget: el }) => {
- if (basis.callback_focus) await basis.callback_focus({ el });
- }}
- onkeydown={async (ev) => {
- if (basis?.callback_keydown)
- await basis.callback_keydown({
- key: ev.key,
- key_s: ev.key === `Enter`,
- el: ev.currentTarget,
- });
- }}
- {id}
- type="text"
- class={`${fmt_cl(basis?.classes)} el-input ${classes_layer} el-re`}
- placeholder={basis?.placeholder || ``}
-/>
diff --git a/apps-lib/src/lib/components/lib/input.svelte b/apps-lib/src/lib/components/lib/input.svelte
@@ -1,114 +0,0 @@
-<script lang="ts">
- import { browser } from "$app/environment";
- import { handle_err, idb, type IInput } from "$root";
- import { fmt_cl, parse_layer, value_constrain } from "@radroots/util";
- import { onMount } from "svelte";
-
- let {
- basis,
- el = $bindable(null),
- value = $bindable(``),
- }: {
- basis: IInput<string>;
- el?: HTMLInputElement | null;
- value?: string;
- } = $props();
-
- const id = $derived(basis?.id ? basis.id : null);
- const layer = $derived(
- typeof basis?.layer === `boolean` ? 0 : parse_layer(basis?.layer),
- );
- const classes_layer = $derived(
- typeof basis?.layer === `boolean` || typeof basis?.layer === `undefined`
- ? ``
- : `bg-layer-${layer}-surface text-layer-${layer}-glyph_d placeholder:text-layer-${layer}-glyph_pl caret-layer-${layer}-glyph`,
- );
-
- const sync_from_idb = async (): Promise<void> => {
- if (!browser || !idb || !id) return;
- try {
- const kv_val = await idb.get(id);
- if (kv_val !== null && kv_val !== undefined && kv_val !== value) {
- value = kv_val;
- } else if (kv_val === null || kv_val === undefined) {
- value = ``;
- await idb.set(id, ``);
- }
- } catch (e) {
- handle_err(e, `sync_from_idb`);
- }
- };
-
- const sync_to_idb = async (): Promise<void> => {
- if (!browser || !idb || !id) return;
- try {
- await idb.set(id, value || ``);
- } catch (e) {
- handle_err(e, `input_idb_sync`);
- }
- };
-
- onMount(async () => {
- await sync_from_idb();
- if (basis?.callback_mount && el) {
- try {
- await basis.callback_mount({ el });
- } catch (e) {
- handle_err(e, `callback_mount`);
- }
- }
- });
-
- $effect(() => {
- if (id && basis?.sync && browser && idb) {
- (async () => {
- await sync_to_idb();
- })();
- }
- });
-
- const handle_on_input = async (): Promise<void> => {
- try {
- let val_cur = value;
- let pass = true;
- if (basis?.field) {
- val_cur = value_constrain(basis.field?.charset, val_cur);
- if (val_cur !== value) {
- value = val_cur;
- }
- pass = basis.field?.validate.test(val_cur);
- }
- if (basis?.callback) {
- await basis.callback({ value: val_cur, pass });
- }
- } catch (e) {
- handle_err(e, `handle_on_input`);
- }
- };
-</script>
-
-<input
- bind:this={el}
- bind:value
- disabled={!!basis.disabled}
- oninput={handle_on_input}
- onblur={async ({ currentTarget: el }) => {
- if (basis.callback_blur) await basis.callback_blur({ el });
- }}
- onfocus={async ({ currentTarget: el }) => {
- if (id && basis.sync && browser && idb) await sync_from_idb();
- if (basis.callback_focus) await basis.callback_focus({ el });
- }}
- onkeydown={async (ev) => {
- if (basis?.callback_keydown)
- await basis.callback_keydown({
- key: ev.key,
- key_s: ev.key === `Enter`,
- el: ev.currentTarget,
- });
- }}
- {id}
- type="text"
- class={`${fmt_cl(basis?.classes)} el-input ${classes_layer} el-re`}
- placeholder={basis?.placeholder || ``}
-/>
diff --git a/apps-lib/src/lib/components/lib/label-swap.svelte b/apps-lib/src/lib/components/lib/label-swap.svelte
@@ -1,37 +0,0 @@
-<script lang="ts">
- import { type ILabelSwap, type ILyOpt } from "$root";
- import { fmt_cl, parse_layer } from "@radroots/util";
-
- let {
- basis,
- el = $bindable(null),
- }: {
- basis: ILabelSwap & ILyOpt;
- el?: HTMLLabelElement | null;
- } = $props();
-
- const layer = $derived(parse_layer(basis?.layer ? basis.layer : 1));
-</script>
-
-<div class={`flex flex-row justify-start items-center`}>
- <!-- svelte-ignore a11y_label_has_associated_control -->
- <label
- bind:this={el}
- class={`swap${basis.swap.toggle ? ` swap-active` : ``}`}
- >
- <div class="swap-on">
- <p
- class={`${fmt_cl(basis.swap.on.classes || `text-nav_prev text-layer-${layer}-glyph-hl group-active:opacity-60`)} font-sans -translate-y-[1px] el-re`}
- >
- {basis.swap.on.value}
- </p>
- </div>
- <div class="swap-off">
- <p
- class={`${fmt_cl(basis.swap.off.classes || `text-nav_prev text-layer-${layer}-glyph-hl group-active:opacity-60`)} font-sans -translate-y-[1px] el-re`}
- >
- {basis.swap.off.value}
- </p>
- </div>
- </label>
-</div>
diff --git a/apps-lib/src/lib/components/lib/load-symbol-white.svelte b/apps-lib/src/lib/components/lib/load-symbol-white.svelte
@@ -1,70 +0,0 @@
-<script lang="ts">
- import { loading_style_map, type ILoadSymbol } from "$root";
-
- let {
- basis = undefined,
- }: {
- basis?: ILoadSymbol;
- } = $props();
-
- const styles = $derived(
- basis?.dim
- ? loading_style_map.get(basis?.dim)
- : loading_style_map.get("sm"),
- );
-
- const num_blades = $derived(basis?.blades || 8);
-</script>
-
-<div
- class={`relative flex flex-row justify-center items-center h-[${styles?.dim_1}px] w-[${styles?.dim_1}px] fade-in el-re`}
->
- <div
- class={`${num_blades === 12 ? `spinner12-white center` : `spinner8-white center`} text-[${styles?.gl_2 || styles?.dim_1}px]`}
- >
- <div
- class={`${num_blades === 12 ? `spinner12-blade-white` : `spinner8-blade-white`}`}
- ></div>
- <div
- class={`${num_blades === 12 ? `spinner12-blade-white` : `spinner8-blade-white`}`}
- ></div>
- <div
- class={`${num_blades === 12 ? `spinner12-blade-white` : `spinner8-blade-white`}`}
- ></div>
- <div
- class={`${num_blades === 12 ? `spinner12-blade-white` : `spinner8-blade-white`}`}
- ></div>
- <div
- class={`${num_blades === 12 ? `spinner12-blade-white` : `spinner8-blade-white`}`}
- ></div>
- <div
- class={`${num_blades === 12 ? `spinner12-blade-white` : `spinner8-blade-white`}`}
- ></div>
- <div
- class={`${num_blades === 12 ? `spinner12-blade-white` : `spinner8-blade-white`}`}
- ></div>
- <div
- class={`${num_blades === 12 ? `spinner12-blade-white` : `spinner8-blade-white`}`}
- ></div>
- {#if num_blades === 12}
- <div
- class={`${num_blades === 12 ? `spinner12-blade-white` : `spinner8-blade-white`}`}
- ></div>
- <div
- class={`${num_blades === 12 ? `spinner12-blade-white` : `spinner8-blade-white`}`}
- ></div>
- <div
- class={`${num_blades === 12 ? `spinner12-blade-white` : `spinner8-blade-white`}`}
- ></div>
- <div
- class={`${num_blades === 12 ? `spinner12-blade-white` : `spinner8-blade-white`}`}
- ></div>
- <div
- class={`${num_blades === 12 ? `spinner12-blade-white` : `spinner8-blade-white`}`}
- ></div>
- <div
- class={`${num_blades === 12 ? `spinner12-blade-white` : `spinner8-blade-white`}`}
- ></div>
- {/if}
- </div>
-</div>
diff --git a/apps-lib/src/lib/components/lib/load-symbol.svelte b/apps-lib/src/lib/components/lib/load-symbol.svelte
@@ -1,70 +0,0 @@
-<script lang="ts">
- import { type ILoadSymbol, loading_style_map } from "$root";
-
- let {
- basis = undefined,
- }: {
- basis?: ILoadSymbol;
- } = $props();
-
- const styles = $derived(
- basis?.dim
- ? loading_style_map.get(basis?.dim)
- : loading_style_map.get("sm"),
- );
-
- const num_blades = $derived(basis?.blades || 8);
-</script>
-
-<div
- class={`relative flex flex-row justify-center items-center h-[${styles?.dim_1}px] w-[${styles?.dim_1}px] fade-in el-re`}
->
- <div
- class={`${num_blades === 12 ? `spinner12 center` : `spinner8 center`} text-[${styles?.gl_2 || styles?.dim_1}px]`}
- >
- <div
- class={`${num_blades === 12 ? `spinner12-blade` : `spinner8-blade`}`}
- ></div>
- <div
- class={`${num_blades === 12 ? `spinner12-blade` : `spinner8-blade`}`}
- ></div>
- <div
- class={`${num_blades === 12 ? `spinner12-blade` : `spinner8-blade`}`}
- ></div>
- <div
- class={`${num_blades === 12 ? `spinner12-blade` : `spinner8-blade`}`}
- ></div>
- <div
- class={`${num_blades === 12 ? `spinner12-blade` : `spinner8-blade`}`}
- ></div>
- <div
- class={`${num_blades === 12 ? `spinner12-blade` : `spinner8-blade`}`}
- ></div>
- <div
- class={`${num_blades === 12 ? `spinner12-blade` : `spinner8-blade`}`}
- ></div>
- <div
- class={`${num_blades === 12 ? `spinner12-blade` : `spinner8-blade`}`}
- ></div>
- {#if num_blades === 12}
- <div
- class={`${num_blades === 12 ? `spinner12-blade` : `spinner8-blade`}`}
- ></div>
- <div
- class={`${num_blades === 12 ? `spinner12-blade` : `spinner8-blade`}`}
- ></div>
- <div
- class={`${num_blades === 12 ? `spinner12-blade` : `spinner8-blade`}`}
- ></div>
- <div
- class={`${num_blades === 12 ? `spinner12-blade` : `spinner8-blade`}`}
- ></div>
- <div
- class={`${num_blades === 12 ? `spinner12-blade` : `spinner8-blade`}`}
- ></div>
- <div
- class={`${num_blades === 12 ? `spinner12-blade` : `spinner8-blade`}`}
- ></div>
- {/if}
- </div>
-</div>
diff --git a/apps-lib/src/lib/components/lib/logo-circle-sm.svelte b/apps-lib/src/lib/components/lib/logo-circle-sm.svelte
@@ -1,14 +0,0 @@
-<div
- class={`relative flex flex-row h-12 w-12 justify-center items-center bg-layer-2-surface rounded-full`}
->
- <p
- class={`font-sans font-[900] text-[1.5rem] text-layer-0-glyph -tracking-[0.4rem] -translate-x-[2px]`}
- >
- {"»`,"}
- </p>
- <p
- class={`font-sans font-[900] text-[1.5rem] text-layer-0-glyph translate-x-[3px]`}
- >
- {"-"}
- </p>
-</div>
diff --git a/apps-lib/src/lib/components/lib/logo-letters.svelte b/apps-lib/src/lib/components/lib/logo-letters.svelte
@@ -1,5 +0,0 @@
-<p
- class={`font-sansd italic font-[700] text-[1.7rem] text-layer-0-glyph lowercase`}
->
- {`radroots`}
-</p>
diff --git a/apps-lib/src/lib/components/lib/logo_circle.svelte b/apps-lib/src/lib/components/lib/logo_circle.svelte
@@ -1,18 +0,0 @@
-<div
- class={`relative flex flex-col h-[196px] w-full justify-center items-center`}
->
- <div
- class={`relative flex flex-row h-36 w-36 justify-center items-center bg-layer-2-surface rounded-full`}
- >
- <p
- class={`font-sans font-[900] text-6xl text-layer-0-glyph -tracking-[0.4rem] -translate-x-[6px]`}
- >
- {"»`,"}
- </p>
- <p
- class={`font-sans font-[900] text-6xl text-layer-0-glyph translate-x-[8px]`}
- >
- {"-"}
- </p>
- </div>
-</div>
diff --git a/apps-lib/src/lib/components/lib/select-menu.svelte b/apps-lib/src/lib/components/lib/select-menu.svelte
@@ -1,80 +0,0 @@
-<script lang="ts">
- import { type ISelect } from "$root";
- import { fmt_cl, parse_layer } from "@radroots/util";
- import type { Snippet } from "svelte";
-
- let {
- basis,
- value = $bindable(``),
- el_wrap = $bindable(null),
- el_select = $bindable(null),
- children,
- }: {
- basis: ISelect;
- value: string;
- el_wrap?: HTMLDivElement | null;
- el_select?: HTMLSelectElement | null;
- children?: Snippet;
- } = $props();
-
- const layer = $derived(
- parse_layer(typeof basis?.layer === `boolean` ? basis.layer : 0),
- );
-
- const classes_layer = $derived(
- typeof basis?.layer === `boolean` ? `` : `text-layer-${layer}-glyph`,
- );
-</script>
-
-<div
- class={`relative flex flex-row h-max w-auto justify-center items-center`}
- bind:this={el_wrap}
->
- <div
- class={`${fmt_cl(basis.classes)} z-20 absolute top-0 left-0 flex flex-row h-full w-full justify-end items-center ${classes_layer}`}
- >
- <select
- class={`select select-ghost h-full w-full bg-transparent focus:border-0 focus:outline-0 text-transparent focus:text-transparent`}
- bind:this={el_select}
- bind:value
- onchange={async (e) => {
- const opt = basis.options
- .map((i) => i.entries)
- .reduce((_, j) => j, [])
- .find(
- (k: { value: string }) =>
- k.value === e.currentTarget?.value,
- );
- if (basis.callback && opt) await basis.callback(opt);
- if (el_select) el_select.value = value;
- }}
- >
- {#each basis.options as opt_g}
- {#if opt_g.group}
- <optgroup>
- {#each opt_g.entries as opt}
- <option
- label={opt_g.group === true
- ? `-`.repeat(21)
- : opt_g.group || ``}
- >
- {opt.label}
- </option>
- {/each}
- </optgroup>
- {:else}
- {#each opt_g.entries as opt}
- <option value={opt.value} disabled={!!opt.disabled}>
- {opt.label}
- </option>
- {/each}
- {/if}
- {/each}
- </select>
- </div>
- {#if children}
- <div class={`z-10 flex flex-row h-full w-full`}>
- {@render children()}
- </div>
- {/if}
-</div>
diff --git a/apps-lib/src/lib/components/lib/select.svelte b/apps-lib/src/lib/components/lib/select.svelte
@@ -1,120 +0,0 @@
-<script lang="ts">
- import { browser } from "$app/environment";
- import { Glyph, handle_err, idb, type ISelect } from "$root";
- import { fmt_cl, parse_layer } from "@radroots/util";
- import { onMount } from "svelte";
-
- let {
- basis,
- value = $bindable(``),
- el = $bindable(null),
- }: {
- basis: ISelect;
- value: string;
- el?: HTMLSelectElement | null;
- } = $props();
-
- const id = $derived(basis?.id ? basis.id : null);
-
- const layer = $derived(
- typeof basis?.layer === `boolean`
- ? parse_layer(0)
- : parse_layer(basis.layer),
- );
-
- const classes_layer = $derived(
- typeof basis?.layer === `boolean`
- ? ``
- : !value
- ? `text-layer-${layer}-glyph/60`
- : `text-layer-${layer}-glyph_d`,
- );
-
- onMount(async () => {
- try {
- if (id && basis?.sync_init && browser) {
- const sync_val = await idb.get(id);
- await idb.set(id, sync_val || ``);
- }
- } catch (e) {
- handle_err(e, `on_mount`);
- }
- });
-
- $effect(() => {
- if (browser && id && basis?.sync) {
- (async () => {
- await idb.set(id, value);
- })();
- }
- });
-
- const handle_on_change = async (el: HTMLSelectElement): Promise<void> => {
- try {
- const opt = basis.options
- .map((i) => i.entries)
- .reduce((_, j) => j, [])
- .find((k) => k.value === el?.value);
- if (el) el.value = value;
- if (basis?.sync && id && browser) await idb.set(id, value);
- if (basis.callback && opt) await basis.callback(opt);
- } catch (e) {
- console.log(`(error) handle_on_change `, e);
- }
- };
-</script>
-
-{#if basis?.show_arrows === "l"}
- <div class={`flex flex-row pr-[2px] justify-center items-center`}>
- <Glyph
- basis={{
- key: `caret-up-down`,
- dim: `xs`,
-
- classes: `text-layer-${layer}-glyph translate-y-[1px]`,
- }}
- />
- </div>
-{/if}
-<select
- bind:this={el}
- bind:value
- onchange={async ({ currentTarget: el }) => {
- handle_on_change(el);
- }}
- {id}
- class={`${fmt_cl(basis.classes)} z-10 el-select ${classes_layer}`}
->
- {#each basis.options as opt_g}
- {#if opt_g.group}
- <optgroup>
- {#each opt_g.entries as opt}
- <option
- label={opt_g.group === true
- ? `-`.repeat(21)
- : opt_g.group || ``}
- >
- {opt.label}
- </option>
- {/each}
- </optgroup>
- {:else}
- {#each opt_g.entries as opt}
- <option value={opt.value} disabled={!!opt.disabled}>
- {opt.label}
- </option>
- {/each}
- {/if}
- {/each}
-</select>
-{#if basis?.show_arrows === "r"}
- <div class={`flex flex-row pl-[2px] justify-center items-center`}>
- <Glyph
- basis={{
- key: `caret-up-down`,
- dim: `xs`,
- classes: `text-layer-${layer}-glyph`,
- }}
- />
- </div>
-{/if}
diff --git a/apps-lib/src/lib/components/lib/splash_screen.svelte b/apps-lib/src/lib/components/lib/splash_screen.svelte
@@ -1,14 +0,0 @@
-<script lang="ts">
- import { LogoCircle } from "$root";
-</script>
-
-<div
- class={`z-50 absolute top-0 left-0 flex flex-col h-[100vh] w-full justify-center items-center bg-layer-0-surface`}
->
- <LogoCircle />
- <p
- class={`font-sansd italic font-[700] text-[1.2rem] text-layer-0-glyph lowercase -translate-y-2`}
- >
- {`radroots`}
- </p>
-</div>
diff --git a/apps-lib/src/lib/components/lib/swipe.svelte b/apps-lib/src/lib/components/lib/swipe.svelte
@@ -1,45 +0,0 @@
-<script lang="ts">
- import type { Snippet } from "svelte";
- import { fade } from "svelte/transition";
-
- const DELTA_X_THRESHOLD = 120;
-
- let {
- visible = $bindable(false),
- children,
- }: {
- visible: boolean;
- children: Snippet;
- } = $props();
-
- let swipe_start_x = $state<number | null>(null);
- let swipe_delta_x = $state<number>(0);
-
- const on_pointer_down = (event: PointerEvent): void => {
- swipe_start_x = event.clientX;
- };
-
- const on_pointer_move = (event: PointerEvent): void => {
- if (swipe_start_x !== null)
- swipe_delta_x = event.clientX - swipe_start_x;
- };
-
- const on_pointer_up = (): void => {
- if (Math.abs(swipe_delta_x) > DELTA_X_THRESHOLD) visible = false;
- swipe_start_x = null;
- swipe_delta_x = 0;
- };
-</script>
-
-{#if visible}
- <div
- out:fade={{ duration: 100 }}
- class={`flex flex-row w-full`}
- onpointerdown={on_pointer_down}
- onpointermove={on_pointer_move}
- onpointerup={on_pointer_up}
- style="transform: translateX({swipe_delta_x}px); transition: transform 0.2s ease;"
- >
- {@render children()}
- </div>
-{/if}
diff --git a/apps-lib/src/lib/components/lib/text-area.svelte b/apps-lib/src/lib/components/lib/text-area.svelte
@@ -1,76 +0,0 @@
-<script lang="ts">
- import { browser } from "$app/environment";
- import { idb, type ITextArea } from "$root";
- import {
- fmt_cl,
- fmt_textarea_value,
- parse_layer,
- value_constrain_textarea,
- } from "@radroots/util";
-
- let {
- basis,
- value = $bindable(``),
- el = $bindable(null),
- }: {
- basis: ITextArea;
- value?: string;
- el?: HTMLTextAreaElement | null;
- } = $props();
-
- const id = $derived(basis?.id ? basis.id : null);
- const layer = $derived(
- typeof basis.layer === `boolean` ? 0 : parse_layer(basis.layer, 1),
- );
-
- $effect(() => {
- if (browser && id && basis?.sync && value) idb.set(id, value);
- });
-
- const handle_on_input = async (el: HTMLTextAreaElement): Promise<void> => {
- try {
- let pass = true;
- let val = el?.value;
- if (basis?.field && el) {
- val = value_constrain_textarea(basis?.field.charset, val);
- el.value = fmt_textarea_value(val);
- if (
- !basis?.field.validate.test(val) &&
- basis?.field_constrain
- ) {
- //@todo set styles
- }
- pass = basis?.field.validate.test(val);
- }
- if (basis?.callback) await basis?.callback({ value: val, pass });
- } catch (e) {
- console.log(`(error) handle_on_input `, e);
- }
- };
-</script>
-
-<textarea
- bind:this={el}
- bind:value
- oninput={async ({ currentTarget: el }) => {
- await handle_on_input(el);
- }}
- onblur={async ({ currentTarget: el }) => {
- if (basis.callback_blur) await basis.callback_blur({ el });
- }}
- onfocus={async ({ currentTarget: el }) => {
- if (basis.callback_focus) await basis.callback_focus({ el });
- }}
- onkeydown={async (ev) => {
- if (basis.callback_keydown)
- await basis.callback_keydown({
- key: ev.key,
- key_s: ev.key === `Enter`,
- el: ev.currentTarget,
- });
- }}
- {id}
- contenteditable="true"
- class={`${fmt_cl(basis.classes)} el-textarea py-4 px-[18px] w-full bg-layer-${layer}-surface text-layer-${layer}-glyph_d placeholder:text-layer-${layer}-glyph_pl caret-layer-${layer}-glyph`}
- placeholder={basis.placeholder || ``}
-></textarea>
diff --git a/apps-lib/src/lib/components/lib/theme.svelte b/apps-lib/src/lib/components/lib/theme.svelte
@@ -1,17 +0,0 @@
-<script lang="ts">
- import { browser } from "$app/environment";
- import { app_th, app_thc, theme_set } from "$root";
- import { parse_color_mode, parse_theme_key } from "@radroots/theme";
-
- app_thc.subscribe(
- (_app_thc) =>
- browser &&
- theme_set(parse_theme_key($app_thc), parse_color_mode(_app_thc)),
- );
-
- app_th.subscribe(
- (_app_th) =>
- browser &&
- theme_set(parse_theme_key(_app_th), parse_color_mode($app_thc)),
- );
-</script>
diff --git a/apps-lib/src/lib/components/lib/toast.svelte b/apps-lib/src/lib/components/lib/toast.svelte
@@ -1,53 +0,0 @@
-<script lang="ts">
- import {
- app_lo,
- Glyph,
- toast_layout_map,
- toast_style_map,
- type IToast,
- type IToastKind,
- } from "$root";
-
- import { fmt_cl, get_layout_default, parse_layer } from "@radroots/util";
-
- let { basis }: { basis: IToast } = $props();
-
- const styles: IToastKind[] = $derived(
- basis?.styles ? basis.styles : [`simple`],
- );
- const layout = $derived(get_layout_default($app_lo));
- const layer = $derived(basis.layer ? parse_layer(basis.layer) : 1);
-</script>
-
-<div
- class={`${fmt_cl(toast_layout_map.get(layout))} z-[1000] h-[100vh] toast w-full ${basis.position || `top-center`} `}
->
- <div class={`flex flex-row w-full h-max justify-center pb-2`}>
- <div
- class={`${fmt_cl(basis.classes)} relative grid grid-cols-12 h-max items-center justify-center ${styles.includes(`simple`) ? `bg-layer-${layer}-surface` : ``} ${fmt_cl(styles.map((style) => fmt_cl(toast_style_map.get(style)?.outer)).join(` `))}`}
- >
- <div
- class={`absolute top-0 left-4 flex flex-row h-full items-center text-layer-${layer}-glyph`}
- >
- <Glyph
- basis={{
- key: `info`,
- dim: `md`,
- ...basis.glyph,
- }}
- />
- </div>
- <div
- class={`col-span-12 flex flex-row pl-1 ${fmt_cl(styles.map((style) => fmt_cl(toast_style_map.get(style)?.inner)).join(` `))}`}
- >
- {#if `value` in basis.label}
- <p
- class={`font-sans font-[500] truncate text-layer-${layer}-glyph -translate-y-[1px]`}
- >
- {basis.label.value}
- </p>
- {/if}
- </div>
- </div>
- </div>
-</div>
diff --git a/apps-lib/src/lib/components/lib/wrap-border.svelte b/apps-lib/src/lib/components/lib/wrap-border.svelte
@@ -1,23 +0,0 @@
-<script lang="ts">
- import { type IClOpt } from "$root";
- import { fmt_cl } from "@radroots/util";
- import type { Snippet } from "svelte";
-
- let {
- basis,
- children,
- }: {
- basis: IClOpt;
- children: Snippet;
- } = $props();
-</script>
-
-<div
- class={`${fmt_cl(basis.classes)} relative flex flex-col w-full py-[4px] px-[4px] justify-start items-center rounded-[32px] overflow-hidden bg-white shadow-sm`}
->
- <div
- class={`flex flex-row h-full w-full justify-center items-center bg-white/30 overflow-hidden rounded-[28px]`}
- >
- {@render children()}
- </div>
-</div>
diff --git a/apps-lib/src/lib/components/map/map-marker-area-display.svelte b/apps-lib/src/lib/components/map/map-marker-area-display.svelte
@@ -1,57 +0,0 @@
-<script lang="ts">
- import { Fade, Glyph, type IBasisOpt } from "$root";
-
- let {
- basis = undefined,
- }: {
- basis?: IBasisOpt<{
- primary: string;
- admin: string;
- country: string;
- }>;
- } = $props();
-</script>
-
-{#if basis}
- <Fade
- basis={{
- classes: `flex-col w-full justify-center items-start`,
- }}
- >
- <div
- class={`flex flex-col w-fit px-5 py-[10px] justify-start items-start bg-layer-1-surface rounded-3xl shadow-lg`}
- >
- <div class={`flex flex-col w-full gap-1 justify-start items-start`}>
- <div class={`flex flex-row gap-1 justify-start items-center`}>
- <p
- class={`font-sans font-[600] text-[0.95rem] text-layer-2-glyph`}
- >
- {basis.primary}
- </p>
- <Glyph
- basis={{
- classes: `text-layer-2-glyph -translate-y-[2px]`,
- dim: `xs`,
-
- key: `map-pin-simple`,
- }}
- />
- </div>
- <div
- class={`flex flex-row w-full gap-1 justify-start items-center`}
- >
- <p
- class={`font-sans font-[600] text-[0.95rem] tracking-tight text-layer-2-glyph`}
- >
- {`${basis.admin},`}
- </p>
- <p
- class={`font-sans font-[600] text-[0.95rem] tracking-tight text-layer-2-glyph`}
- >
- {`${basis.country}`}
- </p>
- </div>
- </div>
- </div>
- </Fade>
-{/if}
diff --git a/apps-lib/src/lib/components/map/map-marker-area.svelte b/apps-lib/src/lib/components/map/map-marker-area.svelte
@@ -1,49 +0,0 @@
-<script lang="ts">
- import {
- get_context,
- MapMarkerAreaDisplay,
- type IMapMarkerArea,
- } from "$root";
- import {
- type GeocoderReverseResult,
- type GeolocationPoint,
- } from "@radroots/util";
- import { Marker, Popup } from "svelte-maplibre";
-
- const { lc_geocode } = get_context(`lib`);
-
- let {
- basis,
- map_geop = $bindable(),
- map_geoc = $bindable(undefined),
- }: {
- basis: IMapMarkerArea;
- map_geop: GeolocationPoint;
- map_geoc?: GeocoderReverseResult | undefined;
- } = $props();
-</script>
-
-<Marker
- bind:lngLat={map_geop}
- draggable={!basis.no_drag}
- class={`flex flex-row h-[100px] w-[100px] bg-blue-400/20 border-[2px] border-white justify-center items-center rounded-full shadow-lg`}
- ondragend={async () => {
- if (!map_geop) return;
- const geoc = await lc_geocode(map_geop);
- if (geoc) map_geoc = geoc;
- }}
->
- {#if basis.show_display}
- <Popup open={basis.show_display} offset={[0, -55]}>
- <MapMarkerAreaDisplay
- basis={map_geoc
- ? {
- primary: map_geoc.name,
- admin: map_geoc.admin1_name,
- country: map_geoc.country_name,
- }
- : undefined}
- />
- </Popup>
- {/if}
-</Marker>
diff --git a/apps-lib/src/lib/components/map/map.svelte b/apps-lib/src/lib/components/map/map.svelte
@@ -1,42 +0,0 @@
-<script lang="ts">
- import { app_thc, type IClOpt } from "$root";
- import { cfg_map, fmt_cl } from "@radroots/util";
- import type { Snippet } from "svelte";
- import { MapLibre } from "svelte-maplibre";
-
- let {
- basis = undefined,
- map = $bindable(undefined),
- children,
- }: {
- basis?: IClOpt & {
- interactive?: boolean;
- zoom_click_off?: boolean;
- };
- map?: maplibregl.Map;
- interactive?: boolean;
- children: Snippet;
- } = $props();
-
- const interactive = $derived(
- typeof basis?.interactive === `boolean` ? basis?.interactive : true,
- );
-
- const zoomOnDoubleClick = $derived(
- typeof basis?.zoom_click_off === `boolean`
- ? basis?.zoom_click_off
- : true,
- );
-</script>
-
-<MapLibre
- bind:map
- class="{fmt_cl(basis?.classes)} relative h-full w-full"
- zoom={10}
- style={cfg_map.styles.base[$app_thc]}
- attributionControl={false}
- {interactive}
- {zoomOnDoubleClick}
->
- {@render children()}
-</MapLibre>
diff --git a/apps-lib/src/lib/components/marker/marker-indexed-view.svelte b/apps-lib/src/lib/components/marker/marker-indexed-view.svelte
@@ -1,31 +0,0 @@
-<script lang="ts">
- import { Empty } from "$root";
- import { type CallbackPromiseGeneric } from "@radroots/util";
-
- let {
- basis,
- }: {
- basis: {
- index_curr: number;
- index_max: number;
- callback_index: CallbackPromiseGeneric<number>;
- };
- } = $props();
-</script>
-
-<div class={`flex flex-row w-full justify-start items-center`}>
- <div
- class={`flex flex-row h-[5px] w-full gap-[6px] justify-start items-center`}
- >
- {#each Array(basis.index_max).fill(0) as _, index}
- <button
- class={`flex flex-row flex-grow h-full justify-start items-center ${basis.index_curr >= index ? `bg-layer-0-glyph` : `bg-layer-2-surface`} rounded-full el-re`}
- onclick={async () => {
- await basis.callback_index(index);
- }}
- >
- <Empty />
- </button>
- {/each}
- </div>
-</div>
diff --git a/apps-lib/src/lib/components/navigation/navigation-tabs.svelte b/apps-lib/src/lib/components/navigation/navigation-tabs.svelte
@@ -1,99 +0,0 @@
-<script lang="ts">
- import { goto } from "$app/navigation";
- import { page } from "$app/state";
- import { app_lo, Empty, Glyph } from "$root";
-</script>
-
-<div
- class={`fixed bottom-0 left-0 h-nav_tabs_${$app_lo} flex flex-row w-full pt-2 justify-center items-start`}
->
- <div class={`flex flex-row justify-between gap-10 items-center`}>
- <div
- class={`grid grid-cols-4 flex flex-row h-[3.1rem] px-6 gap-6 justify-start items-center bg-layer-1-surface rounded-full backdrop-blur-lg`}
- >
- <button
- class={`col-span-1 flex flex-row justify-center items-center`}
- onclick={async () => {
- await goto(`/`);
- }}
- >
- <Glyph
- basis={{
- classes: `text-[26px] text-layer-0-glyph/80 rotate-90`,
- key: `columns`,
- weight: page.url.pathname === `/` ? `fill` : `bold`,
- }}
- />
- </button>
- <button
- class={`relative col-span-1 flex flex-row justify-center items-center`}
- onclick={async () => {
- await goto(`/search`);
- }}
- >
- <Glyph
- basis={{
- classes: `text-[24px] text-layer-0-glyph/80`,
- key: `magnifying-glass`,
- weight: page.url.pathname.includes(`search`)
- ? `fill`
- : `bold`,
- }}
- />
- </button>
- <button
- class={`relative col-span-1 flex flex-row justify-center items-center`}
- onclick={async () => {
- goto(`/profile`);
- }}
- >
- <Glyph
- basis={{
- classes: `text-[24px] text-layer-0-glyph/80`,
- key: `user`,
- weight: page.url.pathname.includes(`profile`)
- ? `fill`
- : `bold`,
- }}
- />
- </button>
- <button
- class={`relative col-span-1 flex flex-row h-full justify-center items-center`}
- onclick={async () => {
- await goto(`/notifications`);
- }}
- >
- <Glyph
- basis={{
- classes: `text-[24px] text-layer-0-glyph/80`,
- key: `bell`,
- weight: page.url.pathname.includes(`notifications`)
- ? `fill`
- : `bold`,
- }}
- />
- <div
- class={`absolute top-2 -right-1 flex flex-row justify-start items-center`}
- >
- <div
- class={`flex flex-row h-2 w-2 justify-start items-center bg-yellow-400 rounded-full`}
- >
- <Empty />
- </div>
- </div>
- </button>
- </div>
- <button
- class={`flex flex-row h-[3.1rem] w-[3.1rem] justify-center items-center bg-layer-1-surface rounded-full backdrop-blur-lg`}
- onclick={async () => {}}
- >
- <Glyph
- basis={{
- classes: `text-[22px] text-layer-0-glyph/80`,
-
- key: `plus`,
- }}
- />
- </button>
- </div>
-</div>
diff --git a/apps-lib/src/lib/components/navigation/page-header.svelte b/apps-lib/src/lib/components/navigation/page-header.svelte
@@ -1,59 +0,0 @@
-<script lang="ts">
- import {
- app_lo,
- callback_route,
- Empty,
- ph_blur,
- type IPageHeader,
- } from "$root";
- import type { Snippet } from "svelte";
- import { fade } from "svelte/transition";
-
- let {
- basis,
- children,
- }: {
- basis: IPageHeader<string>;
- children?: Snippet;
- } = $props();
-</script>
-
-{#if $ph_blur}
- <div
- in:fade={{ duration: 50 }}
- out:fade={{ delay: 50, duration: 200 }}
- class={`z-20 fixed top-0 left-0 flex flex-row h-nav_page_header_${$app_lo} w-full justify-center items-center bg-layer-0-surface-blur/30 backdrop-blur-lg`}
- >
- <Empty />
- </div>
-{/if}
-<div
- class={`z-20 sticky top-0 flex flex-row min-h-nav_page_header_${$app_lo} h-nav_page_header_${$app_lo} w-full px-6 justify-between items-center`}
->
- <div class={`flex flex-row justify-start items-center`}>
- <button
- class={`flex flex-row justify-center items-center`}
- onclick={async () => {
- if (basis.callback_route)
- await callback_route(basis.callback_route);
- }}
- >
- <p
- class={`font-sansd font-[700] text-2xl text-layer-0-glyph capitalize max-w-lo_${$app_lo} truncate`}
- >
- {basis.label || ``}
- </p>
- </button>
- </div>
- {#if children}
- {#if !$ph_blur}
- <div
- in:fade={{ duration: 50 }}
- out:fade={{ delay: 50, duration: 200 }}
- class={`flex flex-row justify-center items-center`}
- >
- {@render children()}
- </div>
- {/if}
- {/if}
-</div>
diff --git a/apps-lib/src/lib/components/navigation/page-toolbar.svelte b/apps-lib/src/lib/components/navigation/page-toolbar.svelte
@@ -1,60 +0,0 @@
-<script lang="ts">
- import { goto } from "$app/navigation";
- import {
- app_lo,
- Glyph,
- LogoCircleSm,
- PageHeader,
- type IBasisOpt,
- type IPageToolbar,
- } from "$root";
- import type { Snippet } from "svelte";
- import LogoLetters from "../lib/logo-letters.svelte";
-
- let {
- basis = undefined,
- header_option,
- }: {
- basis?: IBasisOpt<IPageToolbar<string>>;
- header_option?: Snippet;
- } = $props();
-</script>
-
-<div
- class={`flex flex-row min-h-nav_page_toolbar_${$app_lo} h-nav_page_toolbar_${$app_lo} w-full px-6 justify-between items-end`}
->
- <div class={`flex flex-row w-full justify-between items-center`}>
- <button
- class={`flex flex-row gap-2 justify-start items-center`}
- onclick={async () => {
- if (basis?.callback) await basis.callback();
- else await goto(`/`);
- }}
- >
- <LogoCircleSm />
- <LogoLetters />
- </button>
- <button
- class={`flex flex-row justify-center items-center`}
- onclick={async () => {
- await goto(`/settings`);
- }}
- >
- <Glyph
- basis={{
- classes: `text-layer-0-glyph`,
- dim: `lg`,
-
- key: `gear`,
- }}
- />
- </button>
- </div>
-</div>
-{#if basis?.header}
- <PageHeader basis={basis.header}>
- {#if header_option}
- {@render header_option()}
- {/if}
- </PageHeader>
-{/if}
diff --git a/apps-lib/src/lib/components/trellis/trellis-default-label.svelte b/apps-lib/src/lib/components/trellis/trellis-default-label.svelte
@@ -1,37 +0,0 @@
-<script lang="ts">
- import { type ITrellisDefaultLabel } from "$root";
- import type { ThemeLayer } from "@radroots/theme";
- import { fmt_cl } from "@radroots/util";
-
- let {
- layer,
- labels,
- classes = ``,
- }: {
- layer: ThemeLayer;
- labels: ITrellisDefaultLabel[];
- classes?: string;
- } = $props();
-</script>
-
-<div class={`${fmt_cl(classes)} flex flex-row`}>
- <p class={`font-sans text-trellis_ti text-layer-${layer}-glyph-shade`}>
- {#each labels as label}
- <span class={`${fmt_cl(label.classes)} font-sans text-trellis_ti`}>
- {#if `callback` in label}
- <button
- class={``}
- onclick={async () => {
- if (`callback` in label && label.callback)
- await label.callback();
- }}
- >
- {label.label}
- </button>
- {:else}
- {label.label}
- {/if}
- </span>
- {/each}
- </p>
-</div>
diff --git a/apps-lib/src/lib/components/trellis/trellis-end.svelte b/apps-lib/src/lib/components/trellis/trellis-end.svelte
@@ -1,35 +0,0 @@
-<script lang="ts">
- import { Glyph, type ITrellisBasisTouchEnd } from "$root";
- import type { ThemeLayer } from "@radroots/theme";
-
- let {
- basis,
- layer,
- hide_active,
- }: {
- basis: ITrellisBasisTouchEnd;
- layer: ThemeLayer;
- hide_active: boolean;
- } = $props();
-</script>
-
-<div
- class={`absolute top-0 right-0 h-full w-max flex flex-row justify-center items-center`}
->
- <button
- class={`flex pr-3`}
- onclick={async (ev) => {
- if (basis.callback) await basis.callback(ev);
- }}
- >
- {#if basis.glyph}
- <Glyph
- basis={{
- classes: `text-layer-${layer}-glyph-shade ${hide_active ? `` : `group-active:text-layer-${layer}-glyph_a`} translate-y-[1px] opacity-70`,
- dim: `xs+`,
- ...basis.glyph,
- }}
- />
- {/if}
- </button>
-</div>
diff --git a/apps-lib/src/lib/components/trellis/trellis-input.svelte b/apps-lib/src/lib/components/trellis/trellis-input.svelte
@@ -1,83 +0,0 @@
-<script lang="ts">
- import { Glyph, Input, LoadSymbol, type ITrellisBasisInput } from "$root";
- import type { ThemeLayer } from "@radroots/theme";
- import { fmt_cl, fmt_trellis } from "@radroots/util";
-
- let {
- basis,
- layer,
- hide_border_b,
- hide_border_t,
- }: {
- basis: ITrellisBasisInput;
- layer: ThemeLayer;
- hide_border_b: boolean;
- hide_border_t: boolean;
- } = $props();
-</script>
-
-<div class={`flex flex-row flex-grow h-full w-full`}>
- <div
- class={`${fmt_trellis(hide_border_b, hide_border_t)} flex flex-row h-line w-full justify-start items-center border-t-line border-layer-${layer}-surface-edge overflow-hidden`}
- >
- {#if basis.line_label && basis.line_label.value}
- <div
- class={`${fmt_cl(basis.line_label.classes)} flex flex-row h-full justify-start items-center overflow-x-hidden`}
- >
- <p class={`font-sans text-layer-${layer}-glyph_b`}>
- {basis.line_label.value}
- </p>
- </div>
- {/if}
- <div
- class={`relative flex flex-row flex-grow h-full pr-12 justify-start items-center`}
- >
- <Input
- basis={{
- ...basis.basis,
- layer: layer,
- }}
- />
- {#if basis.action}
- {#if basis.action.visible}
- <div
- class={`absolute top-0 right-0 flex flex-row h-full w-12 pr-4 justify-end items-center fade-in`}
- >
- {#if basis.action.loading}
- <div class={`flex flex-row fade-in`}>
- <LoadSymbol
- basis={{
- dim: `glyph-send-button`,
- blades: 8,
- classes: `text-layer-${layer}-glyph el-re`,
- }}
- />
- </div>
- {:else}
- <button
- class={`group fade-in-long`}
- onclick={async () => {
- if (basis.action?.callback)
- await basis.action.callback();
- }}
- >
- <Glyph
- basis={basis.action.glyph
- ? {
- dim: `md-`,
- ...basis.action.glyph,
- }
- : {
- key: `plus`,
- classes: `text-layer-${layer}-glyph`,
- dim: `md-`,
- }}
- />
- </button>
- {/if}
- </div>
- {/if}
- {/if}
- </div>
- </div>
-</div>
diff --git a/apps-lib/src/lib/components/trellis/trellis-line.svelte b/apps-lib/src/lib/components/trellis/trellis-line.svelte
@@ -1,56 +0,0 @@
-<script lang="ts">
- import { LoadSymbol } from "$root";
- import type { ThemeLayer } from "@radroots/theme";
- import { fmt_trellis, type CallbackPromiseGeneric } from "@radroots/util";
- import type { Snippet } from "svelte";
-
- let {
- loading = false,
- layer,
- callback,
- hide_border_b,
- hide_border_t,
- children,
- el_end,
- }: {
- loading?: boolean;
- layer: ThemeLayer;
- callback?: CallbackPromiseGeneric<MouseEvent>;
- hide_border_b: boolean;
- hide_border_t: boolean;
- children: Snippet;
- el_end?: Snippet;
- } = $props();
-</script>
-
-<button
- class={`flex flex-row flex-grow overflow-hidden`}
- onclick={async (ev) => {
- if (callback) await callback(ev);
- }}
->
- <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 el-re`}
- >
- {#if loading}
- <div
- class={`flex flex-row h-full w-full justify-center items-center`}
- >
- <LoadSymbol basis={{ dim: `sm` }} />
- </div>
- {:else}
- <div
- class={`relative group flex flex-row h-line w-full pr-[2px] justify-between items-center el-re`}
- >
- <div
- class={`flex flex-row h-full w-trellis_display justify-between items-center`}
- >
- {@render children()}
- </div>
- {#if el_end}
- {@render el_end()}
- {/if}
- </div>
- {/if}
- </div>
-</button>
diff --git a/apps-lib/src/lib/components/trellis/trellis-offset.svelte b/apps-lib/src/lib/components/trellis/trellis-offset.svelte
@@ -1,74 +0,0 @@
-<script lang="ts">
- import {
- Empty,
- Glyph,
- GlyphCircle,
- LoadSymbol,
- type ITrellisBasisOffset,
- type ITrellisBasisOffsetMod,
- } from "$root";
- import type { ThemeLayer } from "@radroots/theme";
- import { fmt_cl } from "@radroots/util";
-
- let {
- basis = undefined,
- layer,
- }: {
- basis?: ITrellisBasisOffset;
- layer: ThemeLayer;
- } = $props();
-
- const mod: ITrellisBasisOffsetMod = $derived(basis?.mod ? basis.mod : `sm`);
-</script>
-
-<div class={`flex flex-row h-full`}>
- {#if mod === `sm`}
- <div class={`${fmt_cl(``)} flex flex-row h-full w-[22px]`}>
- <Empty />
- </div>
- {:else if mod === `glyph`}
- <div class={`flex flex-row pr-[2px]`}>
- <div class={`${fmt_cl(``)} flex flex-row h-full w-trellisOffset`}>
- <Empty />
- </div>
- </div>
- {:else if typeof mod === `object`}
- <div
- class={`flex flex-row h-full min-w-[20px] w-trellisOffset justify-center items-center pr-3`}
- >
- <button
- class={`fade-in pl-2 translate-x-[3px] translate-y-[1px]`}
- onclick={async (ev) => {
- if (mod.loading) return;
- else if (typeof basis !== `boolean` && basis?.callback)
- await basis.callback(ev);
- }}
- >
- {#if mod.loading}
- <LoadSymbol basis={{ blades: 8, dim: `xs` }} />
- {:else if `glyph` in mod}
- <Glyph
- basis={{
- classes: mod.glyph.classes
- ? mod.glyph.classes
- : `text-layer-${layer}-glyph`,
- ...mod.glyph,
- }}
- />
- {:else if `glyph_circle` in mod}
- <GlyphCircle
- basis={{
- classes_wrap: mod.glyph_circle?.classes_wrap,
- glyph: {
- classes: mod.glyph_circle?.glyph?.classes
- ? mod.glyph_circle?.glyph?.classes
- : `text-layer-${layer}-glyph`,
- ...mod.glyph_circle?.glyph,
- },
- }}
- />
- {/if}
- </button>
- </div>
- {/if}
-</div>
diff --git a/apps-lib/src/lib/components/trellis/trellis-row-display-value.svelte b/apps-lib/src/lib/components/trellis/trellis-row-display-value.svelte
@@ -1,43 +0,0 @@
-<script lang="ts">
- import { Glyph, type ITrellisKindDisplayValue } from "$root";
- import type { ThemeLayer } from "@radroots/theme";
- import { fmt_cl, get_label_classes_kind } from "@radroots/util";
-
- let {
- basis,
- layer,
- hide_active,
- }: {
- basis: ITrellisKindDisplayValue;
- layer: ThemeLayer;
- hide_active: boolean;
- } = $props();
-</script>
-
-<button
- class={`z-10 flex flex-grow justify-end`}
- onclick={async (ev) => {
- ev.stopPropagation();
- if (basis.callback) await basis.callback(ev);
- }}
->
- {#if `icon` in basis}
- <Glyph
- basis={{
- classes:
- basis.icon.classes ||
- `${get_label_classes_kind(layer, `shade`, hide_active)}`,
- key: basis.icon.key,
- dim: `sm`,
- }}
- />
- {:else if basis.label}
- {#if `value` in basis.label}
- <p
- class={`${fmt_cl(basis.label.classes)} font-sans text-line_d_e line-clamp-1 text-layer-0-glyph-label el-re`}
- >
- {basis.label.value}
- </p>
- {/if}
- {/if}
-</button>
diff --git a/apps-lib/src/lib/components/trellis/trellis-row-label.svelte b/apps-lib/src/lib/components/trellis/trellis-row-label.svelte
@@ -1,62 +0,0 @@
-<script lang="ts">
- import { GlyphButton, type ILabelTupFields } from "$root";
- import type { ThemeLayer } from "@radroots/theme";
- import { fmt_cl, get_label_classes_kind } from "@radroots/util";
-
- let {
- basis,
- layer,
- hide_active,
- }: {
- basis: ILabelTupFields;
- layer: ThemeLayer;
- hide_active: boolean;
- } = $props();
-</script>
-
-<div class={`flex flex-row h-full items-center justify-between`}>
- {#if basis.left && basis.left.length}
- <div class={`flex flex-row h-full items-center truncate`}>
- {#each basis.left as title_l}
- <div
- class={`${fmt_cl(title_l.classes_wrap)} flex flex-row h-full items-center ${get_label_classes_kind(layer, undefined, hide_active)} ${title_l.hide_truncate ? `` : `truncate`}`}
- >
- {#if `glyph` in title_l}
- <div
- class={`flex flex-row justify-start items-center pr-2`}
- >
- <GlyphButton basis={{ ...title_l.glyph }} />
- </div>
- {:else if `value` in title_l}
- <p
- class={`${fmt_cl(title_l.classes)} font-sans text-line_d ${title_l.hide_truncate ? `` : `truncate`} el-re`}
- >
- {title_l.value || ``}
- </p>
- {/if}
- </div>
- {/each}
- </div>
- {/if}
- {#if basis.right && basis.right.length}
- <div
- class={`flex flex-row h-full w-content items-center justify-end pr-4`}
- >
- {#each basis.right.reverse() as title_r}
- <div
- class={`${fmt_cl(title_r.classes_wrap)} flex flex-row h-full gap-1 items-center ${title_r.hide_truncate ? `` : `truncate`}`}
- >
- {#if `glyph` in title_r}
- <GlyphButton basis={{ ...title_r.glyph }} />
- {:else if `value` in title_r}
- <p
- class={`${fmt_cl(title_r.classes)} font-sans text-line_d text-layer-${layer}-glyph_d ${title_r.hide_truncate ? `` : `truncate`} el-re`}
- >
- {title_r.value || ``}
- </p>
- {/if}
- </div>
- {/each}
- </div>
- {/if}
-</div>
diff --git a/apps-lib/src/lib/components/trellis/trellis-select.svelte b/apps-lib/src/lib/components/trellis/trellis-select.svelte
@@ -1,67 +0,0 @@
-<script lang="ts">
- import {
- LoadSymbol,
- SelectMenu,
- TrellisEnd,
- TrellisLine,
- TrellisRowDisplayValue,
- TrellisRowLabel,
- type ITrellisBasisSelect,
- } from "$root";
- import type { ThemeLayer } from "@radroots/theme";
-
- let {
- basis,
- layer,
- hide_active,
- hide_border_b,
- hide_border_t,
- }: {
- basis: ITrellisBasisSelect;
- layer: ThemeLayer;
- hide_active: boolean;
- hide_border_b: boolean;
- hide_border_t: boolean;
- } = $props();
-
- const loading = $derived(
- typeof basis?.loading === `boolean` ? basis.loading : false,
- );
-
- const value = $derived(basis.el.value);
-</script>
-
-<TrellisLine
- {layer}
- {loading}
- {hide_border_b}
- {hide_border_t}
- callback={basis.callback}
->
- <TrellisRowLabel basis={basis.label} {layer} {hide_active} />
- {#if basis.display}
- <div class={`flex flex-row pr-3 justify-center items-end`}>
- <SelectMenu {value} basis={basis.el}>
- {#if basis.display.loading}
- <div
- class={`flex flex-row h-full w-full justify-end items-center`}
- >
- <LoadSymbol basis={{ dim: `sm` }} />
- </div>
- {:else}
- <TrellisRowDisplayValue
- basis={{ ...basis.display }}
- {layer}
- {hide_active}
- />
- {/if}
- </SelectMenu>
- </div>
- {/if}
-
- {#snippet el_end()}
- {#if basis.end}
- <TrellisEnd basis={basis.end} {layer} {hide_active} />
- {/if}
- {/snippet}
-</TrellisLine>
diff --git a/apps-lib/src/lib/components/trellis/trellis-title.svelte b/apps-lib/src/lib/components/trellis/trellis-title.svelte
@@ -1,68 +0,0 @@
-<script lang="ts">
- import { Empty, Glyph, LabelSwap, type ITrellisTitle } from "$root";
- import type { ThemeLayer } from "@radroots/theme";
- import { fmt_cl } from "@radroots/util";
-
- let {
- basis,
- layer = 0,
- }: {
- basis: ITrellisTitle;
- layer: ThemeLayer;
- } = $props();
-
- const mod = $derived(basis?.mod ? basis.mod : `sm`);
-</script>
-
-<div
- class={`${fmt_cl(basis.classes)} flex flex-row h-[24px] w-full pl-[2px] gap-1 items-center`}
->
- <button
- class={`flex flex-row h-full w-max items-center gap-1 ${mod === `glyph` ? `pl-[36px]` : mod === `sm` ? `pl-[16px]` : ``}`}
- onclick={async () => {
- if (basis && basis.callback) await basis.callback();
- }}
- >
- {#if basis.value === true}
- <Empty />
- {:else}
- <p
- class={`font-sans text-trellis_ti text-layer-${layer}-glyph-label uppercase`}
- >
- {basis.value || ``}
- </p>
- {/if}
- </button>
- {#if basis.link}
- <button
- class={`${fmt_cl(basis.link.classes)} group flex flex-row h-full w-max items-center`}
- onclick={async () => {
- if (basis.link && basis.link.callback)
- await basis.link.callback();
- }}
- >
- {#if basis.link.label}
- {#if `swap` in basis.link.label}
- <LabelSwap basis={basis.link.label} />
- {:else if `value` in basis.link.label}
- <p
- class={`${fmt_cl(basis.link.label.classes)} font-sans text-trellis_ti uppercase fade-in`}
- >
- {basis.link.label.value || ``}
- </p>
- {/if}
- {/if}
- {#if basis.link.glyph}
- <div class={`flex flex-row w-max`}>
- <Glyph
- basis={{
- ...basis.link.glyph,
- dim: `xs-`,
- classes: `${fmt_cl(basis.link.glyph.classes)} fade-in`,
- }}
- />
- </div>
- {/if}
- </button>
- {/if}
-</div>
diff --git a/apps-lib/src/lib/components/trellis/trellis-touch.svelte b/apps-lib/src/lib/components/trellis/trellis-touch.svelte
@@ -1,42 +0,0 @@
-<script lang="ts">
- import {
- TrellisEnd,
- TrellisLine,
- TrellisRowDisplayValue,
- TrellisRowLabel,
- type ITrellisBasisTouch,
- } from "$root";
- import type { ThemeLayer } from "@radroots/util";
-
- let {
- basis,
- layer,
- hide_active,
- hide_border_b,
- hide_border_t,
- }: {
- basis: ITrellisBasisTouch;
- layer: ThemeLayer;
- hide_active: boolean;
- hide_border_b: boolean;
- hide_border_t: boolean;
- } = $props();
-</script>
-
-<TrellisLine {layer} {hide_border_b} {hide_border_t} callback={basis.callback}>
- <TrellisRowLabel basis={basis.label} {layer} {hide_active} />
- {#if basis.display}
- <TrellisRowDisplayValue
- basis={{
- ...basis.display,
- }}
- {layer}
- {hide_active}
- />
- {/if}
- {#snippet el_end()}
- {#if basis.end}
- <TrellisEnd basis={basis.end} {layer} {hide_active} />
- {/if}
- {/snippet}
-</TrellisLine>
diff --git a/apps-lib/src/lib/components/trellis/trellis.svelte b/apps-lib/src/lib/components/trellis/trellis.svelte
@@ -1,152 +0,0 @@
-<script lang="ts">
- import {
- app_lo,
- get_context,
- TrellisDefaultLabel,
- TrellisInput,
- TrellisOffset,
- TrellisSelect,
- TrellisTitle,
- TrellisTouch,
- type ITrellis,
- } from "$root";
- import { fmt_cl, parse_layer } from "@radroots/util";
- import type { Snippet } from "svelte";
-
- const { ls } = get_context(`lib`);
-
- let {
- basis,
- el_default,
- el_offset,
- el_append,
- }: {
- basis: ITrellis;
- el_default?: Snippet;
- el_offset?: Snippet;
- el_append?: Snippet;
- } = $props();
-
- const hide_border_t = $derived(
- typeof basis.hide_border_top === `boolean`
- ? basis.hide_border_top
- : true,
- );
-
- const hide_border_b = $derived(
- typeof basis.hide_border_bottom === `boolean`
- ? basis.hide_border_bottom
- : true,
- );
-
- const hide_rounded = $derived(
- typeof basis.hide_rounded === `boolean` ? basis.hide_rounded : false,
- );
-
- const set_title_background = $derived(
- typeof basis.set_title_background === `boolean`
- ? basis.set_title_background
- : false,
- );
-
- const set_default_background = $derived(
- typeof basis.set_default_background === `boolean`
- ? basis.set_default_background
- : false,
- );
-</script>
-
-<div
- id={basis.id || ``}
- class={`${fmt_cl(basis.classes)} flex flex-col`}
- data-view={basis.view || ``}
->
- <div
- class={`relative flex flex-col h-auto w-lo_${$app_lo} gap-[3px] ${set_title_background ? `bg-layer-${basis.layer}-surface` : ``}`}
- >
- {#if basis.title && (!basis.default_el || (basis.default_el && basis.default_el.show_title))}
- <TrellisTitle
- basis={basis.title}
- layer={parse_layer(basis.layer - 1)}
- />
- {/if}
- {#if basis.default_el}
- <div
- class={`flex flex-col h-auto w-full justify-center items-center`}
- >
- {#if el_default}
- {@render el_default()}
- {:else if basis.default_el}
- <TrellisDefaultLabel
- layer={parse_layer(basis.layer - 1)}
- labels={basis.default_el.labels
- ? basis.default_el.labels
- : [
- {
- label: `${$ls(`common.no_items_to_display`)}.`,
- },
- ]}
- />
- {/if}
- </div>
- {:else if basis.list}
- <div class={`flex flex-col w-full justify-center items-center`}>
- {#each basis.list as li}
- {#if li}
- <div
- class={`${li.hide_field ? `hidden` : ``} group flex flex-row h-full w-full justify-end items-center bg-layer-${basis.layer}-surface ${li.full_rounded ? `rounded-touch` : ``} ${hide_rounded ? `` : `first:rounded-t-2xl last:rounded-b-2xl`} ${!li.hide_active ? `active:bg-layer-${basis.layer}-surface_a` : ``} el-re`}
- >
- <div
- class={`flex flex-row h-full w-full gap-1 items-center overflow-y-hidden`}
- >
- {#if !basis.hide_offset}
- <TrellisOffset
- basis={li.offset}
- layer={basis.layer}
- />
- {/if}
- {#if el_offset}
- {@render el_offset()}
- {/if}
- {#if `touch` in li && li.touch}
- <TrellisTouch
- basis={li.touch}
- layer={basis.layer}
- {hide_border_b}
- {hide_border_t}
- hide_active={!!li.hide_active}
- />
- {:else if `input` in li && li.input}
- <TrellisInput
- basis={li.input}
- layer={basis.layer}
- {hide_border_b}
- {hide_border_t}
- />
- {:else if `select` in li && li.select}
- <TrellisSelect
- basis={li.select}
- layer={basis.layer}
- {hide_border_b}
- {hide_border_t}
- hide_active={!!li.hide_active}
- />
- {/if}
- </div>
- </div>
- {/if}
- {/each}
- </div>
- {/if}
- </div>
- {#if el_append}
- <div
- class={`flex flex-col w-full ${set_default_background ? `bg-layer-${basis.layer}-surface` : ``}`}
- >
- {@render el_append()}
- </div>
- {/if}
-</div>
-<div
- class={`hidden group-first:border-t-0 group-first:border-t-line group-first:border-b-0 group-first:border-b-line`}
-></div>
diff --git a/apps-lib/src/lib/components/upload/image-upload-add-photo.svelte b/apps-lib/src/lib/components/upload/image-upload-add-photo.svelte
@@ -1,47 +0,0 @@
-<script lang="ts">
- import { get_context, Glyph, LoadSymbol } from "$root";
-
- const { ls, lc_photos_add } = get_context(`lib`);
-
- let {
- basis,
- photo_path = $bindable(``),
- }: {
- basis: {
- loading?: boolean;
- };
- photo_path: string;
- } = $props();
-</script>
-
-<div class={`relative flex flex-row w-full justify-center items-center`}>
- <button
- class={`flex flex-row h-[5rem] w-[5rem] justify-center items-center bg-layer-1-surface/60 rounded-full`}
- onclick={async () => {
- const photo_paths_add = await lc_photos_add();
- if (photo_paths_add) photo_path = photo_paths_add[0];
- }}
- >
- {#if basis.loading}
- <LoadSymbol basis={{ dim: `md` }} />
- {:else}
- <Glyph
- basis={{
- classes: `text-[40px] text-layer-2-glyph`,
- dim: `sm`,
- key: `camera`,
- }}
- />
- {/if}
-
- <div
- class={`absolute -bottom-[1.8rem] flex flex-row justify-start items-center`}
- >
- <p
- class={`font-arch font-[600] text-sm text-layer-0-glyph capitalize`}
- >
- {`${$ls(`icu.add_*`, { value: `${$ls(`common.photo`)}` })}`}
- </p>
- </div>
- </button>
-</div>
diff --git a/apps-lib/src/lib/components/upload/image-upload-buttons-aspect.svelte b/apps-lib/src/lib/components/upload/image-upload-buttons-aspect.svelte
@@ -1,95 +0,0 @@
-<script lang="ts">
- import { ButtonLabelGlyph, Empty } from "$root";
- import {
- type CallbackPromiseGeneric,
- type ImageAspectRatio,
- } from "@radroots/util";
-
- let {
- basis,
- }: {
- basis: {
- callback: CallbackPromiseGeneric<ImageAspectRatio>;
- };
- } = $props();
-
- let ratio_curr: ImageAspectRatio = $state(`auto`);
-</script>
-
-<div class={`flex flex-row w-full justify-around items-center`}>
- <ButtonLabelGlyph
- basis={{
- glyph: `crop`,
- label: `Auto`,
- ring: ratio_curr === `auto`,
- callback: async () => {
- ratio_curr = `auto`;
- await basis.callback(`auto`);
- },
- }}
- />
- <ButtonLabelGlyph
- basis={{
- label: `1:1`,
- ring: ratio_curr === `1/1`,
- callback: async () => {
- ratio_curr = `1/1`;
- await basis.callback(`1/1`);
- },
- }}
- >
- <div
- class={`flex flex-row h-5 w-5 justify-start items-center rounded-md bg-layer-2-surface shadow-lg`}
- >
- <Empty />
- </div>
- </ButtonLabelGlyph>
- <ButtonLabelGlyph
- basis={{
- label: `4:3`,
- ring: ratio_curr === `4/3`,
- callback: async () => {
- ratio_curr = `4/3`;
- await basis.callback(`4/3`);
- },
- }}
- >
- <div
- class={`flex flex-row w-5 aspect-[4/3] justify-start items-center rounded-md bg-layer-2-surface shadow-lg rotate-90`}
- >
- <Empty />
- </div>
- </ButtonLabelGlyph>
- <ButtonLabelGlyph
- basis={{
- label: `16:9`,
- ring: ratio_curr === `16/9`,
- callback: async () => {
- ratio_curr = `16/9`;
- await basis.callback(`16/9`);
- },
- }}
- >
- <div
- class={`flex flex-row w-5 aspect-[16/9] justify-start items-center rounded-md bg-layer-2-surface shadow-lg rotate-90`}
- >
- <Empty />
- </div>
- </ButtonLabelGlyph>
- <ButtonLabelGlyph
- basis={{
- label: `3:4`,
- ring: ratio_curr === `3/4`,
- callback: async () => {
- ratio_curr = `3/4`;
- await basis.callback(`3/4`);
- },
- }}
- >
- <div
- class={`flex flex-row w-5 aspect-[3/4] justify-start items-center rounded-md bg-layer-2-surface shadow-lg`}
- >
- <Empty />
- </div>
- </ButtonLabelGlyph>
-</div>
diff --git a/apps-lib/src/lib/components/upload/image-upload-simple.svelte b/apps-lib/src/lib/components/upload/image-upload-simple.svelte
@@ -1,69 +0,0 @@
-<script lang="ts">
- import {
- get_context,
- Glyph,
- ImagePath,
- ImageUploadButtonsAspect,
- } from "$root";
- import { list_assign } from "@radroots/util";
-
- const { ls, lc_photos_add } = get_context(`lib`);
-
- let {
- photo_paths = $bindable([]),
- }: {
- photo_paths: string[];
- } = $props();
-
- let img_path = $state(``);
-
- $effect(() => {
- console.log(`img_path `, img_path);
- });
-</script>
-
-<div class={`flex flex-col w-full gap-4 justify-center items-center`}>
- {#if img_path}
- <div
- class={`flex flex-row h-[20rem] w-full gap-2 justify-center items-center rounded-3xl bg-layer-1-surface/60 overflow-hidden`}
- >
- <ImagePath basis={{ path: img_path }} />
- </div>
- {:else}
- <button
- class={`flex flex-row w-full justify-center items-center`}
- onclick={async () => {
- const photo_paths_add = await lc_photos_add();
- if (photo_paths_add) {
- photo_paths = list_assign(photo_paths, photo_paths_add);
- img_path = photo_paths[0];
- }
- }}
- >
- <div
- class={`flex flex-row h-[20rem] w-full gap-2 justify-center items-center border-line border-layer-0-glyph/20 border-[3px] border-dashed rounded-3xl bg-layer-1-surface/60`}
- >
- <Glyph
- basis={{
- classes: `text-layer-0-glyph/80`,
- dim: `sm`,
-
- key: `upload-simple`,
- }}
- />
- <p
- class={`font-sans font-[400] text-layer-0-glyph/80 capitalize`}
- >
- {`${$ls(`icu.upload_*`, { value: `${$ls(`common.image`)}` })}`}
- </p>
- </div>
- </button>
- {/if}
- <ImageUploadButtonsAspect
- basis={{
- callback: async (ratio) => {
- // @todo
- },
- }}
- />
-</div>
diff --git a/apps-lib/src/lib/components/window/window-resize-listener.svelte b/apps-lib/src/lib/components/window/window-resize-listener.svelte
@@ -1,38 +0,0 @@
-<script lang="ts">
- import { browser } from "$app/environment";
- import { handle_err, win_h, win_w } from "$root";
- import { onDestroy, onMount } from "svelte";
-
- let last_h = $state(0);
- let last_w = $state(0);
-
- onMount(async () => {
- try {
- handle_resize();
- if (browser) window.addEventListener(`resize`, handle_resize);
- } catch (e) {
- handle_err(e, `on_mount`);
- }
- });
-
- onDestroy(async () => {
- try {
- if (browser) window.removeEventListener(`resize`, handle_resize);
- } catch (e) {
- handle_err(e, `on_destroy`);
- }
- });
-
- const handle_resize = (): void => {
- if (!browser) return;
- const { innerHeight: h, innerWidth: w } = window;
- if (Math.abs(h - last_h) > 4) {
- last_h = h;
- win_h.set(h);
- }
- if (Math.abs(w - last_w) > 4) {
- last_w = w;
- win_w.set(w);
- }
- };
-</script>
diff --git a/apps-lib/src/lib/components/window/window-safari-listener.svelte b/apps-lib/src/lib/components/window/window-safari-listener.svelte
@@ -1,38 +0,0 @@
-<script lang="ts">
- import { browser } from "$app/environment";
- import { lo_browser_safarinav } from "$lib/store/layout";
- import { handle_err } from "$root";
- import { onDestroy, onMount } from "svelte";
-
- const HEIGHT_THRESHOLD = 60;
- let h_prev = $state(0);
-
- onMount(async () => {
- try {
- handle_resize();
- if (browser) window.addEventListener(`resize`, handle_resize);
- } catch (e) {
- handle_err(e, `on_mount`);
- }
- });
-
- onDestroy(async () => {
- try {
- if (browser) window.removeEventListener(`resize`, handle_resize);
- } catch (e) {
- handle_err(e, `on_destroy`);
- }
- });
-
- const handle_resize = (): void => {
- if (!browser) return;
- const { innerHeight: h_curr } = window;
- if (h_prev !== undefined) {
- const h_del = Math.abs(h_curr - h_prev);
- if (h_del > HEIGHT_THRESHOLD) {
- lo_browser_safarinav.set(h_curr < h_prev);
- }
- }
- h_prev = h_curr;
- };
-</script>
diff --git a/apps-lib/src/lib/features/farm/farms-add-casli-detail.svelte b/apps-lib/src/lib/features/farm/farms-add-casli-detail.svelte
@@ -1,97 +0,0 @@
-<script lang="ts">
- import { CarouselItem, FormLineLedger, get_context } from "$root";
- import { area_units, form_fields } from "@radroots/util";
-
- const { ls } = get_context(`lib`);
-
- let {
- val_farmname = $bindable(``),
- val_farmaddress = $bindable(``),
- val_farmarea = $bindable(``),
- val_farmarea_unit = $bindable(``),
- val_farmcontact = $bindable(``),
- farm_geop_lat,
- farm_geop_lng,
- }: {
- val_farmname: string;
- val_farmaddress: string;
- val_farmarea: string;
- val_farmarea_unit: string;
- val_farmcontact: string;
- farm_geop_lat: string;
- farm_geop_lng: string;
- } = $props();
-</script>
-
-<CarouselItem>
- <div
- class={`flex flex-col h-[100vh] w-full px-6 pt-2 gap-4 justify-start items-center`}
- >
- <FormLineLedger
- bind:value={val_farmaddress}
- basis={{
- id: `farm_location`,
- label: `${$ls(`common.farm_location`)}`,
- input: {
- placeholder: `${$ls(`icu.enter_*`, { value: `${$ls(`common.farm_location`)}`.toLowerCase() })}`,
- },
- }}
- />
-
- <FormLineLedger
- basis={{
- id: `farm_coordinates`,
- label: `${$ls(`common.farm_coordinates`)}`,
- display_value:
- farm_geop_lat && farm_geop_lng
- ? `${farm_geop_lat}, ${farm_geop_lng}`
- : undefined,
- input:
- farm_geop_lat && farm_geop_lng
- ? undefined
- : {
- placeholder: `${$ls(`icu.enter_*`, { value: `${$ls(`common.farm_coordinates`)}`.toLowerCase() })}`,
- },
- }}
- />
- <FormLineLedger
- bind:value={val_farmname}
- basis={{
- id: `farm_name`,
- label: `${$ls(`common.farm_name`)}`,
- input: {
- placeholder: `${$ls(`icu.enter_*`, { value: `${$ls(`common.farm_name`)}`.toLowerCase() })}`,
- },
- }}
- />
- <FormLineLedger
- bind:value={val_farmarea}
- bind:value_label_sel={val_farmarea_unit}
- basis={{
- id: `farm_size`,
- label: `${$ls(`common.farm_size`)}`,
- label_select: {
- label: `${$ls(`units.area.${val_farmarea_unit}_ab`)}`,
- entries: area_units.map((i) => ({
- value: i,
- label: `${$ls(`units.area.${i}`)}`,
- })),
- },
- input: {
- placeholder: `${`${$ls(`icu.enter_*`, { value: `${$ls(`common.farm_size`)}`.toLowerCase() })}`} ${`${$ls(`units.area.${val_farmarea_unit}_pl`)}`.toLowerCase()}`,
- field: form_fields.farm_size,
- },
- }}
- />
- <FormLineLedger
- bind:value={val_farmcontact}
- basis={{
- id: `farm_contact`,
- label: `${$ls(`common.farm_contact`)}`,
- input: {
- placeholder: `${$ls(`icu.enter_*`, { value: `${$ls(`common.contact_name`)}`.toLowerCase() })}`,
- },
- }}
- />
- </div>
-</CarouselItem>
diff --git a/apps-lib/src/lib/features/farm/farms-add-casli-map.svelte b/apps-lib/src/lib/features/farm/farms-add-casli-map.svelte
@@ -1,94 +0,0 @@
-<script lang="ts">
- import Fade from "$lib/components/lib/fade.svelte";
- import {
- CarouselItem,
- Map,
- MapMarkerArea,
- WrapBorder,
- app_lo,
- focus_map_marker,
- geop_is_valid,
- get_context,
- handle_err,
- } from "$root";
- import {
- type GeocoderReverseResult,
- type GeolocationPoint,
- } from "@radroots/util";
- import { onMount } from "svelte";
-
- const { lc_geop_current, lc_geocode } = get_context(`lib`);
-
- let {
- map_geoc = $bindable(undefined),
- map_geop = $bindable(undefined),
- farm_geop_lat,
- farm_geop_lng,
- }: {
- map_geoc: GeocoderReverseResult | undefined;
- map_geop: GeolocationPoint | undefined;
- farm_geop_lat: string;
- farm_geop_lng: string;
- } = $props();
-
- let map: maplibregl.Map | undefined = $state(undefined);
-
- const is_valid_geop = $derived(geop_is_valid(map_geop));
-
- onMount(async () => {
- try {
- const geop = await lc_geop_current();
- if (!geop) return;
- map_geop = { ...geop };
- const geoc = await lc_geocode(geop);
- if (!geoc) return;
- map_geoc = geoc;
- if (map) map.setCenter([map_geop.lng, map_geop.lat]);
- focus_map_marker();
- } catch (e) {
- handle_err(e, `on_mount`);
- }
- });
-</script>
-
-<CarouselItem>
- <div
- class={`flex flex-col h-[100vh] w-full px-6 gap-4 justify-start items-center`}
- >
- <WrapBorder basis={{ classes: `h-lo_view_main_${$app_lo}` }}>
- <Map bind:map>
- {#if map_geop}
- <MapMarkerArea
- bind:map_geop
- bind:map_geoc
- basis={{
- show_display: true,
- }}
- />
- {/if}
- </Map>
- </WrapBorder>
- {#if is_valid_geop}
- <Fade>
- <div
- class={`flex flex-col w-full gap-1 justify-center items-center`}
- >
- <div
- class={`flex flex-row w-full gap-2 justify-center items-center`}
- >
- <p
- class={`font-sans font-[500] text-layer-0-glyph tracking-tightest`}
- >
- {farm_geop_lat}
- </p>
- <p
- class={`font-sans font-[500] text-layer-0-glyph tracking-tightest`}
- >
- {farm_geop_lng}
- </p>
- </div>
- </div>
- </Fade>
- {/if}
- </div>
-</CarouselItem>
diff --git a/apps-lib/src/lib/features/farm/farms-display-li-el.svelte b/apps-lib/src/lib/features/farm/farms-display-li-el.svelte
@@ -1,107 +0,0 @@
-<script lang="ts">
- import { get_context, Map, MapMarkerArea } from "$root";
- import {
- fmt_geolocation_address,
- geol_lat_fmt,
- geol_lng_fmt,
- parse_geol_point_tup,
- parse_tup_geop_point,
- type CallbackPromiseGeneric,
- type FarmExtended,
- type GeolocationPointTuple,
- } from "@radroots/util";
- import { onMount } from "svelte";
-
- const { ls, locale } = get_context(`lib`);
-
- let {
- basis,
- on_handle_farm_view,
- }: {
- basis: FarmExtended;
- on_handle_farm_view: CallbackPromiseGeneric<string>;
- } = $props();
-
- let map: maplibregl.Map | undefined = $state(undefined);
- let map_center: GeolocationPointTuple = $state([0, 0]);
-
- onMount(async () => {
- if (basis.location?.point)
- map_center = parse_geol_point_tup(basis.location.point);
- if (map) map.setCenter(map_center);
- });
-
- const map_geop = $derived(parse_tup_geop_point(map_center));
-
- const farm_addr_fmt = $derived(
- basis.location?.address
- ? fmt_geolocation_address(basis.location.address)
- : ``,
- );
-
- const farm_geop_lat = $derived(
- basis.location?.point
- ? geol_lat_fmt(basis.location.point.lat, `dms`, $locale, 3)
- : ``,
- );
-
- const farm_geop_lng = $derived(
- basis.location?.point
- ? geol_lng_fmt(basis.location.point.lng, `dms`, $locale, 3)
- : ``,
- );
-</script>
-
-<button
- class={`z-10 relative flex flex-col w-full p-4 gap-3 justify-start items-center bg-layer-1-surface layer-1-active-raise-less layer-1-active-ring rounded-3xl el-re`}
- onclick={async () => {
- if (basis.farm.id) await on_handle_farm_view(basis.farm.id);
- }}
->
- <div class={`flex flex-col w-full gap-2 justify-center items-center`}>
- <div class={`flex flex-row w-full justify-between items-center`}>
- <p class={`font-sans font-[500] text-3xl text-layer-0-glyph`}>
- {basis.farm.name}
- </p>
-
- <div
- class={`flex flex-row h-6 px-2 py-1 justify-center items-center bg-lime-400 rounded-lg`}
- >
- <p class={`font-sans font-[700] text-white`}>
- {`${$ls(`common.farm`)}`}
- </p>
- </div>
- </div>
- <div class={`flex flex-col w-full justify-center items-center`}>
- <div class={`flex flex-row w-full justify-start items-center`}>
- <p class={`font-sans font-[500] text-lg text-layer-0-glyph`}>
- {farm_addr_fmt}
- </p>
- </div>
- <div class={`flex flex-row w-full justify-start items-center`}>
- <p class={`font-sans font-[500] text-lg text-layer-0-glyph`}>
- {farm_geop_lat && farm_geop_lng
- ? `${farm_geop_lat}, ${farm_geop_lng}`
- : ``}
- </p>
- </div>
- </div>
- </div>
- <div
- class={`flex flex-col h-[16rem] w-full justify-center items-center rounded-2xl overflow-hidden`}
- >
- <Map
- bind:map
- basis={{
- interactive: false,
- }}
- >
- <MapMarkerArea
- {map_geop}
- basis={{
- no_drag: true,
- }}
- />
- </Map>
- </div>
-</button>
diff --git a/apps-lib/src/lib/features/farm/farms-products-review-card.svelte b/apps-lib/src/lib/features/farm/farms-products-review-card.svelte
@@ -1,132 +0,0 @@
-<script lang="ts">
- import {
- app_lo,
- get_context,
- Glyph,
- ImagePath,
- lib_parse_currency_marker,
- type IViewFarmsProductsAddSubmitPayload,
- } from "$root";
- import { parse_geocode_address, symbols } from "@radroots/util";
-
- const { ls, locale } = get_context(`lib`);
-
- let {
- basis,
- }: {
- basis: {
- data: IViewFarmsProductsAddSubmitPayload | undefined;
- };
- } = $props();
-
- //@todo
-</script>
-
-<div
- class={`flex flex-col h-[20rem] w-lo_line_entry_${$app_lo} justify-start items-start rounded-touch bg-layer-1-surface overflow-hidden`}
->
- <div class={`flex flex-row h-[10rem] w-full justify-center items-center`}>
- {#if basis.data?.photos.length}
- <ImagePath
- basis={{
- path: basis.data.photos[0],
- }}
- />
- {:else}
- <div
- class={`flex flex-row h-full w-full justify-center items-center bg-layer-2-surface`}
- >
- <div class={`flex flex-col justify-start items-center`}>
- <Glyph
- basis={{
- classes: `text-layer-0-glyph`,
- dim: `sm`,
- key: `image-broken`,
- }}
- />
- <p
- class={`font-sans font-[400] text-sm text-layer-0-glyph`}
- >
- {`No photo`}
- </p>
- </div>
- </div>
- {/if}
- </div>
- <div
- class={`flex flex-col h-[10rem] w-full px-3 py-2 justify-start items-center`}
- >
- {#if basis.data}
- {@const data_geoc_address = parse_geocode_address(
- basis.data.geocode_result,
- )}
- <div class={`flex flex-row w-full justify-between items-center`}>
- <div class={`flex flex-row gap-1 justify-start items-center`}>
- <p
- class={`font-sans font-[600] text-xl text-th-black capitalize`}
- >
- {basis.data.product}
- </p>
- </div>
- <div
- class={`flex flex-row gap-[2px] justify-start items-center`}
- >
- <p class={`font-sans font-[600] text-xl text-th-black`}>
- {`${lib_parse_currency_marker($locale, basis.data.price_currency)}${basis.data.price_amount}`}
- </p>
- <p class={`font-sans font-[600] text-xl text-th-black`}>
- {`/`}
- </p>
- <p class={`font-sans font-[600] text-xl text-th-black`}>
- {`${$ls(`units.mass.unit.${basis.data.price_quantity_unit}_ab`)}`}
- </p>
- </div>
- </div>
- <div class={`flex flex-row w-full justify-between items-center`}>
- <div class={`flex flex-row gap-1 justify-start items-center`}>
- <p
- class={`font-sans font-[600] text-lg text-layer-1-glyph capitalize`}
- >
- {basis.data.process}
- </p>
- <p
- class={`font-sans font-[600] text-xl text-layer-1-glyph`}
- >
- {symbols.bullet}
- </p>
- <p
- class={`font-sans font-[600] text-lg text-layer-1-glyph`}
- >
- {`${basis.data.quantity_amount} ${$ls(`units.mass.unit.${basis.data.quantity_unit}_ab`)} ${basis.data.quantity_label}`}
- </p>
- </div>
- </div>
- <div class={`flex flex-row w-full justify-start items-center`}>
- <p
- class={`font-sans font-[400] text-sm text-th-black capitalize line-clamp-2 overflow-hidden text-ellipsis`}
- >
- {basis.data.description}
- </p>
- </div>
- {#if data_geoc_address}
- <div
- class={`flex flex-row w-full pt-2 justify-between items-center`}
- >
- <div
- class={`flex flex-row gap-1 justify-start items-center`}
- >
- <p class={`font-sans font-[600] text-th-black`}>
- {`${data_geoc_address.primary}, ${data_geoc_address.admin}`}
- </p>
- <p class={`font-sans font-[600] text-th-black`}>
- {symbols.bullet}
- </p>
- <p class={`font-sans font-[600] text-th-black`}>
- {`${data_geoc_address.country}`}
- </p>
- </div>
- </div>
- {/if}
- {/if}
- </div>
-</div>
diff --git a/apps-lib/src/lib/index.ts b/apps-lib/src/lib/index.ts
@@ -1,129 +1,6 @@
-export { default as ButtonHorizontalPairSlide } from "./components/button/button-horizontal-pair-slide.svelte"
-export { default as ButtonLabelDashed } from "./components/button/button-label-dashed.svelte"
-export { default as ButtonLabelGlyph } from "./components/button/button-label-glyph.svelte"
-export { default as ButtonLayoutPair } from "./components/button/button-layout-pair.svelte"
-export { default as ButtonLayout } from "./components/button/button-layout.svelte"
-export { default as ButtonRoundNav } from "./components/button/button-round-nav.svelte"
-export { default as ButtonRound } from "./components/button/button-round.svelte"
-export { default as ButtonSimpleGlyph } from "./components/button/button-simple-glyph.svelte"
-export { default as ButtonSimple } from "./components/button/button-simple.svelte"
-export { default as GlyphButtonSimple } from "./components/button/glyph-button-simple.svelte"
-export { default as GlyphButton } from "./components/button/glyph-button.svelte"
-export { default as CarouselFlowItem } from "./components/carousel/carousel-flow-item.svelte"
-export { default as CarouselFlow } from "./components/carousel/carousel-flow.svelte"
-export { default as CarouselItem } from "./components/carousel/carousel-item.svelte"
-export { default as Carousel } from "./components/carousel/carousel.svelte"
-export { default as EnvelopeLowerFull } from "./components/envelope/envelope-lower-full.svelte"
-export { default as MapLocationSelectEnvelope } from "./components/envelope/map-location-select-envelope.svelte"
-export { default as FloatPage } from "./components/float/float-page.svelte"
-export { default as EntryLineIdb } from "./components/form/entry-line-idb.svelte"
-export { default as EntryLine } from "./components/form/entry-line.svelte"
-export { default as EntryMultiline } from "./components/form/entry-multiline.svelte"
-export { default as EntrySelect } from "./components/form/entry-select.svelte"
-export { default as EntryWrap } from "./components/form/entry-wrap.svelte"
-export { default as FormEntryInput } from "./components/form/form-entry-input.svelte"
-export { default as FormEntryPriceQuantity } from "./components/form/form-entry-price-quantity.svelte"
-export { default as FormEntryPrice } from "./components/form/form-entry-price.svelte"
-export { default as FormEntryQuantity } from "./components/form/form-entry-quantity.svelte"
-export { default as FormEntrySelectInput } from "./components/form/form-entry-select-input.svelte"
-export { default as FormEntrySelect } from "./components/form/form-entry-select.svelte"
-export { default as FormEntryTextarea } from "./components/form/form-entry-textarea.svelte"
-export { default as FormLineLedgerLabelSelectLabel } from "./components/form/form-line-ledger-label-select-label.svelte"
-export { default as FormLineLedgerSelect } from "./components/form/form-line-ledger-select.svelte"
-export { default as FormLineLedger } from "./components/form/form-line-ledger.svelte"
-export { default as FormReviewDisplay } from "./components/form/form-review-display.svelte"
-export { default as TradeFieldDisplayKv } from "./components/form/trade_field_display_kv.svelte"
-export { default as GlyphCircle } from "./components/glyph/glyph-circle.svelte"
-export { default as Glyph } from "./components/glyph/glyph.svelte"
-export { default as LabelDisplay } from "./components/label/label-display.svelte"
-export { default as LayoutBottomButton } from "./components/layout/layout-bottom-button.svelte"
-export { default as LayoutPage } from "./components/layout/layout-page.svelte"
-export { default as LayoutTrellisLine } from "./components/layout/layout-trellis-line.svelte"
-export { default as LayoutTrellis } from "./components/layout/layout-trellis.svelte"
-export { default as LayoutView } from "./components/layout/layout-view.svelte"
-export { default as LayoutWindow } from "./components/layout/layout-window.svelte"
-export { default as Css } from "./components/lib/css.svelte"
-export { default as Empty } from "./components/lib/empty.svelte"
-export { default as Fade } from "./components/lib/fade.svelte"
-export { default as ImageBlob } from "./components/lib/image-blob.svelte"
-export { default as ImagePath } from "./components/lib/image-path.svelte"
-export { default as ImageSrc } from "./components/lib/image-src.svelte"
-export { default as Image } from "./components/lib/image.svelte"
-export { default as InputIdb } from "./components/lib/input-idb.svelte"
-export { default as InputValue } from "./components/lib/input-value.svelte"
-export { default as Input } from "./components/lib/input.svelte"
-export { default as LabelSwap } from "./components/lib/label-swap.svelte"
-export { default as LoadSymbolWhite } from "./components/lib/load-symbol-white.svelte"
-export { default as LoadSymbol } from "./components/lib/load-symbol.svelte"
-export { default as LogoCircleSm } from "./components/lib/logo-circle-sm.svelte"
-export { default as LogoLetters } from "./components/lib/logo-letters.svelte"
-export { default as LogoCircle } from "./components/lib/logo_circle.svelte"
-export { default as SelectMenu } from "./components/lib/select-menu.svelte"
-export { default as Select } from "./components/lib/select.svelte"
-export { default as SplashScreen } from "./components/lib/splash_screen.svelte"
-export { default as Swipe } from "./components/lib/swipe.svelte"
-export { default as TextArea } from "./components/lib/text-area.svelte"
-export { default as Theme } from "./components/lib/theme.svelte"
-export { default as Toast } from "./components/lib/toast.svelte"
-export { default as WrapBorder } from "./components/lib/wrap-border.svelte"
-export { default as MapMarkerAreaDisplay } from "./components/map/map-marker-area-display.svelte"
-export { default as MapMarkerArea } from "./components/map/map-marker-area.svelte"
-export { default as Map } from "./components/map/map.svelte"
-export { default as MarkerIndexedView } from "./components/marker/marker-indexed-view.svelte"
-export { default as NavigationTabs } from "./components/navigation/navigation-tabs.svelte"
-export { default as PageHeader } from "./components/navigation/page-header.svelte"
-export { default as PageToolbar } from "./components/navigation/page-toolbar.svelte"
-export { default as TrellisDefaultLabel } from "./components/trellis/trellis-default-label.svelte"
-export { default as TrellisEnd } from "./components/trellis/trellis-end.svelte"
-export { default as TrellisInput } from "./components/trellis/trellis-input.svelte"
-export { default as TrellisLine } from "./components/trellis/trellis-line.svelte"
-export { default as TrellisOffset } from "./components/trellis/trellis-offset.svelte"
-export { default as TrellisRowDisplayValue } from "./components/trellis/trellis-row-display-value.svelte"
-export { default as TrellisRowLabel } from "./components/trellis/trellis-row-label.svelte"
-export { default as TrellisSelect } from "./components/trellis/trellis-select.svelte"
-export { default as TrellisTitle } from "./components/trellis/trellis-title.svelte"
-export { default as TrellisTouch } from "./components/trellis/trellis-touch.svelte"
-export { default as Trellis } from "./components/trellis/trellis.svelte"
-export { default as ImageUploadAddPhoto } from "./components/upload/image-upload-add-photo.svelte"
-export { default as ImageUploadButtonsAspect } from "./components/upload/image-upload-buttons-aspect.svelte"
-export { default as ImageUploadSimple } from "./components/upload/image-upload-simple.svelte"
-export { default as WindowResizeListener } from "./components/window/window-resize-listener.svelte"
-export { default as WindowSafariListener } from "./components/window/window-safari-listener.svelte"
-export { default as FarmsAddCasliDetail } from "./features/farm/farms-add-casli-detail.svelte"
-export { default as FarmsAddCasliMap } from "./features/farm/farms-add-casli-map.svelte"
-export { default as FarmsDisplayLiEl } from "./features/farm/farms-display-li-el.svelte"
-export { default as FarmsProductsReviewCard } from "./features/farm/farms-products-review-card.svelte"
-export * from "./store/app.js"
-export * from "./store/client.js"
-export * from "./store/component.js"
-export * from "./store/layout.js"
-export * from "./store/ndk.js"
-export * from "./store/nostr.js"
-export * from "./types/component.js"
-export * from "./types/context.js"
-export * from "./types/interface.js"
+export * from "./stores/ndk.js"
+export * from "./stores/theme.js"
export * from "./types/lib.js"
-export * from "./types/view/farm.js"
-export * from "./types/view/lib.js"
-export * from "./types/view/profile.js"
-export * from "./util/carousel.js"
-export * from "./util/casl.js"
-export * from "./util/context/lib.js"
-export * from "./util/idb.js"
-export * from "./util/lib.js"
-export * from "./util/nostr/nostr-poll-relays.js"
-export * from "./util/nostr/nostr-sync.js"
-export * from "./util/service/nostr-event-classified.js"
-export * from "./util/service/nostr-sync.js"
-export * from "./util/styles.js"
-export * from "./util/validation/farm.js"
-export * from "./util/view.js"
-export { default as FarmsAdd } from "./view/farms-add.svelte"
-export { default as FarmsDetails } from "./view/farms-details.svelte"
-export { default as FarmsProductsAdd } from "./view/farms-products-add.svelte"
-export { default as Farms } from "./view/farms.svelte"
-export { default as Home } from "./view/home.svelte"
-export { default as Notifications } from "./view/notifications.svelte"
-export { default as ProfileEdit } from "./view/profile-edit.svelte"
-export { default as Profile } from "./view/profile.svelte"
-export { default as Settings } from "./view/settings.svelte"
+export * from "./types/ndk.js"
+export * from "./utils/idb/lib.js"
+export * from "./utils/lib.js"
diff --git a/apps-lib/src/lib/store/app.ts b/apps-lib/src/lib/store/app.ts
@@ -1,26 +0,0 @@
-import { type IToast } from "$root";
-import type { ColorMode, ThemeKey } from "@radroots/theme";
-import type { AppConfigType, AppLayoutKey, BrowserPlatformInfo } from "@radroots/util";
-import { writable } from "svelte/store";
-
-export const app_lo = writable<AppLayoutKey>();
-export const app_platform = writable<BrowserPlatformInfo | undefined>(undefined);
-export const app_cfg_type = writable<AppConfigType>(`personal`);
-export const app_init = writable<boolean>(false);
-export const app_tilt = writable<boolean>(false);
-export const app_loading = writable<boolean>(false);
-export const app_splash = writable<boolean>(true);
-export const app_notify = writable<string>(``);
-export const app_toast = writable<IToast | false>(false);
-export const app_blur = writable<boolean>(false);
-export const app_db = writable<boolean>(false);
-export const app_geoc = writable<boolean>(false);
-export const app_thc = writable<ColorMode>(`light`);
-export const app_th = writable<ThemeKey>();
-export const app_nostr_profiles = writable<string[]>([]);
-export const app_load = writable<boolean>(false);
-
-export const search_results = writable<any[]>([]);
-
-export const win_h = writable<number>(0);
-export const win_w = writable<number>(0);
diff --git a/apps-lib/src/lib/store/client.ts b/apps-lib/src/lib/store/client.ts
@@ -1,44 +0,0 @@
-import type { NavigationPreviousParam, NavigationRouteParamField, NavigationRouteParamId, NavigationRouteParamLat, NavigationRouteParamLng, NavigationRouteParamNostrPublicKey, NavigationRouteParamRef } from "$root";
-import { writable } from "svelte/store";
-import { queryParam, queryParameters } from "sveltekit-search-params";
-
-export const qp = queryParameters();
-export const qp_id = queryParam<NavigationRouteParamId>("id");
-export const qp_field = queryParam<NavigationRouteParamField>("field");
-export const qp_ref = queryParam<NavigationRouteParamRef>("ref");
-export const qp_lat = queryParam<NavigationRouteParamLat>("lat");
-export const qp_lng = queryParam<NavigationRouteParamLng>("lng");
-export const qp_keynostr = queryParam<NavigationRouteParamNostrPublicKey>("key_nostr");
-
-export const app_pwa_polyfills = writable<boolean>(false);
-
-export const nav_visible = writable<boolean>(false);
-export const nav_blur = writable<boolean>(false);
-export const nav_prev = writable<NavigationPreviousParam<string>[]>([]);
-
-export const layout_view_cover = writable<boolean>(false);
-
-export const tabs_visible = writable<boolean>(false);
-export const tabs_blur = writable<boolean>(false);
-export const tabs_active = writable<number>(0);
-
-export const ph_blur = writable<boolean>(false);
-
-export const carousel_active = writable<boolean>(false);
-export const carousel_index = writable<number>(0);
-export const carousel_index_max = writable<number>(0);
-const fn_carousel_num = (num_i: number, num_min: number) => {
- const store = writable<number>(num_i);
- return {
- subscribe: store.subscribe,
- set: (num: number) => {
- store.set(Math.max(num, num_min));
- },
- update: (updater: (num: number) => number) => {
- store.update((num) => Math.max(updater(num), num_min));
- }
- };
-}
-export const carousel_num = fn_carousel_num(1, 1);
-export const envelope_visible = writable<boolean>(false);
-export const envelope_tilt = writable<boolean>(true);
diff --git a/apps-lib/src/lib/store/component.ts b/apps-lib/src/lib/store/component.ts
@@ -1,4 +0,0 @@
-import { writable } from "svelte/store";
-
-export const casl_i = writable<number>(0);
-export const casl_imax = writable<number>(0);
-\ No newline at end of file
diff --git a/apps-lib/src/lib/store/layout.ts b/apps-lib/src/lib/store/layout.ts
@@ -1,3 +0,0 @@
-import { writable } from "svelte/store";
-
-export const lo_browser_safarinav = writable<boolean>(false);
diff --git a/apps-lib/src/lib/store/ndk.ts b/apps-lib/src/lib/store/ndk.ts
@@ -1,24 +0,0 @@
-import { type NDKCacheAdapter, type NDKUser } from "@nostr-dev-kit/ndk";
-import NDKCacheAdapterDexie from "@nostr-dev-kit/ndk-cache-dexie";
-import NDKSvelte from "@nostr-dev-kit/ndk-svelte";
-import { writable } from "svelte/store";
-
-//@ts-ignore
-const ndk_cache_name = import.meta.env.VITE_PUBLIC_NDK_CACHE_NAME;
-if (!ndk_cache_name) throw new Error('Error: VITE_PUBLIC_NDK_CACHE_NAME is required');
-
-//@ts-ignore
-const ndk_client_name = import.meta.env.VITE_PUBLIC_NDK_CLIENT_NAME;
-if (!ndk_client_name) throw new Error('Error: VITE_PUBLIC_NDK_CLIENT_NAME is required');
-
-
-let cacheAdapter: NDKCacheAdapter | undefined;
-if (typeof window !== `undefined`) cacheAdapter = new NDKCacheAdapterDexie({ dbName: ndk_cache_name });
-
-const ndk_svelte = new NDKSvelte({
- cacheAdapter,
- clientName: ndk_client_name,
-});
-
-export const ndk = writable<NDKSvelte>(ndk_svelte);
-export const ndk_user = writable<NDKUser>();
diff --git a/apps-lib/src/lib/store/nostr.ts b/apps-lib/src/lib/store/nostr.ts
@@ -1,16 +0,0 @@
-import { writable } from "svelte/store";
-
-export const nostr_ndk_configured = writable(false);
-
-export const nostr_sync_prevent = writable(false);
-export const nostr_sync_attempts = writable(0);
-export const nostr_sync_attempts_max = writable(8);
-export const nostr_sync_stop = writable(true);
-
-export const nostr_poll_relays_prevent = writable(false);
-export const nostr_poll_relays_attempts = writable(0);
-export const nostr_poll_relays_attempts_max = writable(0);
-export const nostr_poll_relays_stop = writable(true);
-
-export const nostr_relays_connected = writable<string[]>([]);
-
diff --git a/apps-lib/src/lib/stores/ndk.ts b/apps-lib/src/lib/stores/ndk.ts
@@ -0,0 +1,21 @@
+import { type NDKCacheAdapter, type NDKUser } from "@nostr-dev-kit/ndk";
+import NDKCacheAdapterDexie from "@nostr-dev-kit/ndk-cache-dexie";
+import NDKSvelte from "@nostr-dev-kit/ndk-svelte";
+import { writable } from "svelte/store";
+
+const NDK_CACHE_NAME = import.meta.env.VITE_PUBLIC_NDK_CACHE_NAME;
+if (!NDK_CACHE_NAME) throw new Error('Error: VITE_PUBLIC_NDK_CACHE_NAME is required');
+
+const NDK_CLIENT_NAME = import.meta.env.VITE_PUBLIC_NDK_CLIENT_NAME;
+if (!NDK_CLIENT_NAME) throw new Error('Error: VITE_PUBLIC_NDK_CLIENT_NAME is required');
+
+let cacheAdapter: NDKCacheAdapter | undefined;
+if (typeof window !== `undefined`) cacheAdapter = new NDKCacheAdapterDexie({ dbName: NDK_CACHE_NAME });
+
+const ndk_svelte = new NDKSvelte({
+ cacheAdapter,
+ clientName: NDK_CLIENT_NAME,
+});
+
+export const ndk = writable<NDKSvelte>(ndk_svelte);
+export const ndk_user = writable<NDKUser>();
diff --git a/apps-lib/src/lib/stores/theme.ts b/apps-lib/src/lib/stores/theme.ts
@@ -0,0 +1,13 @@
+import type { ThemeMode } from "$lib/types/lib";
+import { get_store } from "$lib/utils/lib";
+import { type CallbackPromiseGeneric } from "@radroots/utils";
+import { writable } from "svelte/store";
+
+export const theme_mode = writable<ThemeMode>(`light`);
+export const theme_key = writable<string>(`default`);
+
+export const theme_toggle = async (callback: CallbackPromiseGeneric<ThemeMode>): Promise<void> => {
+ const mode = get_store(theme_mode) === `light` ? `dark` : `light`;
+ theme_mode.set(mode);
+ await callback(mode);
+};
+\ No newline at end of file
diff --git a/apps-lib/src/lib/types/component.ts b/apps-lib/src/lib/types/component.ts
@@ -1,252 +0,0 @@
-import type { CallbackRoute, ICb, ICbG, ICbGOpt, ICbOpt, IClOpt, IDisabledOpt, IEntryWrap, IGl, IGlOpt, IGlyphKey, IIdGOpt, IIdOpt, ILabel, ILabelOpt, ILabelTup, ILoadingOpt, ILy, ILyOpt, INavigationRoutePreventRouteNav, NavigationRouteParamKey } from "$root";
-import type { CallbackPromise, CallbackPromiseGeneric, ElementCallbackMount, ElementCallbackValue, ElementCallbackValueBlur, ElementCallbackValueKeydown, FormField, GeometryGlyphDimension, GeometryScreenPosition, GeometryScreenPositionHorizontal, GlyphKey, GlyphWeight, NavigationParamTuple } from "@radroots/util";
-
-export type IButtonNavRound = ICb & IDisabledOpt & ILoadingOpt & IGlyphKey;
-
-export type IFloatPage = {
- posx: Omit<GeometryScreenPositionHorizontal, "center">;
-}
-export type IToastKind = `simple`;
-
-export type IToast = IClOpt &
- ILabel & IGlOpt & ILyOpt & {
- styles?: IToastKind[];
- position?: GeometryScreenPosition;
- };
-
-export type IGlyph = ICbOpt & IIdOpt & ILyOpt & IClOpt & {
- weight?: GlyphWeight;
- key: GlyphKey;
- dim?: GeometryGlyphDimension;
-};
-
-export type IInput<T extends string> = IIdGOpt<T> & IClOpt & ILyOpt & IDisabledOpt & {
- placeholder?: string;
- label?: string;
- hidden?: boolean;
- validate?: RegExp;
- sync?: boolean;
- field?: FormField;
- field_constrain?: boolean;
- callback?: ElementCallbackValue,
- callback_keydown?: ElementCallbackValueKeydown<HTMLInputElement>,
- callback_blur?: ElementCallbackValueBlur<HTMLInputElement>;
- callback_focus?: ElementCallbackValueBlur<HTMLInputElement>;
- callback_mount?: ElementCallbackMount<HTMLInputElement>;
-};
-
-export type IInputValue<T extends string> = Omit<IInput<T>, `sync`>;
-
-export type ISelectOption<T extends string> = IDisabledOpt & {
- value: T;
- label: string;
-};
-
-export type ISelectCallback = CallbackPromiseGeneric<ISelectOption<string>>
-
-export type ISelect = IIdOpt & IClOpt & ILyOpt & {
- callback?: ISelectCallback;
- sync?: boolean;
- sync_init?: boolean;
- options: { group?: string | true; entries: ISelectOption<string>[] }[];
- show_arrows?: 'l' | 'r';
-};
-
-export type ITextArea = IIdOpt & IClOpt & ILyOpt & {
- placeholder?: string;
- label?: string;
- hidden?: boolean;
- validate?: RegExp;
- sync?: true;
- field?: FormField;
- field_constrain?: boolean;
- callback?: ElementCallbackValue,
- callback_keydown?: ElementCallbackValueKeydown<HTMLTextAreaElement>,
- callback_blur?: ElementCallbackValueBlur<HTMLTextAreaElement>;
- callback_focus?: ElementCallbackValueBlur<HTMLTextAreaElement>;
- callback_mount?: ElementCallbackMount<HTMLTextAreaElement>;
-};
-
-export type INavigationRoute<T extends string> = {
- route: T | [T, NavigationParamTuple<NavigationRouteParamKey>[]];
-};
-
-export type IPageToolbar<T extends string> = ICbOpt & {
- header?: IPageHeader<T>;
-};
-
-export type IPageHeader<T extends string> = {
- label: string;
- callback_route?: CallbackRoute<T>;
-};
-
-export type IGlyphCircle = {
- classes_wrap: string;
- glyph: IGlyph
-};
-
-export type ITrellis = ILy &
- IClOpt &
- ITrellisStyles & {
- id?: string;
- view?: string;
- title?: ITrellisTitle;
- description?: ITrellisDescription;
- default_el?: ITrellisDefault;
- list?: (ITrellisKind | undefined)[];
- hide_offset?: true;
- };
-
-export type ITrellisStyles = {
- hide_rounded?: boolean;
- hide_border_top?: boolean;
- hide_border_bottom?: boolean;
- set_title_background?: boolean;
- set_default_background?: boolean;
-};
-
-export type ITrellisTitle = ICbOpt &
- IClOpt & {
- mod?: ITrellisBasisOffsetMod,
- value: string | true;
- link?: ICbOpt &
- IClOpt &
- IGlOpt & ILabelOpt;
- };
-
-export type ITrellisDescription = string | true;
-
-export type ITrellisBasisOffsetModKey = 'sm' | 'glyph';
-export type ITrellisBasisOffsetMod = ITrellisBasisOffsetModKey | (({ glyph: IGlyph } | { glyph_circle: IGlyphCircle }) & {
- loading?: boolean;
-});
-
-export type ITrellisDefault = {
- labels?: ITrellisDefaultLabel[];
- show_title?: boolean;
-};
-
-export type ITrellisDefaultLabel = ICbOpt & {
- label: string;
- classes?: string;
-};
-
-export type ITrellisKind = (
- | ITrellisKindTouch
- | ITrellisKindInput
- | ITrellisKindSelect
-);
-
-export type ITrellisBasis = {
- loading?: boolean;
- hide_active?: boolean;
- hide_field?: boolean;
- offset?: ITrellisBasisOffset;
- full_rounded?: boolean;
-};
-
-export type ITrellisBasisOffset = ICbGOpt<MouseEvent> &
- IClOpt & {
- mod?: ITrellisBasisOffsetMod;
- classes?: string;
- hide_space?: boolean;
- hide_offset?: boolean;
- };
-
-export type ITrellisKindDisplay = {
- display?: ITrellisKindDisplayValue;
-}
-export type ITrellisKindDisplayValue = ICbGOpt<MouseEvent> & ILoadingOpt &
- (ITrellisKindDisplayValueIcon | ILabel);
-
-
-export type ITrellisKindDisplayValueIcon = {
- icon: {
- classes?: string;
- key: GlyphKey;
- };
-};
-export type ITrellisKindTouch = ITrellisBasis & {
- touch: ITrellisBasisTouch;
-};
-
-export type ITrellisBasisTouch = ICbGOpt<MouseEvent> &
- ILabelTup & ITrellisKindDisplay & {
- end?: ITrellisBasisTouchEnd;
- };
-
-export type ITrellisKindInput = ITrellisBasis & {
- input: ITrellisBasisInput;
-};
-
-export type ITrellisBasisInput = {
- basis: IInput<string>;
- line_label?: {
- classes?: string;
- value: string;
- };
- action?: {
- visible: boolean;
- loading?: boolean;
- callback?: CallbackPromise;
- glyph?: IGlyph
- };
-};
-
-export type ITrellisKindSelect = ITrellisBasis & {
- select: ITrellisBasisSelect;
-};
-
-export type ITrellisBasisSelect = ICbGOpt<MouseEvent> &
- ILabelTup & ITrellisKindDisplay & ILoadingOpt & {
- end?: ITrellisBasisTouchEnd;
- el: ISelect & { value: string; };
- };
-
-export type ITrellisBasisTouchEnd = ICbGOpt<MouseEvent> & IGl;
-
-export type INavBasisPrev = IClOpt & ICbG<
- HTMLLabelElement | null
-> & IGlOpt & ILabelOpt & IDisabledOpt & {
- loading?: boolean;
-};
-export type INavBasisOption = IClOpt & ICbG<
- HTMLLabelElement | null
-> & IGlOpt & ILabelOpt & IDisabledOpt & {
- loading?: boolean;
-};
-export type INavBasis<T extends string> = {
- prev: ICbOpt & ILoadingOpt & INavigationRoute<T> & INavigationRoutePreventRouteNav & {
- label?: string;
- kind?: 'arrow'
- };
- title?: ICbOpt & ILabel;
- option?: INavBasisOption;
-};
-
-export type IEntrySelect = ILoadingOpt & {
- wrap: IEntryWrap;
- el: ISelect;
- hide_arrows?: boolean;
-};
-
-export type IButtonSimple = ILyOpt & {
- label: string;
- callback: CallbackPromise;
- allow_propogation?: boolean;
-};
-
-export type IMapMarkerArea = {
- show_display?: boolean;
- no_drag?: boolean;
-}
-
-export type ILayoutTrellisLine = ILabelOpt &
- IClOpt & {
- notify?: IClOpt &
- ICb &
- ILabelOpt &
- IGlOpt & {
- glyph_first?: boolean;
- };
- };
diff --git a/apps-lib/src/lib/types/context.ts b/apps-lib/src/lib/types/context.ts
@@ -1,22 +0,0 @@
-import type { LocalCallbackColorMode, LocalCallbackGeocode, LocalCallbackGeocodeCurrent, LocalCallbackGuiAlert, LocalCallbackGuiConfirm, LocalCallbackImgBin, LocalCallbackPhotosAddMultiple, LocalCallbackPhotosUpload } from "$root";
-import type { I18nTranslateFunction, I18nTranslateLocale } from "@radroots/util";
-
-export type ContextKeys =
- | `lib`;
-
-export type ContextMap = {
- lib: LibContext;
-};
-
-export type LibContext = {
- ls: I18nTranslateFunction;
- locale: I18nTranslateLocale;
- lc_color_mode: LocalCallbackColorMode;
- lc_gui_alert: LocalCallbackGuiAlert;
- lc_gui_confirm: LocalCallbackGuiConfirm;
- lc_geocode: LocalCallbackGeocode;
- lc_photos_add: LocalCallbackPhotosAddMultiple;
- lc_img_bin: LocalCallbackImgBin;
- lc_geop_current: LocalCallbackGeocodeCurrent;
- lc_photos_upload: LocalCallbackPhotosUpload;
-};
-\ No newline at end of file
diff --git a/apps-lib/src/lib/types/interface.ts b/apps-lib/src/lib/types/interface.ts
@@ -1,228 +0,0 @@
-import type { IGlyph, IInput, IInputValue, ISelect, ITextArea } from "$root";
-import type { CallbackPromise, CallbackPromiseGeneric, EntryStyle, GlyphKey, LayerGlyphBasisKind, LoadingBlades, LoadingDimension, SvelteTransitionConfig, ThemeLayer } from "@radroots/util";
-
-export type IDisabled = {
- disabled: boolean | never;
-};
-
-export type IDisabledOpt = Partial<IDisabled>;
-
-export type IBasisOpt<T extends object> = T | undefined;
-
-export type IBasis<T> = {
- basis: T;
-};
-
-export type ICb = {
- callback: CallbackPromise | never;
-};
-
-export type ICbOpt = Partial<ICb>;
-
-export type ICbG<T> = {
- callback: CallbackPromiseGeneric<T> | never;
-};
-
-export type ICbMouseEventOpt = ICbGOpt<
- MouseEvent & {
- currentTarget: EventTarget & HTMLImageElement;
- }
->;
-
-export type ICbGOpt<T> = Partial<ICbG<T>>;
-
-export type ICl = {
- classes: string | never;
-};
-
-export type IClOpt = Partial<ICl>;
-
-export type IClWrap = {
- classes_wr: string | never;
-};
-
-export type IClOptWrap = Partial<IClWrap>;
-
-export type IId = {
- id: string | never;
-};
-
-export type IIdOpt = Partial<IId>;
-
-export type IGl = {
- glyph: IGlyph | never;
-};
-
-export type IGlOpt = Partial<IGl>;
-
-export type IGlyphKey = {
- glyph: GlyphKey
-};
-
-export type ILy = {
- layer: ThemeLayer | never;
-};
-
-export type ILyOpt = Partial<ILy>;
-
-export type ILableFieldsSwap = {
- toggle: boolean;
- on: IClOpt & {
- value: string;
- },
- off: IClOpt & {
- value: string;
- },
-};
-
-export type ILabelSwap = {
- swap: ILableFieldsSwap;
-}
-
-export type ILabelTupFields = {
- left?: ILableFields[];
- right?: ILableFields[];
-};
-
-export type ILabelTup = {
- label: ILabelTupFields;
-};
-
-export type ILableFields = & {
- classes_wrap?: string
- classes?: string;
- kind?: LayerGlyphBasisKind;
- hide_truncate?: boolean;
- hide_active?: boolean;
-} & (
- ({
- value: string;
- } | ILabelSwap)
- | IGl
- );
-
-export type ILabel = {
- label: ILableFields;
-};
-
-export type ILabelOpt = Partial<ILabel>;
-
-export type ILoadSymbol = IClOpt & {
- color?: 'white';
- blades?: LoadingBlades;
- dim?: LoadingDimension;
-};
-
-export type IIdG<T extends string> = {
- id: T | never;
-};
-
-export type IIdGOpt<T extends string> = Partial<IIdG<T>>;
-
-export type IIdWrap = {
- id_wrap: string | never;
-};
-
-export type IIdWrapOpt = Partial<IIdWrap>;
-
-export type ILabelValue = {
- label: IClOpt & {
- value: string;
- };
-};
-
-export type ILabelDisplay = IIdWrapOpt & IClOpt & ILabelValue & ILyOpt & {
- style?: EntryStyle;
-};
-
-
-export type ILoading = {
- loading: boolean | never;
-};
-
-export type ILoadingOpt = Partial<ILoading>;
-
-export type IEntryWrap = IClOpt & IIdOpt & ILyOpt & {
- style?: EntryStyle;
- style_a?: true;
- no_pad?: true;
- fade?: {
- in?: SvelteTransitionConfig;
- out?: SvelteTransitionConfig;
- };
-}
-
-export type IEntryLine = ILoadingOpt & {
- wrap?: IEntryWrap;
- el: IInputValue<string>;
- notify_inline?: {
- glyph: GlyphKey | IGlyph;
- };
-};
-
-export type IEntryLineIdb = ILoadingOpt & {
- wrap?: IEntryWrap;
- el: IInput<string>;
- notify_inline?: {
- glyph: GlyphKey | IGlyph;
- };
-};
-
-export type IEntryLineSelectIdb = ILoadingOpt & {
- wrap?: IEntryWrap;
- el_input: IInput<string>;
- el_sel: ISelect;
- /*notify_inline?: {
- glyph: GlyphKey | IGlyph;
- };*/
-};
-
-export type IEntryMultiLine = {
- wrap?: IEntryWrap;
- el: ITextArea;
- notify_inline?: {
- glyph: GlyphKey | IGlyph;
- };
-}
-
-export type IEnvelopeLower = {
- visible: boolean;
- close: CallbackPromise;
- full_cover?: boolean;
- label_close?: string | true;
-};
-
-export type IButtonRound = IClOpt & ILoadingOpt & {
- label: string;
- callback: CallbackPromise;
-};
-
-export type INavigationRoutePreventRouteNav = {
- prevent_route?: {
- callback: CallbackPromise;
- };
-};
-
-export type INavigationRoutePreventRoute = {
- prevent_route: CallbackPromise;
-};
-
-export type IImage = IIdOpt & IClOpt & {
- src?: string;
- alt?: string;
-};
-
-export type IImageBlob = IIdOpt & IClOpt & {
- data: Uint8Array | undefined;
- alt?: string;
-};
-
-export type IImageSource = IIdOpt & IClOpt & {
- src?: string;
- alt?: string;
-};
-
-export type IImagePath = Omit<IImage, 'src'> & {
- path?: string;
-};
-
diff --git a/apps-lib/src/lib/types/lib.ts b/apps-lib/src/lib/types/lib.ts
@@ -1,26 +1 @@
-import type { INavigationRoute, ISelectOption } from "$root";
-import type { CallbackPromise, CallbackPromiseFull, CallbackPromiseGeneric, CallbackPromiseResult, GeocoderReverseResult, GeolocationPoint, IClientGeolocationPosition, MediaImageUploadResult, NavigationParamTuple } from "@radroots/util";
-
-export type CallbackRoute<T extends string> = CallbackPromise | INavigationRoute<T>;
-
-export type NavigationRouteParamId = `id`;
-export type NavigationRouteParamField = `field`;
-export type NavigationRouteParamRef = `ref`;
-export type NavigationRouteParamLat = `lat`;
-export type NavigationRouteParamLng = `lng`;
-export type NavigationRouteParamNostrPublicKey = `key_nostr`;
-export type NavigationRouteParamKey = NavigationRouteParamId | NavigationRouteParamField | NavigationRouteParamRef | NavigationRouteParamLat | NavigationRouteParamLng | NavigationRouteParamNostrPublicKey;
-export type NavigationRouteParamTuple = NavigationParamTuple<NavigationRouteParamKey>;
-export type NavigationPreviousParam<T extends string> = { route: T, label?: string; params?: NavigationRouteParamTuple[] }
-
-export type LocalCallbackColorMode = CallbackPromiseGeneric<ISelectOption<string>>
-export type LocalCallbackGuiAlert = CallbackPromiseFull<string, boolean>;
-export type LocalCallbackGuiConfirm = CallbackPromiseFull<string | { message: string; ok?: string; cancel?: string }, boolean>;
-export type LocalCallbackGeocode = CallbackPromiseFull<GeolocationPoint, GeocoderReverseResult | undefined>;
-export type LocalCallbackGeocodeCurrent = CallbackPromiseResult<IClientGeolocationPosition>;
-export type LocalCallbackImgBin = CallbackPromiseFull<string, Uint8Array | undefined>;
-export type LocalCallbackPhotosAdd = CallbackPromiseResult<string>;
-export type LocalCallbackPhotosAddMultiple = CallbackPromiseResult<string[]>;
-export type LocalCallbackPhotosUpload = CallbackPromiseFull<{ url: string, path: string }, MediaImageUploadResult | undefined>;
-
-export type MaplibreMap = maplibregl.Map;
-\ No newline at end of file
+export type ThemeMode = 'light' | 'dark';
+\ No newline at end of file
diff --git a/apps-lib/src/lib/types/ndk.ts b/apps-lib/src/lib/types/ndk.ts
@@ -0,0 +1,3 @@
+import type { NDKEvent } from "@nostr-dev-kit/ndk";
+
+export type LibNdkEvent = NDKEvent;
+\ No newline at end of file
diff --git a/apps-lib/src/lib/types/view/farm.ts b/apps-lib/src/lib/types/view/farm.ts
@@ -1,34 +0,0 @@
-import type { FarmExtended, GeocoderReverseResult, GeolocationPoint } from "@radroots/util";
-
-export type IViewFarmsData = {
- list: FarmExtended[];
-};
-
-export type IViewFarmsDetailsData = FarmExtended;
-
-export type IViewFarmsProductsAddData = FarmExtended;
-
-export type IViewFarmsProductsAddSubmitPayload = {
- product: string;
- process: string;
- description: string;
- price_amount: number;
- price_currency: string;
- price_quantity_unit: string;
- photos: string[];
- quantity_amount: number;
- quantity_unit: string;
- quantity_label: string;
- geolocation_point: GeolocationPoint;
- geocode_result: GeocoderReverseResult;
-};
-
-export type IViewFarmsAddSubmission = {
- farm_name: string;
- farm_area?: number;
- farm_area_unit?: string;
- farm_contact_name?: string;
- geolocation_point: GeolocationPoint;
- geocode_result: GeocoderReverseResult;
-};
-
diff --git a/apps-lib/src/lib/types/view/lib.ts b/apps-lib/src/lib/types/view/lib.ts
@@ -1,11 +0,0 @@
-import type { CallbackPromiseGeneric } from "@radroots/util";
-
-export type IViewHomeData = {};
-
-export type IViewOnMount<TypeCallbackParam> = {
- on_mount: CallbackPromiseGeneric<TypeCallbackParam>;
-};
-
-export type IViewOnDestroy<TypeCallbackParam> = {
- on_destroy: CallbackPromiseGeneric<TypeCallbackParam>;
-};
diff --git a/apps-lib/src/lib/types/view/profile.ts b/apps-lib/src/lib/types/view/profile.ts
@@ -1,14 +0,0 @@
-export type IViewProfileData = {
- public_key: string;
- name?: string;
- display_name?: string;
- about?: string;
- picture?: string;
-};
-
-export type ViewProfileEditFieldKey = `name` | `display_name` | `about`;
-
-export type IViewProfileEditData = {
- public_key: string;
- field: ViewProfileEditFieldKey;
-};
diff --git a/apps-lib/src/lib/util/carousel.ts b/apps-lib/src/lib/util/carousel.ts
@@ -1,87 +0,0 @@
-import {
- carousel_active,
- carousel_index,
- carousel_index_max,
- carousel_num,
- get_store
-} from "$root";
-import { exe_iter } from "@radroots/util";
-
-const CAROUSEL_DELAY_MS = 150;
-
-const get_slide_container = <T extends string>(
- view: T,
-): Element | undefined => {
- const el = document.querySelector(
- `[data-carousel-container="${view}"]`,
- );
- return el ? el : undefined;
-};
-
-const get_slide_item = <T extends string>(view: T): Element | undefined => {
- const el = document.querySelector(`[data-carousel-item="${view}"]`);
- return el ? el : undefined;
-};
-
-const carousel_dec_handler = async <T extends string>(
- view: T,
-): Promise<void> => {
- const $carousel_active = get_store(carousel_active);
- if ($carousel_active) return;
- carousel_active.set(true);
- const slide_item = get_slide_item<T>(view);
- const slide_container = get_slide_container<T>(view);
- if (slide_container && slide_item) {
- const slide_w = slide_item?.clientWidth || 0;
- slide_container.scrollLeft -= slide_w;
- const $carousel_index = get_store(carousel_index);
- carousel_index.set(Math.max($carousel_index - 1, 0));
- }
- carousel_active.set(false);
-};
-
-const carousel_inc_handler = async <T extends string>(
- view: T,
-): Promise<void> => {
- const $carousel_active = get_store(carousel_active);
- if ($carousel_active) return;
- carousel_active.set(true);
- const slide_item = get_slide_item<T>(view);
- const slide_container = get_slide_container<T>(view);
- if (slide_container && slide_item) {
- const slide_w = slide_item?.clientWidth || 0;
- slide_container.scrollLeft += slide_w;
- const $carousel_index = get_store(carousel_index);
- const $carousel_index_max = get_store(carousel_index_max);
- carousel_index.set(
- Math.min($carousel_index + 1, $carousel_index_max),
- );
- }
- carousel_active.set(false);
-};
-
-export const carousel_inc = async <T extends string>(
- view: T,
- duration: number = CAROUSEL_DELAY_MS
-): Promise<void> => {
- const $carousel_num = get_store(carousel_num);
- carousel_num.set(1);
- await exe_iter(async () => carousel_inc_handler(view), $carousel_num, duration);
-};
-
-
-export const carousel_dec = async <T extends string>(
- view: T,
- duration: number = CAROUSEL_DELAY_MS
-): Promise<void> => {
- const $carousel_num = get_store(carousel_num);
- carousel_num.set(1);
- await exe_iter(async () => carousel_dec_handler(view), $carousel_num, duration);
-};
-
-export const carousel_init = async <T extends string>(view: T, num_max: number): Promise<void> => {
- await carousel_dec(view);
- carousel_index.set(0);
- carousel_index_max.set(num_max);
- carousel_num.set(1);
-};
diff --git a/apps-lib/src/lib/util/casl.ts b/apps-lib/src/lib/util/casl.ts
@@ -1,20 +0,0 @@
-import { casl_i, casl_imax, get_store } from "$root";
-
-export const casl_inc = async (opts?: 'noflow'): Promise<void> => {
- const $casl_i = get_store(casl_i);
- const $casl_imax = get_store(casl_imax);
- if (opts === 'noflow' && $casl_i < $casl_imax) casl_i.set($casl_i + 1);
- else casl_i.set(($casl_i + 1) % ($casl_imax + 1));
-};
-
-export const casl_dec = async (opts?: 'noflow'): Promise<void> => {
- const $casl_i = get_store(casl_i);
- const $casl_imax = get_store(casl_imax);
- if (opts === 'noflow' && $casl_i > 0) casl_i.set($casl_i - 1);
- else casl_i.set(($casl_i - 1 + ($casl_imax + 1)) % ($casl_imax + 1));
-};
-
-export const casl_init = (index_curr: number, index_max: number): void => {
- casl_i.set(index_curr);
- casl_imax.set(index_max);
-};
diff --git a/apps-lib/src/lib/util/context/lib.ts b/apps-lib/src/lib/util/context/lib.ts
@@ -1,10 +0,0 @@
-import type { ContextMap } from "$lib/types/context";
-import { getContext, setContext } from "svelte";
-
-export const get_context = <K extends keyof ContextMap>(key: K): ContextMap[K] => {
- return getContext(key) as ContextMap[K];
-};
-
-export const set_context = <K extends keyof ContextMap>(key: K, value: ContextMap[K]): void => {
- setContext(key, value);
-};
-\ No newline at end of file
diff --git a/apps-lib/src/lib/util/idb.ts b/apps-lib/src/lib/util/idb.ts
@@ -1,54 +0,0 @@
-import { browser } from "$app/environment";
-import { fmt_id } from "$root";
-
-//@ts-ignore
-const idb_name = import.meta.env.VITE_PUBLIC_IDB_NAME;
-if (!idb_name) throw new Error('Error: VITE_PUBLIC_IDB_NAME is required');
-
-export let idb: Keyva;
-if (browser) idb = new Keyva({ name: idb_name });
-
-export const idb_init = async (): Promise<void> => {
- if (!browser) return;
- const range = Keyva.prefix(`*`);
- const idb_list = await idb.each({ range }, `keys`);
- await Promise.all(idb_list.map((i) => idb.delete(i)));
-};
-
-export const idb_init_page = async (): Promise<void> => {
- if (!browser) return;
- const idb_pref = fmt_id();
- const range = Keyva.prefix(idb_pref);
- const idb_list = await idb.each({ range }, `keys`);
- await Promise.all(idb_list.map((i) => idb.delete(i)));
-};
-
-export const idb_sync = async (list: [string, string][]): Promise<void> => {
- if (!browser) return;
- for (const [key, val] of list) await idb.set(key, val);
-};
-
-export class IdbLib<T extends string> {
- private _idb: Keyva;
-
- constructor(kv: Keyva) {
- this._idb = kv;
- }
- public init = async () => {
- await idb_init_page();
- }
-
- public save = async (key: T, value: string) => {
- await this._idb.set(fmt_id(key), value);
- }
-
- public read = async (key: T): Promise<string | undefined> => {
- const result = await this._idb.get<string>(fmt_id(key));
- if (result) return result;
- return undefined;
- }
-
- public del = async (key: T) => {
- await this._idb.delete(fmt_id(key));
- }
-}
-\ No newline at end of file
diff --git a/apps-lib/src/lib/util/lib.ts b/apps-lib/src/lib/util/lib.ts
@@ -1,106 +0,0 @@
-import { browser } from "$app/environment";
-import { goto } from "$app/navigation";
-import { page } from "$app/state";
-import { win_h, win_w, type CallbackRoute, type NavigationRouteParamKey } from "$root";
-import type { ColorMode, ThemeKey } from "@radroots/theme";
-import { encode_route, fmt_geometry_point_coords, fmt_price, geo_point_to_geometry, parse_currency_marker, type GeolocationPoint, type GeometryPoint, type IErrorCatchCallback } from "@radroots/util";
-import { get } from "svelte/store";
-
-export const get_store = get;
-
-export const theme_set = (theme_key: ThemeKey, color_mode: ColorMode): void => {
- const data_theme = `${theme_key}_${color_mode}`;
- document.documentElement.setAttribute("data-theme", data_theme);
-};
-
-export const fmt_id = (id?: string): string => {
- if (!browser) return ``;
- const pref = location?.pathname.slice(1, -1).replaceAll(`-`, `_`).replaceAll(`/`, `-`).replaceAll(`--`, `-`);
- return `*${pref}${id ? `-${id}` : ``}`
-};
-
-export const catch_err = async (e: unknown, func: string, callback: (opts: IErrorCatchCallback) => Promise<void>): Promise<void> => {
- let name = ``;
- let message = ``;
- let stack = ``;
- let url = ``;
- if (e instanceof Error) {
- name = e.name;
- message = e.message;
- stack = e.stack || ``;
- url = page.url.pathname;
- }
- await callback({ name, message, stack, url, func });
-};
-
-export const handle_err = async (e: unknown, fcall: string): Promise<void> => {
- try {
- return void await catch_err(e, fcall, async (opts) => {
- console.log(`handle_err e `, e)
- console.log(JSON.stringify(opts, null, 4), `handle_err opts`)
- });
- } catch (e) {
- console.log(`(handle_err) `, e)
- }
-};
-
-export const callback_route = async <T extends string>(callback_route: CallbackRoute<T>): Promise<void> => {
- if (`route` in callback_route) {
- if (typeof callback_route.route === `string`) return void await goto(callback_route.route);
- else return void await goto(
- encode_route<string, NavigationRouteParamKey>(
- callback_route.route[0],
- callback_route.route[1],
- ),
- );
- }
- return void await callback_route();
-};
-
-export const query_params_clear = async (): Promise<void> => {
- page.url && await goto(page.url.pathname, { replaceState: true })
-};
-
-export const lib_fmt_price = (locale: string, value: string, currency: string): string => {
- return fmt_price(locale, value, currency);
-};
-
-export const lib_parse_currency_marker = (locale: string, currency: string): string => {
- return parse_currency_marker(locale, currency);
-};
-
-export const lib_fmt_geometry_point_coords = (locale: string, point: GeometryPoint): string => {
- return fmt_geometry_point_coords(point, locale);
-};
-
-export const loc_fmt_geo_point_coords = (locale: string, geo_point: GeolocationPoint): string => {
- const point = geo_point_to_geometry(geo_point);
- if (!point) return ``; //@todo
- return fmt_geometry_point_coords(point, locale);
-};
-
-
-export const view_effect = <T extends string>(view: T): void => {
- if (!browser) return;
- for (const el of document.querySelectorAll(`[data-view]`)) {
- if (el.getAttribute(`data-view`) !== view) el.classList.add(`hidden`)
- else el.classList.remove(`hidden`)
- }
-};
-
-export const window_set = (): void => {
- if (!browser) return;
- win_h.set(window.innerHeight);
- win_w.set(window.innerWidth);
-};
-
-export const geop_is_valid = (point?: GeolocationPoint): boolean => {
- if (!point) return false;
- return !(point.lat === 0 && point.lng === 0);
-};
-export const geop_init = (): GeolocationPoint => ({ lat: 0, lng: 0 });
-
-export const focus_map_marker = (): void => {
- const el = document.querySelector(".maplibregl-marker");
- if (el instanceof HTMLElement) el.click();
-};
-\ No newline at end of file
diff --git a/apps-lib/src/lib/util/nostr/nostr-poll-relays.ts b/apps-lib/src/lib/util/nostr/nostr-poll-relays.ts
@@ -1,72 +0,0 @@
-import { get_store, handle_err, ndk_user, nostr_poll_relays_attempts, nostr_poll_relays_attempts_max, nostr_poll_relays_stop, nostr_relays_connected } from "$root";
-import { type CallbackPromiseFull, type CallbackPromiseGeneric, type ErrorMessage, type I18nTranslateFunction, type IHttpResponse } from "@radroots/util";
-import { lib_nostr_relay_build_information_document, type NostrRelayInformationDocumentFields } from "@radroots/utils-nostr";
-
-export const nostr_poll_relays_retry_handler = async (callback: () => Promise<any>) => {
- let current_count = 0;
- const attempts_max = get_store(nostr_poll_relays_attempts_max);
-
- nostr_poll_relays_attempts.set(0);
- nostr_poll_relays_stop.set(false);
-
- const exe = async () => {
- if (get_store(nostr_poll_relays_stop)) return;
- console.log(`[nostr poll relays] attempt ${current_count}`)
- try {
- await callback();
- } catch (e) {
- current_count += 1;
- nostr_poll_relays_attempts.set(current_count);
- if (current_count < attempts_max) {
- await new Promise((res) => setTimeout(res, 2000));
- await exe();
- } else nostr_poll_relays_stop.set(true);
- }
- };
-
- await exe();
-};
-
-export const nostr_poll_relays_handler = async (opts: {
- ls: I18nTranslateFunction;
- callback_alert: CallbackPromiseGeneric<string>;
- callback_relay_urls: CallbackPromiseFull<string, { id: string; url: string; }[]>;
- callback_fetch_document: CallbackPromiseFull<string, IHttpResponse | ErrorMessage<string>>;
- callback_set_relay_document: CallbackPromiseGeneric<{ url: string; doc: NostrRelayInformationDocumentFields; }>;
-}): Promise<void> => {
- try {
- const { ls, callback_alert, callback_relay_urls, callback_fetch_document, callback_set_relay_document } = opts;
- const $ls = get_store(ls);
- const $ndk_user = get_store(ndk_user);
- const public_key = $ndk_user?.pubkey;
- if (!public_key) return void await callback_alert(`${$ls(`error.client.nostr.missing_public_key`)}`);
- const $nostr_relays_connected = get_store(nostr_relays_connected);
-
- const relay_urls = await callback_relay_urls(public_key);
- const unconnected_relays = relay_urls.filter(
- (i) => !$nostr_relays_connected.includes(i.id),
- );
- if (unconnected_relays.length === 0) return void nostr_poll_relays_stop.set(true);
-
- for (const relay of unconnected_relays) {
- const res = await callback_fetch_document(relay.url);
- if (`err` in res) continue;
- else if (res.status === 200 && res.data) {
- const doc = lib_nostr_relay_build_information_document(res.data);
- if (!doc) continue;
- await callback_set_relay_document({ url: relay.url, doc });
- nostr_relays_connected.set(
- Array.from(
- new Set([
- ...$nostr_relays_connected,
- relay.id,
- ]),
- ),
- );
- }
-
- }
- } catch (e) {
- await handle_err(e, `nostr_poll_relays_handler`);
- }
-};
diff --git a/apps-lib/src/lib/util/nostr/nostr-sync.ts b/apps-lib/src/lib/util/nostr/nostr-sync.ts
@@ -1,63 +0,0 @@
-import { get_store, handle_err, ndk_user, nostr_sync, nostr_sync_attempts, nostr_sync_attempts_max, nostr_sync_prevent, nostr_sync_stop } from "$root";
-import { throw_err, type CallbackPromiseFull, type CallbackPromiseGeneric, type I18nTranslateFunction } from "@radroots/util";
-import type { INostrMetadata } from "@radroots/utils-nostr";
-
-export const nostr_sync_retry_handler = async (callback: () => Promise<any>) => {
- let current_count = 0;
- const attempts_max = get_store(nostr_sync_attempts_max);
-
- nostr_sync_attempts.set(0);
- nostr_sync_stop.set(false);
-
- const exe = async () => {
- if (get_store(nostr_sync_stop)) return;
- console.log(`[nostr sync] attempt ${current_count}`)
- try {
- await callback();
- } catch (e) {
- current_count += 1;
- nostr_sync_attempts.set(current_count);
- if (current_count < attempts_max) {
- await new Promise((res) => setTimeout(res, 500));
- await exe();
- } else nostr_sync_stop.set(true);
- }
- };
-
- await exe();
-};
-
-export const nostr_sync_handler = async (opts: {
- ls: I18nTranslateFunction;
- callback_alert: CallbackPromiseGeneric<string>;
- callback_confirm: CallbackPromiseFull<string, boolean>;
- callback_metadata: CallbackPromiseFull<string, INostrMetadata>;
- callback_relay_urls: CallbackPromiseFull<string, { id: string; url: string; }[]>;
-}): Promise<void> => {
- try {
- const { ls, callback_alert, callback_confirm, callback_metadata, callback_relay_urls } = opts;
- const $ls = get_store(ls);
- const $ndk_user = get_store(ndk_user);
- const public_key = $ndk_user.pubkey;
- if (!public_key) return void await callback_alert(`${$ls(`error.client.nostr.missing_public_key`)}`);
-
- const $nostr_sync_prevent = get_store(nostr_sync_prevent);
- if ($nostr_sync_prevent) {
- const confirm = await callback_confirm(`${$ls(`error.client.nostr.sync_disabled`)}`);
- if (confirm) nostr_sync_prevent.set(false);
- else return;
- }
-
- const metadata = await callback_metadata(public_key);
- const ev = await nostr_sync.metadata({ metadata });
- if (`err` in ev) throw_err(ev);
- await ev.publish();
-
- const relays = await callback_relay_urls(public_key);
- for (const relay of relays) {
- //@todo
- }
- } catch (e) {
- await handle_err(e, `nostr_sync_handler`);
- }
-};
-\ No newline at end of file
diff --git a/apps-lib/src/lib/util/service/nostr-event-classified.ts b/apps-lib/src/lib/util/service/nostr-event-classified.ts
@@ -1,274 +0,0 @@
-import type { NDKEvent } from '@nostr-dev-kit/ndk';
-import type NDKSvelte from '@nostr-dev-kit/ndk-svelte';
-import { derived, writable, type Readable, type Unsubscriber, type Writable } from 'svelte/store';
-
-const E_REF = 'e_ref';
-
-export interface NostrEventsClassifiedBundle {
- event: NDKEvent;
- job_results: NDKEvent[];
- job_feedback: NDKEvent[];
- loading: boolean;
- on_job_result?: (callback: (ev: NDKEvent) => void) => Unsubscriber;
-}
-
-export type NostrEventClassifiedSubscriptionServiceBundleStore = Readable<NostrEventsClassifiedBundle>;
-export type NostrEventClassifiedSubscriptionServiceStore = Readable<Map<string, NostrEventsClassifiedBundle>>;
-export type NostrEventClassifiedSubscriptionServiceOnJobResult = Readable<NDKEvent | undefined>;
-
-export class NostrEventClassifiedSubscriptionService {
- private ndk: NDKSvelte;
- private subscription: ReturnType<NDKSvelte['subscribe']> | null = null;
- private filter_subscription: Unsubscriber | null = null;
-
- private filter_authors: Writable<string[] | undefined> = writable();
- private filter_kinds: Writable<number[]> = writable([30402, 6300, 7000]);
-
- private events_list: Writable<NDKEvent[]> = writable([]);
- private job_results: Writable<NDKEvent[]> = writable([]);
- private job_feedback: Writable<NDKEvent[]> = writable([]);
-
- private loading_map: Writable<Record<string, boolean>> = writable({});
- public loading: Readable<Record<string, boolean>> = this.loading_map;
-
- private timeouts: Map<string, number> = new Map();
-
- private bundle_map: Map<string, Writable<NostrEventsClassifiedBundle>> = new Map();
-
- private job_results_notification: Writable<NDKEvent | undefined> = writable(undefined);
- public readonly on_job_result: NostrEventClassifiedSubscriptionServiceOnJobResult = this.job_results_notification;
-
- public store: NostrEventClassifiedSubscriptionServiceStore;
-
- private load_complete = false;
-
- constructor(ndk: NDKSvelte) {
- this.ndk = ndk;
-
- this.store = derived(
- [this.events_list, this.job_results, this.job_feedback, this.loading_map],
- ([$events, $results, $feedback, $loading]) => {
- const map = new Map<string, NostrEventsClassifiedBundle>();
-
- for (const ev of $events) {
- if (!ev.id) continue;
-
- const bundle: NostrEventsClassifiedBundle = {
- event: ev,
- job_results: [],
- job_feedback: [],
- loading: Boolean($loading[ev.id]),
- on_job_result: (callback: (ev: NDKEvent) => void): Unsubscriber => {
- const ev_id = ev.id!;
- const subscription_start_time = Date.now();
-
- const unsubscribe = this.job_results.subscribe((list: NDKEvent[]) => {
- for (const e of list) {
- const ref_id = e.tags?.find(([tag]) => tag === E_REF)?.[1];
- const ev_created_at = (e.created_at ?? 0) * 1000;
- if (ref_id === ev_id && ev_created_at > subscription_start_time) callback(e);
- }
- });
-
- return unsubscribe;
- },
- };
-
- map.set(ev.id, bundle);
-
- if (!this.bundle_map.has(ev.id)) {
- this.bundle_map.set(ev.id, writable(bundle));
- } else {
- this.bundle_map.get(ev.id)!.set(bundle);
- }
- }
-
- for (const ev of $results) {
- const ref = ev.tags?.find(([tag]) => tag === E_REF)?.[1];
- if (ref && map.has(ref)) {
- map.get(ref)!.job_results.push(ev);
- }
- }
-
- for (const ev of $feedback) {
- const ref = ev.tags?.find(([tag]) => tag === E_REF)?.[1];
- if (ref && map.has(ref)) {
- map.get(ref)!.job_feedback.push(ev);
- }
- }
-
- for (const [id, bundle] of map.entries()) {
- if (this.bundle_map.has(id)) {
- this.bundle_map.get(id)!.set(bundle);
- }
- }
-
- return map;
- }
- );
-
- this.filter_subscription = derived(
- [this.filter_authors, this.filter_kinds],
- ([$authors, $kinds]) => ({ authors: $authors, kinds: $kinds })
- ).subscribe(({ authors, kinds }) => {
- this.restart_subscription(authors, kinds);
- });
-
- this.restart_subscription(undefined, [30402, 6300, 7000]);
- }
-
- public set_filter_authors(authors: string[]): void {
- this.filter_authors.set(authors);
- }
-
- public set_filter_kinds(kinds: number[]): void {
- this.filter_kinds.set(kinds);
- }
-
- public get_event_bundle(eventId: string): NostrEventClassifiedSubscriptionServiceBundleStore | undefined {
- if (!this.bundle_map.has(eventId)) {
- return undefined;
- }
- return this.bundle_map.get(eventId)!;
- }
-
- public async await_job_request(event_id: string): Promise<NDKEvent> {
- this.loading_map.update(states => ({ ...states, [event_id]: true }));
- this.clear_timeout(event_id);
-
- try {
- const result = await new Promise<NDKEvent>((resolve, reject) => {
- let unsubscribe_res: Unsubscriber;
- let unsubscribe_fb: Unsubscriber;
- let seen_jobres = false;
- let seen_jobfb = false;
-
- const cleanup_subs = () => {
- unsubscribe_res();
- unsubscribe_fb();
- };
-
- const on_response = (ev: NDKEvent) => {
- cleanup_subs();
- this.clear_timeout(event_id);
- resolve(ev);
- setTimeout(() => {
- this.loading_map.update(states => {
- const { [event_id]: _, ...rest } = states;
- return rest;
- });
- }, 0);
- };
-
- unsubscribe_res = this.job_results.subscribe(list => {
- if (!seen_jobres) { seen_jobres = true; return; }
- const ev = list.find(e =>
- e.tags?.find(([t]) => t === E_REF)?.[1] === event_id
- );
- if (ev) on_response(ev);
- });
-
- unsubscribe_fb = this.job_feedback.subscribe(list => {
- if (!seen_jobfb) { seen_jobfb = true; return; }
- const ev = list.find(e =>
- e.tags?.find(([t]) => t === E_REF)?.[1] === event_id
- );
- if (ev) on_response(ev);
- });
-
- const timeout_id = window.setTimeout(() => {
- cleanup_subs();
- this.loading_map.update(states => {
- const { [event_id]: _, ...rest } = states;
- return rest;
- });
- this.clear_timeout(event_id);
- reject(new Error(`Timeout waiting for job result for event ${event_id}`));
- }, 7000);
-
- this.timeouts.set(event_id, timeout_id);
- });
-
- return result;
- } catch (err) {
- this.loading_map.update(states => {
- const { [event_id]: _, ...rest } = states;
- return rest;
- });
- throw err;
- }
- }
-
- private restart_subscription(authors?: string[], kinds: number[] = []): void {
- if (this.subscription) {
- this.subscription.stop();
- this.subscription = null;
- }
-
- this.events_list.set([]);
- this.job_results.set([]);
- this.job_feedback.set([]);
- this.clear_all_loading();
-
- this.load_complete = false;
-
- const filter = { kinds, ...(authors ? { authors } : {}) };
- const sub = this.ndk.subscribe(filter, { closeOnEose: false });
-
- sub.on('event', (event: NDKEvent) => {
- console.log(`event `, event.kind, event.id)
- switch (event.kind) {
- case 30402:
- event.tags.forEach(i => {
- if (i[0].includes(`price`) || i[0].includes(`quantity`)) console.log(i.join(`, `))
- })
- this.events_list.update(arr => [...arr, event]);
- break;
- case 6300:
- this.job_results.update(arr => [...arr, event]);
- if (this.load_complete) {
- this.job_results_notification.set(event);
- }
- break;
- case 7000:
- this.job_feedback.update(arr => [...arr, event]);
- break;
- }
- });
-
- sub.on('eose', () => {
- this.load_complete = true;
- });
-
- sub.start();
- this.subscription = sub;
- }
-
- private clear_timeout(event_id: string) {
- const to = this.timeouts.get(event_id);
- if (to !== undefined) {
- clearTimeout(to);
- this.timeouts.delete(event_id);
- }
- }
-
- private clear_all_loading() {
- for (const to of this.timeouts.values()) {
- clearTimeout(to);
- }
- this.timeouts.clear();
- this.loading_map.set({});
- }
-
- public destroy(): void {
- if (this.subscription) {
- this.subscription.stop();
- this.subscription = null;
- }
- if (this.filter_subscription) {
- this.filter_subscription();
- this.filter_subscription = null;
- }
- this.clear_all_loading();
- }
-}
diff --git a/apps-lib/src/lib/util/service/nostr-sync.ts b/apps-lib/src/lib/util/service/nostr-sync.ts
@@ -1,42 +0,0 @@
-import { get_store, handle_err, ndk, ndk_user } from "$root";
-import type { NDKEvent, NDKUser } from "@nostr-dev-kit/ndk";
-import type NDKSvelte from "@nostr-dev-kit/ndk-svelte";
-import { err_msg, type ErrorMessage } from "@radroots/util";
-import { ndk_event_metadata, type INostrMetadata } from "@radroots/utils-nostr";
-
-export type INostrSyncServiceMetadata = {
- metadata: INostrMetadata;
-};
-
-export type INostrSyncService = {
- metadata: (opts: INostrSyncServiceMetadata) => Promise<NDKEvent | ErrorMessage<string>>;
-};
-
-export class NostrSyncService implements INostrSyncService {
- constructor() { }
-
- private config = (): { $ndk: NDKSvelte; $ndk_user: NDKUser } => {
- const $ndk = get_store(ndk);
- const $ndk_user = get_store(ndk_user);
- return { $ndk, $ndk_user };
- }
-
- public metadata = async (opts: INostrSyncServiceMetadata): Promise<NDKEvent | ErrorMessage<string>> => {
- try {
- const { $ndk: ndk, $ndk_user: ndk_user } = this.config();
- const { metadata: data } = opts;
- const ev = await ndk_event_metadata({
- ndk,
- ndk_user,
- data,
- });
- if (ev) return ev;
- return err_msg(`error.nostr.sync.metadata.missing_event`);
- } catch (e) {
- await handle_err(e, `metadata`);
- return err_msg(`error.nostr.sync.failure`); //@todo
- }
- }
-}
-
-export const nostr_sync = new NostrSyncService();
-\ No newline at end of file
diff --git a/apps-lib/src/lib/util/styles.ts b/apps-lib/src/lib/util/styles.ts
@@ -1,45 +0,0 @@
-import type { IToastKind } from "$lib/types/component";
-import type { AppLayoutKey, GeometryGlyphDimension, LoadingDimension } from "@radroots/util";
-
-export const glyph_style_map: Map<GeometryGlyphDimension, { gl_1: number; dim_1?: number; }> = new Map([
- ["xs--", { gl_1: 12 }],
- ["xs-", { gl_1: 12, dim_1: 17 }],
- ["xs", { gl_1: 15, dim_1: 18 }],
- ["xs+", { gl_1: 18, dim_1: 20 }],
- ["sm-", { gl_1: 19, dim_1: 22 }],
- ["sm", { gl_1: 20, dim_1: 24 }],
- ["sm+", { gl_1: 21 }],
- ["md-", { gl_1: 23 }],
- ["md", { gl_1: 24 }],
- ["md+", { gl_1: 26 }],
- ["lg-", { gl_1: 27 }],
- ["lg", { gl_1: 28 }],
- ["xl", { gl_1: 30 }],
- ["xl+", { gl_1: 40 }],
-]);
-
-export const loading_style_map: Map<LoadingDimension, { dim_1: number; gl_2: number }> = new Map([
- ["glyph-send-button", { dim_1: 20, gl_2: 20 }],
- ["xs", { dim_1: 12, gl_2: 12 }],
- ["sm", { dim_1: 16, gl_2: 16 }],
- ["md", { dim_1: 20, gl_2: 20 }],
- ["lg", { dim_1: 28, gl_2: 28 }],
- ["xl", { dim_1: 36, gl_2: 36 }],
-]);
-
-export const toast_layout_map: Map<AppLayoutKey, string> = new Map([
- [`ios0`, `pt-8`],
- [`ios1`, `pt-16`],
- [`webm0`, `pt-8`],
- [`webm1`, `pt-16`],
-]);
-
-export const toast_style_map: Map<IToastKind, { inner: string; outer: string }> = new Map([
- [
- `simple`,
- {
- inner: `justify-center`,
- outer: `min-h-toast_min w-full px-4 rounded-2xl shadow-sm`,
- },
- ],
-]);
-\ No newline at end of file
diff --git a/apps-lib/src/lib/util/validation/farm.ts b/apps-lib/src/lib/util/validation/farm.ts
@@ -1,28 +0,0 @@
-import { dev } from "$app/environment";
-import type { IViewFarmsAddSubmission, IViewFarmsProductsAddSubmitPayload } from "$lib/types/view/farm";
-import { form_fields, schema_geocode_result, schema_geolocation_point, util_rxp, zf_numf_pos, zf_numi_pos, zf_price } from "@radroots/util";
-import { z } from "zod";
-
-export const schema_view_farms_add_submission: z.ZodSchema<IViewFarmsAddSubmission> = z.object({
- farm_name: z.string().regex(form_fields.farm_name.validate),
- farm_area: zf_numf_pos.optional(),
- farm_area_unit: z.string().regex(form_fields.area_unit.validate).optional(),
- farm_contact_name: z.string().regex(form_fields.contact_name.validate).optional(),
- geolocation_point: schema_geolocation_point,
- geocode_result: schema_geocode_result,
-});
-
-export const schema_view_farms_products_add_submission: z.ZodSchema<IViewFarmsProductsAddSubmitPayload> = z.object({
- product: z.string().regex(form_fields.product_key.validate),
- process: z.string().regex(form_fields.product_process.validate),
- description: z.string().regex(form_fields.product_description.validate),
- price_amount: zf_price,
- price_currency: z.string().regex(form_fields.price_currency.validate),
- price_quantity_unit: z.string().regex(form_fields.quantity_unit.validate),
- photos: z.array(z.string().regex(dev ? util_rxp.url_image_upload_dev : util_rxp.url_image_upload)),
- quantity_amount: zf_numi_pos,
- quantity_unit: z.string().regex(form_fields.quantity_unit.validate),
- quantity_label: z.string().regex(form_fields.quantity_label.validate),
- geolocation_point: schema_geolocation_point,
- geocode_result: schema_geocode_result,
-});
-\ No newline at end of file
diff --git a/apps-lib/src/lib/util/view.ts b/apps-lib/src/lib/util/view.ts
@@ -1,12 +0,0 @@
-import type { ViewProfileEditFieldKey } from "$root";
-
-export const parse_view_profile_field_key = (val?: string | null): ViewProfileEditFieldKey | undefined => {
- switch (val) {
- case `name`:
- case `display_name`:
- case `about`:
- return val;
- default:
- return undefined;
- }
-};
-\ No newline at end of file
diff --git a/apps-lib/src/lib/utils/idb/lib.ts b/apps-lib/src/lib/utils/idb/lib.ts
@@ -0,0 +1,87 @@
+import { browser } from '$app/environment';
+import { fmt_id } from '../lib';
+
+const IDB_NAME = import.meta.env.VITE_PUBLIC_IDB_NAME;
+if (!IDB_NAME) throw new Error('VITE_PUBLIC_IDB_NAME is required');
+
+
+let _kv: Keyva | null = null;
+export function get_idb(): Keyva {
+ if (!browser) throw new Error('IndexedDB not available on server');
+ if (!_kv) _kv = new Keyva({ name: IDB_NAME });
+ return _kv;
+}
+
+export class IdbLib<
+ CKey extends string,
+ CMap extends Record<CKey, any>,
+ SKey extends string,
+ SMap extends Record<SKey, any>
+> {
+ private get kv(): Keyva {
+ return get_idb();
+ }
+
+ public async save_global(key: CKey, value: CMap[CKey]): Promise<void> {
+ await this.kv.set(key, value);
+ }
+
+ public async read_global<K extends CKey>(key: K): Promise<CMap[K] | undefined> {
+ const result = await this.kv.get<CMap[K]>(key);
+ return result ? result : undefined;
+ }
+
+ public async del_global(key: CKey): Promise<void> {
+ await this.kv.delete(key);
+ }
+
+ public async list_global(): Promise<Array<[CKey, CMap[CKey]]>> {
+ const entries = await this.kv.each<CMap[CKey]>();
+ return entries.map(([rk, v]) => [rk as CKey, v]);
+ }
+
+ private keyof(key: SKey): string {
+ return fmt_id(key);
+ }
+
+ public async save(key: SKey, value: SMap[SKey]): Promise<void> {
+ await this.kv.set(this.keyof(key), value);
+ }
+
+ public async read(key: SKey): Promise<SMap[SKey] | undefined> {
+ const result = await this.kv.get<SMap[SKey]>(this.keyof(key));
+ return result ? result : undefined;
+ }
+
+ public async del(key: SKey): Promise<void> {
+ await this.kv.delete(this.keyof(key));
+ }
+
+ public async list(): Promise<Array<[SKey, SMap[SKey]]>> {
+ const prefix = fmt_id();
+ const range = Keyva.prefix(prefix);
+ const entries = await this.kv.each<SMap[SKey]>({ range });
+ return entries.map(([rk, v]) => {
+ const str = String(rk);
+ const suffix = str.startsWith(prefix) ? str.slice(prefix.length) : str;
+ return [suffix as SKey, v];
+ });
+ }
+
+ public async clear_all(): Promise<void> {
+ const range = Keyva.prefix('*');
+ const keys = await this.kv.each({ range }, 'keys');
+ if (keys.length) await Promise.all(keys.map((k) => this.kv.delete(k)));
+ }
+
+ public async clear_scope(): Promise<void> {
+ const prefix = fmt_id();
+ const range = Keyva.prefix(prefix);
+ const keys = await this.kv.each({ range }, 'keys');
+ if (keys.length) await Promise.all(keys.map((k) => this.kv.delete(k)));
+ }
+
+ public async sync_batch(entries: Array<[string, any]>): Promise<void> {
+ if (entries.length) await this.kv.set(entries);
+ }
+}
diff --git a/apps-lib/src/lib/utils/lib.ts b/apps-lib/src/lib/utils/lib.ts
@@ -0,0 +1,41 @@
+import { browser } from '$app/environment';
+import type { ThemeMode } from '$lib/types/lib';
+import { get } from "svelte/store";
+
+export const get_store = get;
+
+export const trim_slashes = (path: string): string =>
+ path.replace(/^\/+|\/+$/g, '');
+
+export const normalize_path = (path: string): string =>
+ path
+ .replace(/-/g, '_')
+ .replace(/\//g, '-')
+ .replace(/-+/g, '-');
+
+export const sanitize_path = (id: string): string =>
+ id.replace(/[^A-Za-z0-9_-]+/g, '');
+
+export const fmt_id = (raw_id?: string): string => {
+ if (!browser) return '';
+ const pathname = window.location.pathname;
+ const trimmed = trim_slashes(pathname);
+ const prefix = normalize_path(trimmed);
+ const suffix = raw_id ? `-${sanitize_path(raw_id)}` : '';
+ return `*${prefix}${suffix}`;
+};
+
+export const build_storage_key = (
+ raw_id: string,
+ base_prefix: string
+): string =>
+ `${fmt_id()}-${sanitize_path(raw_id)}`
+ .replace(new RegExp(`^\\*${normalize_path(trim_slashes(base_prefix))}-?`), '*');
+
+export const get_system_theme = (): ThemeMode => {
+ return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
+};
+
+export const theme_set = (theme_key: string, color_mode: ThemeMode): void => {
+ document.documentElement.setAttribute("data-theme", `${theme_key}_${color_mode}`);
+};
+\ No newline at end of file
diff --git a/apps-lib/src/lib/view/farms-add.svelte b/apps-lib/src/lib/view/farms-add.svelte
@@ -1,223 +0,0 @@
-<script lang="ts">
- import LayoutBottomButton from "$lib/components/layout/layout-bottom-button.svelte";
- import { schema_view_farms_add_submission } from "$lib/util/validation/farm";
- import {
- app_platform,
- ButtonLayoutPair,
- Carousel,
- casl_dec,
- casl_i,
- casl_inc,
- casl_init,
- FarmsAddCasliDetail,
- FarmsAddCasliMap,
- fmt_id,
- focus_map_marker,
- geop_init,
- geop_is_valid,
- get_context,
- handle_err,
- LayoutView,
- PageToolbar,
- type CallbackRoute,
- type IViewFarmsAddSubmission,
- } from "$root";
- import {
- el_id,
- geol_lat_fmt,
- geol_lng_fmt,
- parse_float,
- parse_geocode_address,
- type CallbackPromiseGeneric,
- type GeocoderReverseResult,
- type GeolocationAddress,
- type GeolocationPoint,
- } from "@radroots/util";
- import { onMount } from "svelte";
-
- const { ls, locale, lc_gui_alert, lc_geop_current, lc_geocode } =
- get_context(`lib`);
-
- let {
- basis,
- }: {
- basis: {
- callback_route?: CallbackRoute<string>;
- on_submit: CallbackPromiseGeneric<{
- payload: IViewFarmsAddSubmission;
- }>;
- };
- } = $props();
-
- let map_geop: GeolocationPoint = $state(geop_init());
- let map_geoc: GeocoderReverseResult | undefined = $state(undefined);
-
- let val_farmname = $state(``);
- let val_farmaddress = $state(``);
- let val_farmcontact = $state(``);
- let val_farmarea = $state(``);
- let val_farmarea_unit = $state(`ac`);
-
- const disabled_submit = $derived($casl_i === 1 && !val_farmname);
-
- onMount(async () => {
- try {
- casl_init(0, 2);
- } catch (e) {
- handle_err(e, `on_mount`);
- }
- });
-
- const farm_geop_lat = $derived(
- geop_is_valid(map_geop)
- ? geol_lat_fmt(map_geop.lat, `dms`, $locale, 3)
- : ``,
- );
-
- const farm_geop_lng = $derived(
- geop_is_valid(map_geop)
- ? geol_lng_fmt(map_geop.lng, `dms`, $locale, 3)
- : ``,
- );
-
- const farm_geolocation_address: GeolocationAddress | undefined = $derived(
- parse_geocode_address(map_geoc),
- );
-
- $effect(() => {
- if (farm_geolocation_address)
- val_farmaddress = `${farm_geolocation_address.primary}, ${farm_geolocation_address.admin}, ${farm_geolocation_address.country}`;
- });
-
- const handle_enter_location = async (): Promise<void> => {
- map_geoc = undefined;
- map_geop = geop_init();
- val_farmaddress = ``;
- await handle_continue();
- el_id(fmt_id(`farm_location`))?.focus();
- };
-
- const handle_continue_1 = async (): Promise<void> => {
- if (!map_geop || !map_geoc)
- return void lc_gui_alert(`No farm location provided.`); //@todo
- const farms_add_submission = schema_view_farms_add_submission.safeParse(
- {
- farm_name: val_farmname,
- farm_area: val_farmarea ? parse_float(val_farmarea) : undefined,
- farm_area_unit:
- val_farmarea && val_farmarea_unit
- ? val_farmarea_unit
- : undefined,
- farm_contact_name: val_farmcontact
- ? val_farmcontact
- : undefined,
- geolocation_point: map_geop,
- geocode_result: map_geoc,
- } satisfies IViewFarmsAddSubmission,
- );
-
- if (!farms_add_submission.success) {
- return void lc_gui_alert(
- `Request invalid: ${farms_add_submission.error}`,
- ); //@todo
- }
- await basis.on_submit({ payload: farms_add_submission.data });
- };
-
- const handle_continue = async (): Promise<void> => {
- switch ($casl_i) {
- case 1:
- return await handle_continue_1();
- default:
- await casl_inc();
- }
- };
-
- const handle_back = async (): Promise<void> => {
- switch ($casl_i) {
- case 1: {
- if (!geop_is_valid(map_geop)) {
- const geop_cur = await lc_geop_current();
- if (geop_cur) {
- map_geop = geop_cur;
- const geoc_cur = await lc_geocode(geop_cur);
- if (geoc_cur) map_geoc = geoc_cur;
- focus_map_marker();
- }
- }
- }
- default:
- return await casl_dec();
- }
- };
-</script>
-
-<LayoutView>
- <PageToolbar
- basis={{
- header: {
- label: `${$ls(`common.farms`)} / ${`${$ls(`common.add`)}`}`,
- callback_route: basis.callback_route,
- },
- }}
- >
- {#snippet header_option()}
- <!-- @todo {#if $casl_i === 0}
- <button
- class={`flex flex-row justify-center items-center`}
- onclick={async () => {
- await handle_enter_location();
- }}
- >
- <p
- class={`font-sans font-[600] text-[18px] text-layer-0-glyph-hl`}
- >
- {`${$ls(`common.enter_location`)}`}
- </p>
- <Glyph
- basis={{
- classes: `text-layer-0-glyph-hl`,
- dim: `md`,
- key: `caret-right`,
- }}
- />
- </button>
- {/if}-->
- {/snippet}
- </PageToolbar>
- <Carousel>
- <FarmsAddCasliMap
- bind:map_geop
- bind:map_geoc
- {farm_geop_lat}
- {farm_geop_lng}
- />
- <FarmsAddCasliDetail
- bind:val_farmname
- bind:val_farmaddress
- bind:val_farmcontact
- bind:val_farmarea
- bind:val_farmarea_unit
- {farm_geop_lat}
- {farm_geop_lng}
- />
- </Carousel>
-</LayoutView>
-{#if $app_platform?.browser !== `safari`}
- <LayoutBottomButton>
- <ButtonLayoutPair
- basis={{
- continue: {
- label: `${$ls(`common.continue`)}`,
- disabled: disabled_submit,
- callback: handle_continue,
- },
- back: {
- label: `${$ls(`common.back`)}`,
- visible: $casl_i > 0,
- callback: handle_back,
- },
- }}
- />
- </LayoutBottomButton>
-{/if}
diff --git a/apps-lib/src/lib/view/farms-details.svelte b/apps-lib/src/lib/view/farms-details.svelte
@@ -1,268 +0,0 @@
-<script lang="ts">
- import {
- ButtonSimple,
- Empty,
- get_context,
- Glyph,
- handle_err,
- LayoutPage,
- LayoutView,
- Map,
- MapMarkerArea,
- PageToolbar,
- type CallbackRoute,
- type IViewFarmsDetailsData,
- } from "$root";
- import {
- fmt_geolocation_address,
- geol_lat_fmt,
- geol_lng_fmt,
- parse_geol_point_tup,
- parse_tup_geop_point,
- type CallbackPromiseGeneric,
- type GeolocationPointTuple,
- type IViewBasis,
- } from "@radroots/util";
- import { onDestroy, onMount } from "svelte";
-
- const { ls, locale } = get_context(`lib`);
-
- let {
- basis,
- }: {
- basis: IViewBasis<{
- data: IViewFarmsDetailsData;
- callback_route?: CallbackRoute<string>;
- on_handle_farm_lot_add: CallbackPromiseGeneric<string>;
- on_handle_farm_products_view: CallbackPromiseGeneric<string>;
- on_handle_farm_orders_view: CallbackPromiseGeneric<string>;
- }>;
- } = $props();
-
- let map: maplibregl.Map | undefined = $state(undefined);
- let map_center: GeolocationPointTuple = $state([0, 0]);
-
- onMount(async () => {
- try {
- if (basis.on_mount) await basis.on_mount();
- if (basis.data?.location)
- map_center = parse_geol_point_tup(basis.data?.location.point);
- if (map) {
- map.setCenter(map_center);
- map.setZoom(11);
- }
- } catch (e) {
- handle_err(e, `on_mount`);
- }
- });
-
- onDestroy(async () => {
- try {
- if (basis.on_destroy) await basis.on_destroy();
- } catch (e) {
- handle_err(e, `on_destroy`);
- }
- });
-
- const map_geop = $derived(parse_tup_geop_point(map_center));
-
- const farm_addr_fmt = $derived(
- basis.data?.location?.address
- ? fmt_geolocation_address(basis.data?.location.address)
- : ``,
- );
-
- const farm_geop_lat = $derived(
- basis.data?.location?.point
- ? geol_lat_fmt(basis.data?.location.point.lat, `dms`, $locale, 3)
- : ``,
- );
-
- const farm_geop_lng = $derived(
- basis.data?.location?.point
- ? geol_lng_fmt(basis.data?.location.point.lng, `dms`, $locale, 3)
- : ``,
- );
-</script>
-
-<LayoutView>
- <PageToolbar
- basis={{
- header: {
- label: `${$ls(`common.farms`)}${basis.data?.farm.name ? ` / ${basis.data?.farm.name}` : ``}`,
- callback_route: basis.callback_route,
- },
- }}
- />
- <LayoutPage>
- <div
- class={`flex flex-row h-[12rem] w-full justify-start items-center`}
- >
- <div
- class={`flex flex-col basis-1/2 h-full p-4 gap-2 justify-start items-center`}
- >
- <div class={`flex flex-col w-full justify-start items-center`}>
- <div
- class={`flex flex-row w-full justify-start items-center`}
- >
- <p
- class={`font-sans font-[500] text-lg text-layer-0-glyph`}
- >
- {farm_addr_fmt}
- </p>
- </div>
- <div
- class={`flex flex-row w-full justify-start items-center`}
- >
- <p
- class={`font-sans font-[500] text-lg text-layer-0-glyph tracking-tight`}
- >
- {farm_geop_lat && farm_geop_lng
- ? `${farm_geop_lat}, ${farm_geop_lng}`
- : ``}
- </p>
- </div>
- </div>
- </div>
- <div
- class={`flex flex-col basis-1/2 h-full justify-start items-center`}
- >
- <div
- class={`flex flex-col h-full w-full p-4 gap-4 justify-start items-center bg-layer-1-surface rounded-2xl`}
- >
- <p
- class={`font-sans font-[500] text-sm text-layer-0-glyph`}
- >
- {`Farm Info`}
- </p>
- <div
- class={`flex flex-col w-full gap-1 justify-start items-center`}
- >
- <div
- class={`flex flex-row w-full gap-4 justify-between items-center`}
- >
- <p
- class={`font-sans font-[400] text-layer-0-glyph`}
- >
- {`Farm Size:`}
- </p>
-
- {#if basis.data?.farm.area && basis.data?.farm.area_unit}
- <p
- class={`font-sans font-[400] text-layer-0-glyph`}
- >
- {`${basis.data?.farm.area} ${basis.data?.farm.area_unit}`}
- </p>
- {:else}
- <div
- class={`flex flex-row gap-line justify-start items-center`}
- >
- <p
- class={`font-sans font-[400] text-layer-0-glyph_pl`}
- >
- {`Add`}
- </p>
- <Glyph
- basis={{
- classes: `text-layer-0-glyph_pl`,
- dim: `xs`,
- key: `caret-right`,
- }}
- />
- </div>
- {/if}
- </div>
- <div
- class={`flex flex-row w-full gap-4 justify-between items-center`}
- >
- <p
- class={`font-sans font-[400] text-layer-0-glyph`}
- >
- {`Farm Lots:`}
- </p>
- <p
- class={`font-sans font-[400] text-layer-0-glyph`}
- >
- {`${basis.data?.lots?.length || 0}`}
- </p>
- </div>
- <div
- class={`flex flex-row w-full gap-4 justify-between items-center`}
- >
- <p
- class={`font-sans font-[400] text-layer-0-glyph`}
- >
- {`Products:`}
- </p>
- <p
- class={`font-sans font-[400] text-layer-0-glyph`}
- >
- {`${0}`}
- </p>
- </div>
- <div
- class={`flex flex-row w-full gap-4 justify-between items-center`}
- >
- <p
- class={`font-sans font-[400] text-layer-0-glyph`}
- >
- {`Orders:`}
- </p>
- <p
- class={`font-sans font-[400] text-layer-0-glyph`}
- >
- {`${0}`}
- </p>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div class={`flex flex-col w-full gap-3 justify-center items-center`}>
- <ButtonSimple
- basis={{
- label: `View Products`,
- callback: async () => {
- if (basis.data?.farm.id)
- await basis.on_handle_farm_products_view(
- basis.data?.farm.id,
- );
- },
- }}
- />
- <ButtonSimple
- basis={{
- label: `View Orders`,
- callback: async () => {
- if (basis.data?.farm.id)
- await basis.on_handle_farm_orders_view(
- basis.data?.farm.id,
- );
- },
- }}
- />
- </div>
- <div
- class={`flex flex-col flex-shrink-0 h-[16rem] w-full justify-center items-center rounded-2xl overflow-hidden`}
- >
- <Map
- bind:map
- basis={{
- interactive: false,
- }}
- >
- <MapMarkerArea
- {map_geop}
- basis={{
- no_drag: true,
- }}
- />
- </Map>
- </div>
- <div
- class={`flex flex-col h-[12rem] w-full justify-center items-center`}
- >
- <Empty />
- </div>
- </LayoutPage>
-</LayoutView>
diff --git a/apps-lib/src/lib/view/farms-products-add.svelte b/apps-lib/src/lib/view/farms-products-add.svelte
@@ -1,669 +0,0 @@
-<script lang="ts">
- import {
- app_lo,
- ButtonLayoutPair,
- Carousel,
- CarouselItem,
- casl_dec,
- casl_i,
- casl_imax,
- casl_inc,
- casl_init,
- FarmsProductsReviewCard,
- fmt_id,
- FormEntryPrice,
- FormEntryQuantity,
- FormEntrySelect,
- FormEntrySelectInput,
- FormEntryTextarea,
- get_context,
- handle_err,
- idb,
- ImageUploadSimple,
- LayoutBottomButton,
- LayoutView,
- loc_fmt_geo_point_coords,
- MapLocationSelectEnvelope,
- MarkerIndexedView,
- PageToolbar,
- schema_view_farms_products_add_submission,
- type CallbackRoute,
- type ISelectOption,
- type IViewFarmsProductsAddData,
- type IViewFarmsProductsAddSubmitPayload,
- } from "$root";
- import {
- el_id,
- fmt_geocode_address,
- fmt_geolocation_address,
- form_fields,
- location_basis_to_geo_point,
- obj_keys_maxnum,
- parse_float,
- parse_geop_point,
- parse_int,
- parse_trade_key,
- sleep,
- str_trunc,
- trade,
- trade_keys,
- type CallbackPromiseFull,
- type CallbackPromiseGeneric,
- type GeocoderReverseResult,
- type GeolocationPoint,
- type IViewBasis,
- type LocationBasis,
- } from "@radroots/util";
- import { onMount } from "svelte";
-
- const { ls, locale, lc_geocode, lc_gui_alert, lc_geop_current } =
- get_context(`lib`);
-
- let {
- basis,
- }: {
- basis: IViewBasis<{
- data: IViewFarmsProductsAddData;
- callback_route?: CallbackRoute<string>;
- on_handle_farm_lot_add: CallbackPromiseGeneric<string>;
- on_handle_photo_envelope_edit: CallbackPromiseGeneric<number>;
- on_handle_tradepr_key_toggle: CallbackPromiseFull<boolean, string>;
- on_submit: CallbackPromiseGeneric<{
- payload: IViewFarmsProductsAddSubmitPayload;
- farm_id: string;
- geolocation_id?: string;
- }>;
- }>;
- } = $props();
-
- const casl_param: Record<
- "default",
- {
- index_map: Record<number, { label_desc: string }>;
- }
- > = {
- default: {
- index_map: {
- 0: {
- label_desc: `${$ls(`icu.add_*`, { value: `${$ls(`icu.*_information`, { value: `${$ls(`common.product`)}` })}` })}`,
- },
- 1: {
- label_desc: `${$ls(`icu.upload_*`, { value: `${$ls(`common.images`)}` })}`,
- },
- 2: {
- label_desc: `${$ls(`icu.*_price`, { value: `${$ls(`common.product`)}` })}`,
- },
- 3: {
- label_desc: `${$ls(`icu.add_*`, { value: `${$ls(`common.location`)}` })}`,
- },
- 4: {
- label_desc: `${$ls(`common.review`)}`,
- },
- },
- },
- };
-
- let choose_location_map_geop: GeolocationPoint | undefined =
- $state(undefined);
- let choose_location_map_geoc: GeocoderReverseResult | undefined =
- $state(undefined);
-
- let loading_submit = $state(false);
- let payload_submit: IViewFarmsProductsAddSubmitPayload | undefined =
- $state(undefined);
-
- let photo_paths = $state([]);
-
- let product_key_sel = $state(`cacao`);
- let product_key_sel_input = $state(``);
- let product_key_sel_toggle = $state(false);
-
- let product_process_sel = $state(`raw`);
- let product_process_sel_input = $state(``);
- let product_process_sel_toggle = $state(false);
-
- let product_description_input = $state(`Cool Description`);
-
- let product_location_sel = $state(``);
- let product_location_map_toggle = $state(false);
- let product_location_sel_geoc: GeocoderReverseResult | undefined =
- $state(undefined);
-
- let product_price_cur_sel = $state(`usd`);
- let product_price_input = $state(`4.50`);
- let product_price_qty_unit_sel = $state(`lb`);
-
- let product_quantity_input = $state(`60`);
- let product_quantity_unit_sel = $state(`kg`);
- let product_quantity_label_sel = $state(`bag`);
-
- const tradepr_key_parsed = $derived(parse_trade_key(product_key_sel));
-
- const product_process_list = $derived(
- tradepr_key_parsed ? trade.key[tradepr_key_parsed].process : [],
- );
-
- const list_farm_geolocations: LocationBasis[] = $derived(
- [
- basis.data?.location ? basis.data?.location : undefined,
- ...(basis.data?.lots?.length
- ? [...basis.data?.lots.map((i) => i.location)]
- : []),
- ].filter((i) => typeof i !== `undefined`),
- );
-
- const find_location_by_id = (id: string): LocationBasis | undefined => {
- return list_farm_geolocations.find((i) => i.id === id) || undefined;
- };
-
- const product_geolocation_id: string | undefined = $derived(
- product_location_sel === `*map-current`
- ? undefined
- : find_location_by_id(product_location_sel)?.id,
- );
-
- const product_location: LocationBasis | undefined = $derived(
- product_location_sel
- ? find_location_by_id(product_location_sel)
- : undefined,
- );
-
- $effect(() => {
- console.log(`choose_location_map_geoc `, choose_location_map_geoc);
- });
-
- $effect(() => {
- console.log(`product_location_sel_geoc `, product_location_sel_geoc);
- });
-
- const product_geolocation_point: GeolocationPoint | undefined = $derived(
- product_location_sel === `*map-current`
- ? choose_location_map_geop
- : location_basis_to_geo_point(product_location) || undefined,
- );
-
- const product_geocode_reverse: GeocoderReverseResult | undefined = $derived(
- product_location_sel === `*map-current`
- ? choose_location_map_geoc
- : product_location_sel_geoc,
- );
-
- const entries_farm_location: ISelectOption<string>[] = $derived(
- basis.data?.location
- ? [
- {
- value: basis.data.location.id,
- label: basis.data.location.address
- ? fmt_geolocation_address(basis.data.location.address)
- : basis.data.location.point
- ? loc_fmt_geo_point_coords(
- $locale,
- basis.data.location.point,
- )
- : ``,
- },
- ]
- : [],
- );
- const entries_farm_lots_locations: ISelectOption<string>[] = $derived(
- basis.data?.lots?.length
- ? basis.data.lots
- .filter(
- (i) =>
- i.location &&
- i.location?.address &&
- !entries_farm_location
- .map((i) => i.value)
- .includes(i.location.id),
- )
- .map(({ location }) =>
- location && location.address
- ? {
- value: location.id,
- label: `${location.address.primary}, ${location.address.admin}, ${location.address.country}`,
- }
- : undefined,
- )
- .filter((i) => typeof i !== `undefined`)
- : [],
- );
-
- $effect(() => {
- if (product_key_sel === ``) product_process_sel = ``;
- });
-
- onMount(async () => {
- try {
- casl_init(0, obj_keys_maxnum(casl_param.default.index_map));
- } catch (e) {
- handle_err(e, `on_mount`);
- }
- });
-
- const handle_sel_key = async (value: string): Promise<void> => {
- if (value in trade.key) product_process_sel = ``;
- el_id(fmt_id(`key_wrap`))?.classList.remove(`layer-1-ring-apply`);
- if (value === `*other`) {
- await handle_tradepr_key_toggle(true);
- product_process_sel = ``;
- }
- };
-
- const handle_tradepr_key_toggle = async (
- input_visible: boolean,
- ): Promise<void> => {
- product_key_sel_toggle = input_visible;
- if (input_visible) {
- product_key_sel_input = ``;
- } else {
- product_key_sel = ``;
- product_key_sel_input = ``;
- }
- };
-
- const handle_sel_process = async (value: string): Promise<void> => {
- el_id(fmt_id(`process_wrap`))?.classList.remove(`layer-1-ring-apply`);
- if (value === `*other`) handle_product_process_toggle(true);
- else if (value === `*choose-product`) {
- product_process_sel = ``;
- el_id(fmt_id(`key_wrap`))?.classList.add(`layer-1-ring-apply`);
- await sleep(1000);
- el_id(fmt_id(`key_wrap`))?.classList.remove(`layer-1-ring-apply`);
- }
- };
-
- const handle_product_process_toggle = async (
- input_visible: boolean,
- ): Promise<void> => {
- product_process_sel_toggle = input_visible;
- if (input_visible) {
- product_process_sel = ``;
- product_process_sel_input = ``;
- }
- };
-
- const handle_product_location_sel = async (
- value: string,
- ): Promise<void> => {
- console.log(`value `, value);
- el_id(fmt_id(`location_wrap`))?.classList.remove(`layer-1-ring-apply`);
- if (value === `*map`) {
- product_location_sel_geoc = undefined;
- if (choose_location_map_geop) choose_location_map_geop = undefined;
- if (choose_location_map_geoc) choose_location_map_geoc = undefined;
- const geop = await lc_geop_current();
- if (!geop) {
- return void (await lc_gui_alert(
- `${$ls(`icu.failure_reading_*`, { value: `${$ls(`common.location`)}`.toLowerCase() })}`,
- ));
- }
- const geoc = await lc_geocode(geop);
- if (!geoc) return; //@todo
- choose_location_map_geoc = geoc;
- choose_location_map_geop = parse_geop_point(geop);
- product_location_map_toggle = true;
- await sleep(1000);
- product_location_sel = ``;
- } else if (value) {
- const value_product_location = find_location_by_id(value);
- if (!value_product_location) return; //@todo
- const geoc = await lc_geocode(value_product_location.point);
- if (geoc) product_location_sel_geoc = geoc;
- }
- };
-
- const continue_0 = async (): Promise<void> => {
- for (const kv_id of [`key`, `process`, `description`]) {
- const val = await idb.get(fmt_id(kv_id));
- if (!val)
- return void (await lc_gui_alert(
- `${$ls(`farm.product.validation.${kv_id}.required`)}`,
- ));
- }
- await casl_inc();
- };
-
- const continue_1 = async (): Promise<void> => {
- if (!photo_paths.length)
- return void (await lc_gui_alert(
- `Upload a product photo`, //@todo
- ));
- await casl_inc();
- };
-
- const continue_2 = async (): Promise<void> => {
- await casl_inc();
- };
-
- const continue_3 = async (): Promise<void> => {
- if (!product_geolocation_point || !product_geocode_reverse)
- return void (await lc_gui_alert(`Product location not provided`));
- const vp_payload_submit =
- schema_view_farms_products_add_submission.safeParse({
- product: product_key_sel_input || product_key_sel,
- process: product_process_sel_input || product_process_sel,
- description: product_description_input,
- price_amount: parse_float(product_price_input, 1.0),
- price_currency: product_price_cur_sel,
- price_quantity_unit: product_price_qty_unit_sel,
- quantity_amount: parse_int(product_quantity_input, 1),
- quantity_unit: product_quantity_unit_sel,
- quantity_label: product_quantity_label_sel,
- photos: photo_paths,
- geolocation_point: product_geolocation_point,
- geocode_result: product_geocode_reverse,
- } satisfies IViewFarmsProductsAddSubmitPayload);
- if (!vp_payload_submit.success)
- return void (await lc_gui_alert(
- `Errors: ${vp_payload_submit.error}`,
- ));
- payload_submit = vp_payload_submit.data;
- await casl_inc();
- };
-
- const continue_4 = async (): Promise<void> => {
- if (!payload_submit)
- return void (await lc_gui_alert(`${$ls(`error.default.failure`)}`));
- loading_submit = true;
- try {
- await basis.on_submit({
- payload: payload_submit,
- farm_id: basis.data.farm.id,
- geolocation_id: product_geolocation_id,
- });
- } catch {
- } finally {
- loading_submit = false;
- }
- };
-
- const handle_continue = async (): Promise<void> => {
- try {
- switch ($casl_i) {
- case 0:
- return await continue_0();
- case 1:
- return await continue_1();
- case 2:
- return await continue_2();
- case 3:
- return await continue_3();
- case 4:
- return await continue_4();
- }
- } catch (e) {
- await handle_err(e, `handle_continue`);
- }
- };
-
- const handle_back = async (): Promise<void> => {
- try {
- switch ($casl_i) {
- default:
- return await casl_dec();
- }
- } catch (e) {
- await handle_err(e, `handle_back`);
- }
- };
-</script>
-
-<LayoutView basis={{ classes: `` }}>
- <PageToolbar
- basis={{
- header: {
- label: `${`${$ls(`common.farm`)}`} / ${`${$ls(`common.product`)}`}`,
- callback_route: basis.callback_route || { route: `/farms` },
- },
- }}
- />
- <LayoutBottomButton>
- <ButtonLayoutPair
- basis={{
- continue: {
- label:
- $casl_i === $casl_imax
- ? `${$ls(`common.post`)}`
- : `${$ls(`common.continue`)}`,
- disabled: false,
- loading: loading_submit,
- callback: handle_continue,
- },
- back: {
- label: `${$ls(`common.back`)}`,
- visible: $casl_i > 0,
- callback: handle_back,
- },
- }}
- />
- </LayoutBottomButton>
- <div
- class={`flex flex-col w-lo_line_entry_${$app_lo} pt-4 pb-6 px-1 gap-4 justify-center items-center`}
- >
- <div class={`flex flex-row h-2 w-full justify-start items-center`}>
- <p
- class={`font-sans font-[500] text-sm text-layer-0-glyph/60 capitalize`}
- >
- {casl_param.default.index_map[$casl_i]?.label_desc}
- </p>
- </div>
- <MarkerIndexedView
- basis={{
- index_max: $casl_imax + 1,
- index_curr: $casl_i,
- callback_index: async (index) => {
- casl_i.set(index);
- },
- }}
- />
- </div>
- <Carousel>
- <CarouselItem basis={{ classes: `gap-4` }}>
- <FormEntrySelectInput
- bind:val_sel={product_key_sel}
- bind:val_sel_input={product_key_sel_input}
- basis={{
- id: `key`,
- entry_label: `${$ls(`common.product`)}`,
- visible_input: product_key_sel_toggle,
- input_placeholder: `${$ls(`icu.enter_the_*`, { value: `${$ls(`icu.*_name`, { value: `${$ls(`common.product`)}` })}`.toLowerCase() })}`,
- input_field: form_fields.product_key,
- callback_visible: handle_tradepr_key_toggle,
- callback_select: async ({ value }) => {
- await handle_sel_key(value);
- },
- select_entries: [
- {
- value: ``,
- label: `${$ls(`icu.choose_*`, { value: `${$ls(`common.product`)}`.toLowerCase() })}`,
- disabled: true,
- },
- ...trade_keys.map((i) => ({
- value: i,
- label: `${$ls(`products.key.${i}.name`)}`,
- })),
- {
- value: `*other`,
- label:
- product_key_sel === `*other`
- ? ``
- : `${$ls(`common.other`)}`,
- },
- ],
- }}
- />
- <FormEntrySelectInput
- bind:val_sel={product_process_sel}
- bind:val_sel_input={product_process_sel_input}
- basis={{
- id: `process`,
- entry_label: `${$ls(`common.process`)}`,
- visible_input: product_process_sel_toggle,
- input_placeholder: `${$ls(`icu.enter_the_*`, { value: `${$ls(`common.process`)}`.toLowerCase() })}`,
- input_field: form_fields.product_process,
- callback_visible: handle_product_process_toggle,
- callback_select: async ({ value }) =>
- await handle_sel_process(value),
- select_entries: product_process_list.length
- ? [
- {
- value: ``,
- label: `${$ls(`icu.choose_*`, { value: `${$ls(`common.process`)}`.toLowerCase() })}`,
- disabled: true,
- },
- ...product_process_list.map((i) => ({
- value: i,
- label: `${$ls(`products.key.${tradepr_key_parsed}.process.${i}`)}`,
- })),
- {
- value: `*other`,
- label:
- product_key_sel === `*other`
- ? ``
- : `${$ls(`common.other`)}`,
- },
- ]
- : [
- {
- value: ``,
- label: `${$ls(`icu.choose_*`, { value: `${$ls(`common.process`)}`.toLowerCase() })}`,
- disabled: true,
- },
- {
- value: `*choose-product`,
- label: `${$ls(`icu.choose_*`, { value: `${$ls(`common.product`)}`.toLowerCase() })}`,
- },
- ]
- .concat(
- product_key_sel === `*other`
- ? [
- ...trade.default.process.map(
- (i) => ({
- value: i,
- label: `${$ls(`products.default.process.${i}`)}`,
- }),
- ),
- {
- value: `*other`,
- label: `${$ls(`common.other`)}`,
- },
- ]
- : [],
- )
- .filter((i) =>
- product_key_sel
- ? i.value !== `*choose-product`
- : true,
- ),
- }}
- />
- <FormEntryTextarea
- bind:val={product_description_input}
- basis={{
- id: `description`,
- entry_label: `${$ls(`common.description`)}`,
- field: form_fields.product_description,
- placeholder: `${$ls(`common.describe_your_product`)}`,
- }}
- />
- </CarouselItem>
- <CarouselItem basis={{ classes: `px-4` }}>
- <ImageUploadSimple bind:photo_paths />
- </CarouselItem>
- <CarouselItem basis={{ classes: `gap-4` }}>
- <FormEntryPrice
- bind:val_input_price={product_price_input}
- bind:val_sel_currency={product_price_cur_sel}
- bind:val_sel_quantity_unit={product_price_qty_unit_sel}
- basis={{
- id: `price`,
- entry_label: `price`,
- input_placeholder: `${$ls(`icu.enter_*`, { value: `${$ls(`common.price`)}` })}`,
- }}
- />
- <FormEntryQuantity
- bind:val_input_quantity={product_quantity_input}
- bind:val_sel_quantity_unit={product_quantity_unit_sel}
- bind:val_sel_quantity_label={product_quantity_label_sel}
- basis={{
- id: `quantity`,
- entry_label: `quantity`,
- input_placeholder: `${$ls(`icu.enter_*`, { value: `${$ls(`common.quantity`)}` })}`,
- }}
- />
- </CarouselItem>
- <CarouselItem>
- <FormEntrySelect
- bind:val={product_location_sel}
- basis={{
- id: `location`,
- entry_label: `${$ls(`common.location`)}`,
- callback: async ({ value }) =>
- await handle_product_location_sel(value),
- entries: choose_location_map_geoc
- ? [
- {
- value: ``,
- label: `${$ls(`icu.choose_*`, { value: `${$ls(`common.location`)}`.toLowerCase() })}`,
- disabled: true,
- },
- {
- value: `*map`,
- label: `${$ls(`common.choose_on_map`)}`,
- },
- {
- value: `*map-current`,
- label: `${str_trunc(fmt_geocode_address(choose_location_map_geoc))} (map)`,
- },
- ...entries_farm_location,
- ...entries_farm_lots_locations,
- ]
- : [
- {
- value: ``,
- label: `${$ls(`icu.choose_*`, { value: `${$ls(`common.location`)}`.toLowerCase() })}`,
- disabled: true,
- },
- ...entries_farm_location,
- ...entries_farm_lots_locations,
- {
- value: `*map`,
- label: `${$ls(`common.choose_on_map`)}`,
- },
- ],
- }}
- />
- </CarouselItem>
- <CarouselItem>
- <div class={`flex flex-col w-full justify-center items-center`}>
- <FarmsProductsReviewCard
- basis={{
- data: payload_submit,
- }}
- />
- </div>
- </CarouselItem>
- </Carousel>
-</LayoutView>
-<MapLocationSelectEnvelope
- bind:map_geop={choose_location_map_geop}
- bind:map_geoc={choose_location_map_geoc}
- basis={{
- visible: product_location_map_toggle,
- on_submit: async (params) => {
- try {
- if (!params) {
- choose_location_map_geoc = undefined;
- return;
- }
- const { map_geoc, map_geop } = params;
- if (map_geoc && map_geop) product_location_sel = `*map-current`;
- else product_location_sel = ``;
- } catch (e) {
- await handle_err(e, `on_submit`);
- } finally {
- product_location_map_toggle = false;
- }
- },
- }}
-/>
diff --git a/apps-lib/src/lib/view/farms.svelte b/apps-lib/src/lib/view/farms.svelte
@@ -1,90 +0,0 @@
-<script lang="ts">
- import {
- ButtonLabelDashed,
- Fade,
- FarmsDisplayLiEl,
- get_context,
- GlyphButtonSimple,
- handle_err,
- idb_init_page,
- LayoutPage,
- LayoutView,
- PageToolbar,
- type CallbackRoute,
- type IViewFarmsData,
- } from "$root";
- import {
- type CallbackPromise,
- type CallbackPromiseGeneric,
- type IViewBasis,
- } from "@radroots/util";
- import { onMount } from "svelte";
-
- const { ls } = get_context(`lib`);
-
- let {
- basis,
- }: {
- basis: IViewBasis<{
- data?: IViewFarmsData;
- callback_route?: CallbackRoute<string>;
- on_handle_farm_add: CallbackPromise;
- on_handle_farm_view: CallbackPromiseGeneric<string>;
- }>;
- } = $props();
-
- onMount(async () => {
- try {
- if (!basis.kv_init_prevent) await idb_init_page();
- } catch (e) {
- handle_err(e, `on_mount`);
- }
- });
-</script>
-
-<LayoutView>
- <PageToolbar
- basis={{
- header: {
- label: `${$ls(`common.farms`)}`,
- callback_route: basis.callback_route,
- },
- }}
- >
- {#snippet header_option()}
- {#if basis.data?.list.length}
- <Fade>
- <GlyphButtonSimple
- basis={{
- label: `${$ls(`icu.add_*`, { value: `${$ls(`common.farm`)}` })}`,
- callback: async () => {
- await basis.on_handle_farm_add();
- },
- }}
- />
- </Fade>
- {/if}
- {/snippet}
- </PageToolbar>
- <LayoutPage>
- {#if basis.data}
- {#if basis.data?.list.length}
- {#each basis.data?.list || [] as li}
- <FarmsDisplayLiEl
- basis={li}
- on_handle_farm_view={basis.on_handle_farm_view}
- />
- {/each}
- {:else}
- <ButtonLabelDashed
- basis={{
- label: `Add farm`,
- callback: async () => {
- await basis.on_handle_farm_add();
- },
- }}
- />
- {/if}
- {/if}
- </LayoutPage>
-</LayoutView>
diff --git a/apps-lib/src/lib/view/home.svelte b/apps-lib/src/lib/view/home.svelte
@@ -1,59 +0,0 @@
-<script lang="ts">
- import {
- ButtonSimple,
- get_context,
- handle_err,
- idb_init_page,
- LayoutPage,
- LayoutView,
- NavigationTabs,
- PageToolbar,
- type IViewHomeData,
- } from "$root";
- import { type CallbackPromise, type IViewBasis } from "@radroots/util";
- import { onMount } from "svelte";
-
- const { ls } = get_context(`lib`);
-
- let {
- basis,
- }: {
- basis: IViewBasis<{
- data?: IViewHomeData;
- on_handle_farms: CallbackPromise;
- on_handle_products: CallbackPromise;
- }>;
- } = $props();
-
- onMount(async () => {
- try {
- if (!basis.kv_init_prevent) await idb_init_page();
- } catch (e) {
- handle_err(e, `on_mount`);
- }
- });
-</script>
-
-{#if basis.data}
- {@const { data: basis_data } = basis}
- <LayoutView>
- <PageToolbar
- basis={{
- header: {
- label: `${$ls(`common.general`)}`,
- },
- }}
- />
- <LayoutPage>
- <ButtonSimple
- basis={{
- label: `${$ls(`common.farms`)}`,
- callback: async () => {
- await basis.on_handle_farms();
- },
- }}
- />
- </LayoutPage>
- </LayoutView>
- <NavigationTabs />
-{/if}
diff --git a/apps-lib/src/lib/view/notifications.svelte b/apps-lib/src/lib/view/notifications.svelte
@@ -1,34 +0,0 @@
-<script lang="ts">
- import { LayoutView, NavigationTabs, PageToolbar } from "$root";
- import type { I18nTranslateFunction } from "@radroots/util";
-
- let notifications: any[] = [];
-
- let { basis, ls }: { basis: {}; ls: I18nTranslateFunction } = $props();
-</script>
-
-<LayoutView>
- <PageToolbar
- basis={{
- header: {
- label: `${$ls(`common.notifications`)} (${notifications.length})`,
- },
- }}
- />
- <div class={`flex flex-col w-full px-4 gap-6 justify-center items-center`}>
- {#if notifications.length}
- {#each notifications as li}
- <div class={`flex flex-row w-full justify-center items-center`}>
- {li}
- </div>
- {/each}
- {:else}
- <div class={`flex flex-row w-full justify-center items-center`}>
- <p class={`font-sans font-[500] text-layer-0-glyph capitalize`}>
- {`${$ls(`icu.no_*`, { value: `${$ls(`common.notifications`)}` })}`}
- </p>
- </div>
- {/if}
- </div>
-</LayoutView>
-<NavigationTabs />
diff --git a/apps-lib/src/lib/view/profile-edit.svelte b/apps-lib/src/lib/view/profile-edit.svelte
@@ -1,105 +0,0 @@
-<script lang="ts">
- import ButtonRoundNav from "$lib/components/button/button-round-nav.svelte";
- import FloatPage from "$lib/components/float/float-page.svelte";
- import Empty from "$lib/components/lib/empty.svelte";
- import {
- fmt_id,
- get_context,
- handle_err,
- idb_init_page,
- Input,
- LayoutPage,
- LayoutView,
- NavigationTabs,
- type IViewProfileEditData,
- type ViewProfileEditFieldKey,
- } from "$root";
- import {
- type CallbackPromiseGeneric,
- type ElementCallbackValue,
- type IViewBasis,
- } from "@radroots/util";
- import { onMount } from "svelte";
-
- const { ls } = get_context(`lib`);
-
- let {
- basis,
- val_field = $bindable(``),
- }: {
- basis: IViewBasis<{
- data?: IViewProfileEditData;
- on_handle_back: CallbackPromiseGeneric<{
- field: ViewProfileEditFieldKey;
- public_key: string;
- }>;
- on_handle_input: ElementCallbackValue;
- }>;
- val_field: string;
- } = $props();
-
- const param: Record<ViewProfileEditFieldKey, { placeholder: string }> = {
- name: {
- placeholder: `${$ls(`icu.enter_*`, { value: `profile username` })}`, //@todo
- },
- display_name: {
- placeholder: `${$ls(`icu.enter_*`, { value: `profile display name` })}`, //@todo
- },
- about: {
- placeholder: `${$ls(`icu.enter_*`, { value: `profile bio` })}`, //@todo
- },
- };
-
- onMount(async () => {
- try {
- if (!basis.kv_init_prevent) await idb_init_page();
- } catch (e) {
- handle_err(e, `on_mount`);
- }
- });
-
- const input_placeholder = $derived(
- basis.data?.field ? param[basis.data.field]?.placeholder : ``,
- );
-</script>
-
-{#if basis.data}
- {@const { data: basis_data } = basis}
- <LayoutView>
- <LayoutPage>
- <div class={`flex flex-row h-20 w-full justify-start items-center`}>
- <Empty />
- </div>
- {#if basis.data.field}
- <Input
- bind:value={val_field}
- basis={{
- id: fmt_id(`field`),
- sync: true,
- classes: `pl-6 h-entry_line text-layer-1-glyph bg-layer-1-surface rounded-2xl`,
- placeholder: input_placeholder,
- callback: basis.on_handle_input,
- }}
- />
- {/if}
- </LayoutPage>
- </LayoutView>
- <FloatPage
- basis={{
- posx: `left`,
- }}
- >
- <ButtonRoundNav
- basis={{
- glyph: `arrow-left`,
- callback: async () => {
- await basis.on_handle_back({
- field: basis_data.field,
- public_key: basis_data.public_key,
- });
- },
- }}
- />
- </FloatPage>
- <NavigationTabs />
-{/if}
diff --git a/apps-lib/src/lib/view/profile.svelte b/apps-lib/src/lib/view/profile.svelte
@@ -1,306 +0,0 @@
-<script lang="ts">
- import {
- ButtonRoundNav,
- FloatPage,
- get_context,
- Glyph,
- handle_err,
- idb_init_page,
- ImagePath,
- ImageUploadAddPhoto,
- NavigationTabs,
- SelectMenu,
- type IViewOnDestroy,
- type IViewProfileData,
- type ViewProfileEditFieldKey,
- } from "$root";
- import {
- symbols,
- type CallbackPromise,
- type CallbackPromiseGeneric,
- type IViewBasis,
- } from "@radroots/util";
- import { onDestroy, onMount } from "svelte";
-
- const { ls } = get_context(`lib`);
-
- let {
- basis,
- photo_path = $bindable(``),
- }: {
- basis: IViewBasis<{
- data?: IViewProfileData;
- loading_photo_upload: boolean;
- loading_photo_upload_open: boolean;
- on_handle_back: CallbackPromiseGeneric<{
- is_photo_existing: boolean;
- }>;
- on_handle_photo_options: CallbackPromise;
- on_handle_edit_profile_field: CallbackPromiseGeneric<{
- field: ViewProfileEditFieldKey;
- }>;
- }> &
- IViewOnDestroy<{ public_key: string }>;
- photo_path: string;
- } = $props();
-
- type ViewDisplay = `photos` | `following` | `followers`;
- let view_display: ViewDisplay = $state(`photos`);
-
- let val_sel_options_button = $state(``);
-
- onMount(async () => {
- try {
- if (!basis.kv_init_prevent) await idb_init_page();
- } catch (e) {
- handle_err(e, `on_mount`);
- }
- });
-
- onDestroy(async () => {
- try {
- if (basis.data?.public_key)
- await basis.on_destroy({
- public_key: basis.data.public_key,
- });
- } catch (e) {
- handle_err(e, `on_destroy`);
- }
- });
-
- const photo_overlay_visible = $derived(
- !!(basis.data?.picture || photo_path),
- );
-
- const classes_photo_overlay_glyph = $derived(
- photo_overlay_visible ? `text-white` : `text-layer-0-glyph`,
- );
-
- const classes_photo_overlay_glyph_opt = $derived(
- photo_overlay_visible ? `text-gray-300` : `text-layer-0-glyph`,
- );
-
- const classes_photo_overlay_glyph_opt_selected = $derived(
- photo_overlay_visible ? `text-white` : `text-layer-1-glyph_d`,
- );
-</script>
-
-{#if basis.data}
- <div
- class={`relative flex flex-col min-h-[525px] h-[525px] w-full justify-center items-center bg-layer-2-surface fade-in`}
- >
- <FloatPage
- basis={{
- posx: `left`,
- }}
- >
- <ButtonRoundNav
- basis={{
- glyph: `arrow-left`,
- loading: basis.loading_photo_upload,
- callback: async () => {
- await basis.on_handle_back({
- is_photo_existing: photo_overlay_visible,
- });
- },
- }}
- />
- </FloatPage>
- <FloatPage
- basis={{
- posx: `right`,
- }}
- >
- <SelectMenu
- bind:value={val_sel_options_button}
- basis={{
- layer: 0,
- options: [
- {
- entries: [
- {
- value: `*add-new`,
- label: `Add new photo`,
- },
- ],
- },
- ],
- }}
- >
- <ButtonRoundNav
- basis={{
- glyph: `images-square`,
- callback: basis.on_handle_photo_options,
- }}
- />
- </SelectMenu>
- </FloatPage>
- {#if basis.data.picture || photo_path}
- {@const img_path = photo_path || basis.data.picture || ``}
- <ImagePath basis={{ path: img_path }} />
- {:else}
- <div
- class={`flex flex-row justify-start items-center -translate-y-8`}
- >
- <ImageUploadAddPhoto
- bind:photo_path
- basis={{
- loading: basis.loading_photo_upload_open,
- }}
- />
- </div>
- {/if}
- <div
- class={`absolute bottom-0 left-0 flex flex-col h-[calc(100%-100%/1.618)] w-full px-6 gap-2 justify-end items-center`}
- >
- <div
- class={`flex flex-col w-full gap-[2px] justify-center items-center`}
- >
- <div
- class={`flex flex-row h-10 w-full justify-start items-center`}
- >
- <button
- class={`group flex flex-row justify-center items-center`}
- onclick={async () => {
- await basis.on_handle_edit_profile_field({
- field: `display_name`,
- });
- }}
- >
- <p
- class={`font-sansd font-[600] text-[2rem] ${classes_photo_overlay_glyph} ${basis.data?.name ? `` : `capitalize opacity-active`} el-re`}
- >
- {#if basis.data?.display_name}
- {`${basis.data?.display_name}`}
- {:else if basis.data?.name}
- {`${basis.data?.display_name || basis.data?.name || ``}`}
- {:else}
- {`+ ${`${$ls(`icu.add_*`, { value: `${$ls(`common.profile_name`)}` })}`}`}
- {/if}
- </p>
- </button>
- </div>
- <div
- class={`flex flex-row w-full gap-[6px] justify-start items-center`}
- >
- <button
- class={`group flex flex-row justify-center items-center`}
- onclick={async () => {
- await basis.on_handle_edit_profile_field({
- field: `name`,
- });
- }}
- >
- <p
- class={`font-sansd font-[600] text-[1.1rem] ${classes_photo_overlay_glyph} ${basis.data?.name ? `` : `capitalize opacity-active`} el-re`}
- >
- {#if basis.data?.name}
- {`@${basis.data.name}`}
- {:else}
- {`+ ${`${$ls(`icu.add_*`, { value: `${$ls(`common.username`)}` })}`}`}
- {/if}
- </p>
- </button>
- <p
- class={`font-sans font-[400] ${classes_photo_overlay_glyph}`}
- >
- {symbols.bullet}
- </p>
- <button
- class={`flex flex-row justify-center items-center`}
- onclick={async () => {
- alert(`@todo!`);
- }}
- >
- <Glyph
- basis={{
- classes: `${classes_photo_overlay_glyph}`,
- dim: `xs`,
-
- key: `link-simple`,
- }}
- />
- </button>
- </div>
- <div class={`flex flex-row w-full justify-start items-center`}>
- <button
- class={`group flex flex-row justify-center items-center`}
- onclick={async () => {
- await basis.on_handle_edit_profile_field({
- field: `about`,
- });
- }}
- >
- <p
- class={`font-sansd font-[400] text-[1.1rem] ${classes_photo_overlay_glyph} ${basis.data?.about ? `` : `capitalize opacity-active`}`}
- >
- {#if basis.data?.about}
- {`${basis.data.about}`}
- {:else}
- {`+ ${`${$ls(`icu.add_*`, { value: `${$ls(`common.bio`)}` })}`}`}
- {/if}
- </p>
- </button>
- </div>
- </div>
- <div
- class={`flex flex-row w-full pt-2 pb-6 gap-2 justify-start items-center`}
- >
- <button
- class={`flex flex-row justify-center items-center`}
- onclick={async () => {
- view_display = `photos`;
- }}
- >
- <p
- class={`font-sans text-[1.1rem] font-[600] capitalize ${view_display === `photos` ? classes_photo_overlay_glyph_opt_selected : classes_photo_overlay_glyph_opt} el-re`}
- >
- {`${$ls(`common.photos`)}`}
- </p>
- </button>
- <button
- class={`flex flex-row justify-center items-center`}
- onclick={async () => {
- view_display = `following`;
- }}
- >
- <p
- class={`font-sans text-[1.1rem] font-[600] capitalize ${view_display === `following` ? classes_photo_overlay_glyph_opt_selected : classes_photo_overlay_glyph_opt} el-re`}
- >
- {`${$ls(`common.following`)}`}
- </p>
- </button>
- <button
- class={`flex flex-row justify-center items-center`}
- onclick={async () => {
- view_display = `followers`;
- }}
- >
- <p
- class={`font-sans text-[1.1rem] font-[600] capitalize ${view_display === `followers` ? classes_photo_overlay_glyph_opt_selected : classes_photo_overlay_glyph_opt} el-re`}
- >
- {`${$ls(`common.followers`)}`}
- </p>
- </button>
- </div>
- </div>
- </div>
- <div
- class={`flex flex-col w-full min-h-[500px] justify-start items-center`}
- >
- {#if view_display === `photos`}
- <p class={`font-sans font-[400] text-layer-0-glyph`}>
- {view_display}
- </p>
- {:else if view_display === `following`}
- <p class={`font-sans font-[400] text-layer-0-glyph`}>
- {view_display}
- </p>
- {:else if view_display === `followers`}
- <p class={`font-sans font-[400] text-layer-0-glyph`}>
- {view_display}
- </p>
- {/if}
- </div>
- <NavigationTabs />
-{/if}
diff --git a/apps-lib/src/lib/view/settings.svelte b/apps-lib/src/lib/view/settings.svelte
@@ -1,108 +0,0 @@
-<script lang="ts">
- import {
- app_thc,
- get_context,
- handle_err,
- idb_init_page,
- LayoutTrellis,
- LayoutView,
- PageToolbar,
- Trellis,
- type ITrellisKind,
- } from "$root";
- import { symbols, type IViewBasis } from "@radroots/util";
- import { onMount } from "svelte";
-
- const { ls, lc_color_mode } = get_context(`lib`);
-
- let {
- basis,
- }: {
- basis: IViewBasis<{
- trellis_2?: (ITrellisKind | undefined)[];
- }>;
- } = $props();
-
- onMount(async () => {
- try {
- if (!basis.kv_init_prevent) await idb_init_page();
- } catch (e) {
- handle_err(e, `on_mount`);
- }
- });
-</script>
-
-<LayoutView>
- <PageToolbar
- basis={{
- header: {
- label: `${$ls(`common.settings`)}`,
- },
- }}
- />
- <LayoutTrellis>
- <Trellis
- basis={{
- layer: 1,
- title: {
- value: `Appearance`,
- },
- list: [
- {
- hide_active: true,
- select: {
- label: {
- left: [
- {
- value: `${$ls(`common.color_mode`)}`,
- classes: `capitalize`,
- },
- ],
- },
- display: {
- label: {
- value: `${$app_thc}`,
- classes: `capitalize`,
- },
- },
- el: {
- value: $app_thc,
- options: [
- {
- entries: [
- {
- value: symbols.bullet,
- label: `${$ls(`icu.choose_*`, { value: `${$ls(`common.color_mode`)}`.toLowerCase() })}`,
- disabled: true,
- },
- {
- value: `light`,
- label: `${$ls(`common.light`)}`,
- },
- {
- value: `dark`,
- label: `${$ls(`common.dark`)}`,
- },
- ],
- },
- ],
- callback: lc_color_mode,
- },
- end: {
- glyph: {
- key: `caret-right`,
- },
- },
- },
- },
- ],
- }}
- />
- <Trellis
- basis={{
- layer: 1,
- list: basis.trellis_2,
- }}
- />
- </LayoutTrellis>
-</LayoutView>