commit b8234b9494aec681663632b4bc3b67bf4f939662
parent c0cd82be6c17d9493fb83adb40575209e860682d
Author: triesap <137732411+triesap@users.noreply.github.com>
Date: Fri, 27 Dec 2024 02:23:53 +0000
apps-lib: in-progress refactor
Diffstat:
99 files changed, 668 insertions(+), 4937 deletions(-)
diff --git a/apps-lib/.gitignore b/apps-lib/.gitignore
@@ -27,7 +27,8 @@ yarn-error.log*
# turbo
.turbo
-_tmp
+.dev*
+.tmp*
.vscode
notes*.txt
justfile
diff --git a/apps-lib/src/lib/components/badge_info_key.svelte b/apps-lib/src/lib/components/badge_info_key.svelte
@@ -1,18 +0,0 @@
-<script lang="ts">
- import { fmt_cl } from "$lib/utils/client";
-
- export let basis: {
- classes?: string;
- label: string;
- };
-</script>
-
-<div
- class={`${fmt_cl(basis.classes || `bg-layer-0-surface`)} flex flex-row h-6 px-2 justify-start items-center rounded-lg`}
->
- <p
- class={`font-mono font-[500] text-[1rem] tracking-tighter text-layer-0-glyph`}
- >
- {`${basis.label}`}
- </p>
-</div>
diff --git a/apps-lib/src/lib/components/button_arrow.svelte b/apps-lib/src/lib/components/button_arrow.svelte
@@ -1,58 +0,0 @@
-<script lang="ts">
- import { Glyph, type CallbackPromise } from "$lib";
- import { onDestroy, onMount } from "svelte";
-
- export let basis: {
- label: string;
- callback: CallbackPromise;
- };
-
- let visible_action = false;
-
- onMount(async () => {
- try {
- document.addEventListener("click", () => toggle(false));
- } catch (e) {
- } finally {
- }
- });
-
- onDestroy(() => {
- document.removeEventListener("click", () => toggle(false));
- });
-
- const toggle = (toggle_force?: boolean): void => {
- visible_action =
- typeof toggle_force === `boolean` ? toggle_force : !visible_action;
- };
-</script>
-
-<div class={`relative inline-block`}>
- <button
- class={`flex flex-row w-auto h-10 gap-1 justify-center items-center el-re`}
- on:click|stopPropagation={async () => {
- toggle();
- }}
- >
- <button
- class={`${visible_action ? `fade-in` : `hidden`} absolute top-0 left-0 flex flex-row h-full justify-start items-center el-re`}
- on:click|stopPropagation={async () => {
- await basis.callback();
- }}
- >
- <Glyph
- basis={{
- classes: `text-layer-0-glyph`,
- dim: `sm`,
- weight: `bold`,
- key: `arrow-left`,
- }}
- />
- </button>
- <p
- class={`font-circ font-[700] text-layer-0-glyph text-[1.6rem] tracking-tight ${visible_action ? `translate-x-8` : ``} duration-[350ms] el-re`}
- >
- {basis.label || ``}
- </p>
- </button>
-</div>
diff --git a/apps-lib/src/lib/components/button_glyph.svelte b/apps-lib/src/lib/components/button_glyph.svelte
@@ -1,21 +0,0 @@
-<script lang="ts">
- import { fmt_cl, glyph_style_map, type IGlyph } from "$lib";
-
- export let basis: IGlyph;
- $: basis = basis;
-
- $: weight =
- !basis?.weight || basis?.weight === `regular` ? `` : `-${basis.weight}`;
- $: styles = basis?.dim
- ? glyph_style_map.get(basis.dim)
- : glyph_style_map.get(`sm`);
-</script>
-
-<button
- class={`${fmt_cl(basis.classes)} flex flex-col justify-center items-center text-[${styles?.gl_1}px] el-re`}
- on:click={async () => {
- if (basis.callback) await basis.callback();
- }}
->
- <i class={`ph${weight} ph-${basis.key}`}></i>
-</button>
diff --git a/apps-lib/src/lib/components/button_glyph_simple.svelte b/apps-lib/src/lib/components/button_glyph_simple.svelte
@@ -1,25 +0,0 @@
-<script lang="ts">
- import type { CallbackPromise } from "$lib";
-
- export let basis: {
- kind?: `primary` | `neutral`;
- label: string;
- callback: CallbackPromise;
- };
-
- $: classes_kind =
- basis.kind === `neutral`
- ? `text-layer-0-glyph-shade`
- : `text-layer-0-glyph-hl`;
-</script>
-
-<button
- class={`group flex flex-row justify-center items-center`}
- on:click={async () => {
- await basis.callback();
- }}
->
- <p class={`font-sans font-[600] text-guide ${classes_kind} opacity-active`}>
- {basis.label}
- </p>
-</button>
diff --git a/apps-lib/src/lib/components/button_layout_pair.svelte b/apps-lib/src/lib/components/button_layout_pair.svelte
@@ -1,16 +1,15 @@
<script lang="ts">
import {
app_layout,
+ ButtonLayout,
Fill,
- ls,
type CallbackPromise,
type IDisabledOpt,
} from "$lib";
- import ButtonLayout from "./button_layout.svelte";
export let basis: {
continue: IDisabledOpt & {
- label?: string;
+ label: string;
callback: CallbackPromise;
};
back?: IDisabledOpt & {
@@ -25,13 +24,13 @@
<ButtonLayout
basis={{
disabled: basis.continue.disabled,
- label: basis.continue.label || `${$ls(`common.continue`)}`,
+ 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}
+ {#if basis.back.visible}
<button
class={`group flex flex-row h-12 w-${$app_layout} justify-center items-center fade-in`}
on:click|stopPropagation={async () => {
@@ -41,7 +40,7 @@
<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 || `${$ls(`common.back`)}`}
+ {basis.back.label}
</p>
</button>
{:else}
diff --git a/apps-lib/src/lib/components/button_loading.svelte b/apps-lib/src/lib/components/button_loading.svelte
@@ -1,24 +0,0 @@
-<script lang="ts">
- import { type CallbackPromise, fmt_cl, Loading, ls } from "$lib";
-
- export let basis: {
- classes?: string;
- callback: CallbackPromise;
- loading?: boolean;
- label?: string;
- };
- $: basis = basis;
-</script>
-
-<button
- class={`${fmt_cl(basis.classes)} button-submit`}
- on:click={async () => {
- await basis.callback();
- }}
->
- {#if basis.loading}
- <Loading basis={{ dim: `xs` }} />
- {:else}
- {basis.label || `${$ls(`common.submit`, { default: `submit` })}`}
- {/if}
-</button>
diff --git a/apps-lib/src/lib/components/button_opts_display.svelte b/apps-lib/src/lib/components/button_opts_display.svelte
@@ -1,80 +0,0 @@
-<script lang="ts">
- import { Glyph, type CallbackPromise, type IClOpt } from "$lib";
- import { onDestroy, onMount } from "svelte";
- import { slide } from "svelte/transition";
-
- export let basis: IClOpt & {
- label: string;
- list: {
- label: string;
- callback: CallbackPromise;
- }[];
- };
-
- let visible_menu = false;
-
- onMount(async () => {
- try {
- document.addEventListener("click", () => toggle(false));
- } catch (e) {
- } finally {
- }
- });
-
- onDestroy(() => {
- document.removeEventListener("click", () => toggle(false));
- });
-
- const toggle = (toggle_force?: boolean): void => {
- visible_menu =
- typeof toggle_force === `boolean` ? toggle_force : !visible_menu;
- };
-</script>
-
-<div class={`relative inline-block`}>
- <button
- class={`group flex flex-row h-[2rem] ${visible_menu ? `w-[160px] pl-5 pr-3` : `min-w-[120px] pl-3 pr-3`} gap-[0.5rem] justify-between items-center bg-layer-0-surface_w rounded-t-touch ${visible_menu ? `` : `rounded-b-touch`} border-line border-layer-0-surface-edge el-re`}
- on:click|stopPropagation={async () => {
- toggle();
- }}
- >
- <p
- class={`font-circ font-[400] text-layer-1-glyph text-sm tracking-wide`}
- >
- {basis.label || ``}
- </p>
- <Glyph
- basis={{
- classes: `text-layer-1-glyph ${visible_menu ? `rotate-90` : ``} duration-[350ms] el-re`,
- dim: `xs`,
- weight: `bold`,
- key: `caret-down`,
- }}
- />
- </button>
- {#if visible_menu}
- <div
- class={`absolute left-0 w-full bg-base-100 rounded-b-touch border-b-line border-l-line border-r-line border-layer-0-surface-edge overflow-hidden`}
- in:slide={{ duration: 350 }}
- out:slide={{ duration: 150 }}
- >
- <div class={`flex flex-col w-full justify-center items-start`}>
- {#each basis.list as li}
- <button
- class={`group flex flex-row h-[2rem] w-full first:pt-1 last:pb-1 pl-5 pr-1 gap-[0.5rem] justify-start items-center overflow-hidden active:bg-layer-0-surface_a/40 el-re`}
- on:click|stopPropagation={async () => {
- toggle(false);
- await li.callback();
- }}
- >
- <p
- class={`font-circ font-[400] text-layer-1-glyph text-sm tracking-wide group-active:opacity-60 el-re`}
- >
- {li.label || ``}
- </p>
- </button>
- {/each}
- </div>
- </div>
- {/if}
-</div>
diff --git a/apps-lib/src/lib/components/button_opts_static.svelte b/apps-lib/src/lib/components/button_opts_static.svelte
@@ -1,99 +0,0 @@
-<script lang="ts">
- import { Fill, Glyph, type CallbackPromise, type IClOpt } from "$lib";
- import { onDestroy, onMount } from "svelte";
- import { slide } from "svelte/transition";
-
- export let basis: IClOpt & {
- label: string;
- list: {
- label: string;
- callback: CallbackPromise;
- active: boolean;
- }[];
- };
-
- let visible_menu = false;
-
- onMount(async () => {
- try {
- document.addEventListener("click", () => toggle(false));
- } catch (e) {
- } finally {
- }
- });
-
- onDestroy(() => {
- document.removeEventListener("click", () => toggle(false));
- });
-
- const toggle = (toggle_force?: boolean): void => {
- visible_menu =
- typeof toggle_force === `boolean` ? toggle_force : !visible_menu;
- };
-</script>
-
-<div class={`relative inline-block`}>
- <button
- class={`group flex flex-row h-[2rem] ${visible_menu ? `w-[160px] pl-8 pr-3` : `w-[90px] pl-3 pr-3`} gap-[0.5rem] justify-between items-center bg-layer-0-surface_w rounded-t-touch ${visible_menu ? `` : `rounded-b-touch`} border-line border-layer-0-surface-edge el-re`}
- on:click|stopPropagation={async () => {
- toggle();
- }}
- >
- <p
- class={`font-circ font-[400] text-layer-1-glyph text-sm tracking-wide`}
- >
- {basis.label || ``}
- </p>
- <Glyph
- basis={{
- classes: `text-layer-1-glyph ${visible_menu ? `rotate-90` : ``} duration-[350ms] el-re`,
- dim: `xs`,
- weight: `bold`,
- key: `caret-down`,
- }}
- />
- </button>
- {#if visible_menu}
- <div
- class={`z-[20] absolute left-0 w-full bg-base-100 rounded-b-touch border-b-line border-l-line border-r-line border-layer-0-surface-edge overflow-hidden`}
- in:slide={{ duration: 350 }}
- out:slide={{ duration: 150 }}
- >
- <div
- class={`z-[20] flex flex-col w-full justify-center items-start`}
- >
- {#each basis.list as li}
- <button
- class={`group flex flex-row h-[2rem] w-full first:pt-1 last:pb-1 pl-1 pr-1 gap-[0.5rem] justify-start items-center overflow-hidden active:bg-layer-0-surface_a/40 el-re`}
- on:click|stopPropagation={async () => {
- toggle(false);
- await li.callback();
- }}
- >
- <div
- class={`flex flex-row w-5 justify-end items-center`}
- >
- {#if li.active}
- <Glyph
- basis={{
- classes: `text-layer-1-glyph`,
- dim: `xs-`,
- weight: `bold`,
- key: `check`,
- }}
- />
- {:else}
- <Fill />
- {/if}
- </div>
- <p
- class={`font-circ font-[400] text-layer-1-glyph text-sm tracking-wide group-active:opacity-60 el-re`}
- >
- {li.label || ``}
- </p>
- </button>
- {/each}
- </div>
- </div>
- {/if}
-</div>
diff --git a/apps-lib/src/lib/components/controls.svelte b/apps-lib/src/lib/components/controls.svelte
@@ -1,36 +0,0 @@
-<script lang="ts">
- import {
- app_layout,
- app_tilt,
- app_toast,
- app_win,
- envelope_tilt,
- envelope_visible,
- Toast,
- wind,
- } from "$lib";
- import { onMount } from "svelte";
-
- onMount(async () => {
- try {
- app_win.set({ h: window.innerHeight, w: window.innerWidth });
- app_toast.set(false);
- } catch (e) {
- console.log(`(layout mount) `, e);
- } finally {
- }
- });
-
- app_win.subscribe((_app_win) => {
- if (_app_win.h > wind.app.layout.mobile_y.h) app_layout.set(`mobile_y`);
- });
-
- envelope_visible.subscribe(async (_envelope_visible) => {
- if (_envelope_visible && $envelope_tilt) app_tilt.set(true);
- else app_tilt.set(false);
- });
-</script>
-
-{#if $app_toast}
- <Toast basis={$app_toast} />
-{/if}
diff --git a/apps-lib/src/lib/components/display_line.svelte b/apps-lib/src/lib/components/display_line.svelte
@@ -1,28 +0,0 @@
-<script lang="ts">
- import { fmt_cl, parse_layer, type IDisplayLine } from "$lib";
-
- export let basis: IDisplayLine;
- $: basis = basis;
-
- $: layer =
- typeof basis?.layer === `boolean`
- ? false
- : parse_layer(basis?.layer, 1);
- $: classes_layer =
- typeof layer === `boolean`
- ? `bg-transparent`
- : `bg-layer-${layer}-surface`;
- $: clases_style =
- 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/entry_line.svelte b/apps-lib/src/lib/components/entry_line.svelte
@@ -3,10 +3,10 @@
EntryWrap,
Glyph,
InputElement,
- Loading,
+ LoadSymbol,
parse_layer,
type IEntryLine,
- type ILoadingDimension,
+ type LoadingDimension,
} from "$lib";
export let basis: IEntryLine;
@@ -20,7 +20,7 @@
typeof basis.wrap?.layer === `boolean`
? ``
: `text-layer-${layer}-glyph`;
- let loading_dim: ILoadingDimension = `sm`;
+ let loading_dim: LoadingDimension = `sm`;
$: loading_dim = basis.wrap?.style === `guide` ? `md` : `sm`;
</script>
@@ -30,7 +30,7 @@
<div
class={`z-5 absolute right-0 top-0 flex flex-row h-full pr-4 justify-end items-center fade-in el-re`}
>
- <Loading
+ <LoadSymbol
basis={{
dim: loading_dim,
}}
diff --git a/apps-lib/src/lib/components/entry_multiline.svelte b/apps-lib/src/lib/components/entry_multiline.svelte
@@ -1,46 +0,0 @@
-<script lang="ts">
- import {
- fmt_cl,
- Glyph,
- parse_layer,
- TextareaElement,
- type IEntryMultiLine,
- } from "$lib";
-
- export let basis: IEntryMultiLine;
- $: basis = basis;
-
- $: layer =
- typeof basis.el?.layer === `boolean`
- ? false
- : parse_layer(basis.el?.layer, 1);
- $: classes_layer =
- 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}`}
->
- <TextareaElement 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+`,
- weight: `bold`,
- classes: `text-layer-${layer}-glyph`,
- }
- : basis.notify_inline.glyph}
- />
- </div>
- {/if}
- {/if}
-</div>
diff --git a/apps-lib/src/lib/components/entry_select.svelte b/apps-lib/src/lib/components/entry_select.svelte
@@ -1,50 +0,0 @@
-<script lang="ts">
- import {
- fmt_cl,
- Glyph,
- type IEntrySelect,
- Loading,
- parse_layer,
- } from "$lib";
- import SelectElement from "$lib/el/select_element.svelte";
- import EntryWrap from "./entry_wrap.svelte";
-
- export let value: string;
- export let basis: IEntrySelect;
- $: basis = basis;
-
- $: layer =
- 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`}>
- <Loading basis={{ dim: `sm`, blades: 8 }} />
- </div>
- {:else}
- <SelectElement
- 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`,
- weight: `bold`,
- classes: `text-layer-${layer}-glyph_d`,
- }}
- />
- </div>
- {/if}
-</EntryWrap>
diff --git a/apps-lib/src/lib/components/envelope.svelte b/apps-lib/src/lib/components/envelope.svelte
@@ -1,75 +0,0 @@
-<script lang="ts">
- import {
- EnvelopeTitled,
- Fill,
- fmt_cl,
- parse_layer,
- sleep,
- type IEnvelopeBasis,
- } from "$lib";
- import { quintInOut } from "svelte/easing";
- import { writable } from "svelte/store";
- import { slide } from "svelte/transition";
-
- export let basis: IEnvelopeBasis;
- $: basis = basis;
-
- $: layer = parse_layer(basis.layer, 1);
-
- let envelope_toggle = writable<boolean>(false);
- let envelope_visible = false;
-
- $: {
- envelope_toggle.set(basis.visible);
- }
-
- envelope_toggle.subscribe(async (envelope_toggle) => {
- if (envelope_toggle) {
- await sleep(100);
- envelope_visible = true;
- } else {
- envelope_visible = false;
- }
- });
-</script>
-
-<div
- class={`z-50 modal modal-bottom ${basis.visible ? `modal-open` : ``} m-0 p-0 backdrop-blur-sm`}
->
- <div class={`modal-box h-[100vh] m-0 p-0 bg-transparent`}>
- <div class={`flex flex-col h-full w-full justify-end items-end`}>
- <button
- class={`flex flex-grow w-full`}
- on:click={async () => {
- if (basis.close) await basis.close();
- }}
- >
- <Fill />
- </button>
- {#if envelope_visible}
- <div
- class={`${fmt_cl(basis.classes)} relative flex flex-col w-full`}
- in:slide={{
- axis: `y`,
- duration: 250,
- easing: quintInOut,
- }}
- >
- {#if `titled` in basis && basis.titled}
- <EnvelopeTitled
- basis={basis.titled}
- callback_close={basis.close}
- {layer}
- >
- {#if $$slots.default}
- <slot />
- {/if}
- </EnvelopeTitled>
- {:else if $$slots.el}
- <slot name="el" />
- {/if}
- </div>
- {/if}
- </div>
- </div>
-</div>
diff --git a/apps-lib/src/lib/components/envelope_buttons.svelte b/apps-lib/src/lib/components/envelope_buttons.svelte
@@ -1,37 +0,0 @@
-<script lang="ts">
- import { type CallbackPromise, fmt_cl } from "$lib";
- import { quintInOut } from "svelte/easing";
- import { fly } from "svelte/transition";
-
- export let basis: {
- visible: boolean;
- buttons: {
- classes?: string;
- label: string;
- callback: CallbackPromise;
- }[];
- };
-
- $: basis = basis;
-</script>
-
-{#if basis.visible}
- <div
- in:fly={{ y: `100`, easing: quintInOut }}
- out:fly={{ y: `100`, easing: quintInOut }}
- class={`z-20 absolute bottom-0 left-0 flex flex-col w-full px-4 pb-4 gap-3 justify-start items-center`}
- >
- {#each basis.buttons as button}
- <button
- class={`flex flex-row h-envelope_button w-full justify-center items-center bg-layer-2-surface active:bg-layer-2-surface_a rounded-2xl`}
- on:click={async () => {
- await button.callback();
- }}
- >
- <p class={`${fmt_cl(button.classes)} font-sans `}>
- {button.label}
- </p>
- </button>
- {/each}
- </div>
-{/if}
diff --git a/apps-lib/src/lib/components/envelope_lower.svelte b/apps-lib/src/lib/components/envelope_lower.svelte
@@ -1,97 +0,0 @@
-<script lang="ts">
- import { envelope_visible, Fill, ls, type CallbackPromise } from "$lib";
- import { quintInOut } from "svelte/easing";
- import { fly } from "svelte/transition";
-
- let el_c: HTMLDivElement;
-
- let el_c_scrolled = false;
-
- export let basis: {
- close: CallbackPromise;
- full_cover?: boolean;
- label_close?: string | true;
- };
- $: basis = basis;
-
- const handle_close = async (): Promise<void> => {
- envelope_visible.set(false);
- await basis.close();
- };
-
- const handle_scroll = (): void => {
- if (el_c.scrollTop > 10) el_c_scrolled = true;
- else el_c_scrolled = false;
- };
-</script>
-
-{#if $envelope_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`}
- >
- {#if !basis.full_cover}
- <button
- class={`flex flex-row h-[12%] w-full justify-center items-center`}
- on:click={async () => {
- await handle_close();
- }}
- >
- <Fill />
- </button>
- {/if}
- <div
- class={`z-50 relative flex flex-col ${basis.full_cover ? `h-[100vh]` : `h-[calc(100vh-12%)]`} w-full justify-start justify-start items-start rounded-t-3xl overflow-hidden`}
- >
- <div
- class={`absolute top-0 left-0 grid grid-cols-12 flex flex-row h-12 w-full px-4 pb-2 justify-center items-center ${el_c_scrolled ? `bg-layer-1-surface/30 backdrop-blur-lg` : ``} el-re`}
- >
- <div
- class={`col-span-4 flex flex-row h-full justify-start items-end`}
- >
- {#if basis.label_close}
- <button
- class={`flex flex-row justify-center items-center`}
- on:click={async () => {
- await handle_close();
- }}
- >
- <p
- class={`font-sans font-[500] text-layer-1-glyph-hl`}
- >
- {typeof basis.label_close === `string`
- ? basis.label_close
- : `${$ls(`common.cancel`)}`}
- </p>
- </button>
- {:else}
- <Fill />
- {/if}
- </div>
- <button
- class={`col-span-4 flex flex-row h-full pt-3 justify-center items-start`}
- on:click={async () => {
- await handle_close();
- }}
- >
- <div
- class={`flex flex-row justify-start items-center h-1 w-10 rounded-full ${basis.full_cover ? `bg-layer-1-surface shadow-md` : `bg-layer-2-surface-edge`}`}
- />
- </button>
- <div
- class={`col-span-4 flex flex-row justify-start items-center`}
- >
- <Fill />
- </div>
- </div>
- <div
- bind:this={el_c}
- on:scroll={handle_scroll}
- class={`z-[100] [flex flex-col ${basis.full_cover ? `h-full` : `pt-12 `} w-full justify-start items-center overflow-y-scroll overflow-x-hidden scroll-hide`}
- >
- <slot />
- </div>
- </div>
- </div>
-{/if}
diff --git a/apps-lib/src/lib/components/envelope_titled.svelte b/apps-lib/src/lib/components/envelope_titled.svelte
@@ -1,91 +0,0 @@
-<script lang="ts">
- import {
- ButtonGlyph,
- type CallbackPromise,
- Fill,
- fmt_cl,
- type IEnvelopeTitledBasis,
- ls,
- } from "$lib";
- import type { ThemeLayer } from "@radroots/theme";
-
- export let basis: IEnvelopeTitledBasis;
- export let layer: ThemeLayer;
- export let callback_close: CallbackPromise;
-
- $: classes_base =
- basis.hide_border === true || typeof basis.hide_border !== `boolean`
- ? ``
- : `border-b-line border-layer-${layer}-surface-edge`;
- $: classes_submit =
- typeof basis.submit?.valid === `boolean` && !basis.submit?.valid
- ? `text-layer-${layer}-glyph-shade opacity-40`
- : `text-layer-${layer}-glyph-hl group-active:opacity-60`;
-</script>
-
-<div
- class={`flex flex-col h-[700px] w-full bg-layer-${layer + 1}-surface rounded-t-3xl`}
->
- <div class={`${classes_base} grid grid-cols-12 h-envelope_top w-full px-4`}>
- <div
- class={`col-span-3 flex flex-row h-full justify-start items-center`}
- >
- <button
- class={`group`}
- on:click|preventDefault={async () => await callback_close()}
- >
- <p
- class={`${fmt_cl(basis.previous?.label?.classes)} font-sans text-env_tiPrevious text-layer-${layer}-glyph-hl group-active:opacity-40 el-re`}
- >
- {basis.previous?.label?.value || `${$ls(`common.cancel`)}`}
- </p>
- </button>
- </div>
- <div
- class={`col-span-6 flex flex-row h-full justify-center items-center`}
- >
- {#if basis.heading?.label?.value}
- <p
- class={`${fmt_cl(basis.heading?.label?.classes)} font-sans text-env_ti text-layer-${layer + 1}-glyph`}
- >
- {basis.heading?.label?.value || ``}
- </p>
- {:else}
- <Fill />
- {/if}
- </div>
- <div class={`col-span-3 flex flex-row h-full justify-end items-center`}>
- {#if basis.submit}
- <button
- class={`group`}
- on:click|preventDefault={async () => {
- if (
- typeof basis.submit?.valid === `boolean` &&
- !basis.submit?.valid
- )
- return;
- await basis.submit?.callback();
- }}
- >
- {#if `glyph` in basis.submit}
- <ButtonGlyph basis={basis.submit?.glyph} />
- {:else if `label` in basis.submit}
- <p
- class={`font-sans text-env_tiAction ${classes_submit} el-re`}
- >
- {basis.submit?.label.value ||
- `${$ls(`common.add`)}`}
- </p>
- {:else}
- <Fill />
- {/if}
- </button>
- {:else}
- <Fill />
- {/if}
- </div>
- </div>
- <div class={`flex flex-col w-full overflow-y-scroll`}>
- <slot />
- </div>
-</div>
diff --git a/apps-lib/src/lib/components/glyph_title_select_label.svelte b/apps-lib/src/lib/components/glyph_title_select_label.svelte
@@ -1,34 +0,0 @@
-<script lang="ts">
- import { ascii } from "$lib";
-
- export let basis: {
- label: string;
- };
-</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]`}
- >
- {`${ascii.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]`}
- >
- {`${ascii.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/inset_white.svelte b/apps-lib/src/lib/components/inset_white.svelte
@@ -1,9 +0,0 @@
-<script lang="ts">
- import { Fill } from "$lib";
-</script>
-
-<div
- class={`absolute inset-0 flex flex-row justify-start items-center bg-white/10`}
->
- <Fill />
-</div>
diff --git a/apps-lib/src/lib/components/label_display.svelte b/apps-lib/src/lib/components/label_display.svelte
@@ -0,0 +1,28 @@
+<script lang="ts">
+ import { fmt_cl, parse_layer, type ILabelDisplay } from "$lib";
+
+ export let basis: ILabelDisplay;
+ $: basis = basis;
+
+ $: layer =
+ typeof basis?.layer === `boolean`
+ ? false
+ : parse_layer(basis?.layer, 1);
+ $: classes_layer =
+ typeof layer === `boolean`
+ ? `bg-transparent`
+ : `bg-layer-${layer}-surface`;
+ $: clases_style =
+ 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_area.svelte b/apps-lib/src/lib/components/layout_area.svelte
@@ -1,59 +0,0 @@
-<script lang="ts">
- import {
- type AppLayoutKey,
- type IClOpt,
- app_layout,
- fmt_cl,
- nav_blur,
- tabs_blur,
- } from "$lib";
- import { onDestroy, onMount } from "svelte";
-
- const styles: Record<AppLayoutKey, string> = {
- mobile_base: "pt-4",
- mobile_y: "pt-16 pb-10",
- };
-
- export let basis:
- | (IClOpt & { fade?: boolean; hide_padding?: boolean })
- | undefined = undefined;
- $: basis = basis;
-
- let el: HTMLElement | null;
-
- onMount(async () => {
- try {
- el?.addEventListener("scroll", scrollChange);
- } catch (e) {
- } finally {
- }
- });
-
- onDestroy(async () => {
- try {
- el?.removeEventListener("scroll", scrollChange);
- } catch (e) {
- } finally {
- }
- });
-
- $: classes_fade = basis?.fade ? `fade-in` : ``;
-
- 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);
- };
-</script>
-
-<div
- bind:this={el}
- class={`${fmt_cl(basis?.classes)} absolute top-0 left-0 flex flex-col h-[100vh] w-full justify-center items-center ${classes_fade}`}
->
- <div
- class={`flex flex-col h-view_${$app_layout} w-full justify-start items-start overflow-y-scroll scroll-hide -translate-y-h_view_offset_${$app_layout}`}
- >
- <slot />
- </div>
-</div>
diff --git a/apps-lib/src/lib/components/layout_root.svelte b/apps-lib/src/lib/components/layout_root.svelte
@@ -0,0 +1,6 @@
+<script lang="ts">
+ import { CssStatic, CssStyles } from "$lib";
+</script>
+
+<CssStatic />
+<CssStyles />
diff --git a/apps-lib/src/lib/components/layout_trellis.svelte b/apps-lib/src/lib/components/layout_trellis.svelte
@@ -1,11 +0,0 @@
-<script lang="ts">
- import { fmt_cl, type IClOpt } from "$lib";
-
- export let basis: IClOpt | undefined = undefined;
-</script>
-
-<div
- class={`${fmt_cl(basis?.classes)} flex flex-col pb-12 gap-4 justify-center items-center scroll-hide`}
->
- <slot />
-</div>
diff --git a/apps-lib/src/lib/components/layout_trellis_line.svelte b/apps-lib/src/lib/components/layout_trellis_line.svelte
@@ -1,67 +0,0 @@
-<script lang="ts">
- import {
- fmt_cl,
- type ICb,
- type IClOpt,
- type IGlOpt,
- type ILabelOpt,
- } from "$lib";
- import Glyph from "$lib/el/glyph.svelte";
- import { fade } from "svelte/transition";
-
- export let basis:
- | (ILabelOpt &
- IClOpt & {
- notify?: IClOpt &
- ICb &
- ILabelOpt &
- IGlOpt & {
- glyph_first?: boolean;
- };
- })
- | undefined = undefined;
- $: basis = basis;
-</script>
-
-<div
- class={`${fmt_cl(basis?.classes)} flex flex-col w-trellis_line 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 `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 }}
- on:click={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}
- <slot />
-</div>
diff --git a/apps-lib/src/lib/components/layout_view.svelte b/apps-lib/src/lib/components/layout_view.svelte
@@ -1,7 +1,5 @@
<script lang="ts">
import {
- type AppLayoutKey,
- type IClOpt,
app_layout,
fmt_cl,
layout_view_cover,
@@ -10,6 +8,8 @@
ph_blur,
tabs_blur,
tabs_visible,
+ type AppLayoutKey,
+ type IClOpt,
} from "$lib";
import { onDestroy, onMount } from "svelte";
@@ -19,8 +19,6 @@
};
export let basis: (IClOpt & { fade?: boolean }) | undefined = undefined;
- $: basis = basis;
-
let el: HTMLElement | null;
onMount(async () => {
@@ -39,11 +37,6 @@
}
});
- $: classes_layout = $nav_visible
- ? `pt-h_nav_${$app_layout} ${styles[$app_layout]}`
- : styles[$app_layout];
- $: classes_tabs = $tabs_visible ? `pb-h_tabs_${$app_layout}` : ``;
-
const scrollChange = (): void => {
if (Math.max(el?.scrollTop || 0, 0) > 10) nav_blur.set(true);
else nav_blur.set(false);
@@ -56,7 +49,14 @@
<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 overflow-y-scroll scroll-hide ${$layout_view_cover ? `` : classes_layout} ${$layout_view_cover ? `` : classes_tabs} ${basis?.fade ? `fade-in` : ``}`}
+ class={`${fmt_cl(basis?.classes)} absolute top-0 left-0 flex flex-col h-[100vh] w-full justify-start items-center overflow-y-scroll scroll-hide ${
+ $layout_view_cover
+ ? ``
+ : $nav_visible
+ ? `pt-h_nav_${$app_layout} ${styles[$app_layout]}`
+ : `` //styles[$app_layout]
+ } ${$layout_view_cover ? `` : $tabs_visible ? `pb-h_tabs_${$app_layout}` : ``} `}
+ class:fade-in={basis?.fade}
>
<slot />
</div>
diff --git a/apps-lib/src/lib/components/layout_window.svelte b/apps-lib/src/lib/components/layout_window.svelte
@@ -1,5 +1,7 @@
-<script>
- import { Blur, app_tilt } from "$lib";
+<script lang="ts">
+ import { app_tilt } from "$lib";
+
+ // <Blur />
</script>
<div
@@ -8,6 +10,4 @@
<div class={`flex flex-col h-full w-full`}>
<slot />
</div>
- <slot name="overlay" />
- <Blur />
</div>
diff --git a/apps-lib/src/lib/components/loading_view.svelte b/apps-lib/src/lib/components/loading_view.svelte
@@ -1,9 +0,0 @@
-<script lang="ts">
- import { Loading } from "$lib";
-</script>
-
-<div
- class={`z-50 absolute top-0 left-0 flex flex-row h-[100vh] w-full justify-center items-center bg-layer-0-surface`}
->
- <Loading basis={{ dim: `lg` }} />
-</div>
diff --git a/apps-lib/src/lib/components/nav.svelte b/apps-lib/src/lib/components/nav.svelte
@@ -1,167 +0,0 @@
-<script lang="ts">
- import { goto } from "$app/navigation";
- import {
- app_layout,
- ButtonArrow,
- encode_qp_route,
- Fill,
- fmt_cl,
- Glyph,
- Loading,
- nav_blur,
- nav_prev,
- nav_visible,
- NavOption,
- type INavBasis,
- } from "$lib";
- import { onDestroy, onMount } from "svelte";
-
- export let basis: INavBasis;
- $: basis = basis;
-
- let el: HTMLElement | null;
- let el_inner: HTMLElement | null;
-
- let nav_prev_label = ``;
-
- $: classes_nav_blur = $nav_blur ? `bg-white/40 backdrop-blur-sm` : ``;
-
- onMount(async () => {
- try {
- nav_visible.set(true);
- if ($nav_prev.length)
- nav_prev_label = $nav_prev[$nav_prev.length - 1].label || ``;
- } catch (e) {
- } finally {
- }
- });
-
- onDestroy(async () => {
- try {
- nav_visible.set(false);
- } catch (e) {
- } finally {
- }
- });
-
- const callback_prev = async (): Promise<void> => {
- try {
- if (basis.prev.prevent_route) {
- await basis.prev.prevent_route.callback();
- return;
- } else if (basis.prev.callback) await basis.prev.callback();
- let route_to =
- typeof basis.prev.route === `string`
- ? basis.prev.route
- : encode_qp_route(basis.prev.route[0], basis.prev.route[1]);
- if ($nav_prev.length) {
- const nav_prev_li = $nav_prev[$nav_prev.length - 1];
- $nav_prev = [...$nav_prev.slice(0, -1)];
- if (nav_prev_li)
- route_to = encode_qp_route(
- nav_prev_li.route,
- nav_prev_li.params,
- );
- }
- await goto(route_to);
- } catch (e) {
- console.log(`(error) callback_prev `, e);
- }
- };
-</script>
-
-<div
- bind:this={el}
- class={`z-10 absolute top-0 left-0 flex flex-col w-full justify-start items-start h-nav_${$app_layout} ${classes_nav_blur} duration-[250ms] el-re`}
->
- <div
- bind:this={el_inner}
- class={`relative flex flex-col h-full w-full justify-end items-center`}
- >
- <div
- class={`absolute bottom-[6px] left-0 grid grid-cols-12 flex flex-row h-8 w-full justify-start items-center`}
- >
- <div
- class={`col-span-4 flex flex-row w-full justify-start items-center`}
- >
- {#if basis.prev.loading}
- <div
- class={`flex flex-row pl-4 justify-center items-center`}
- >
- <Loading />
- </div>
- {:else if basis.prev.kind === `arrow`}
- <div
- class={`flex flex-row w-full pl-8 justify-start items-center`}
- >
- <ButtonArrow
- basis={{
- label: nav_prev_label || basis.prev.label,
- callback: async () => {
- await callback_prev();
- },
- }}
- />
- </div>
- {:else}
- <button
- class={`group flex flex-row h-full pl-2 justify-start items-center`}
- on:click={async () => {
- await callback_prev();
- }}
- >
- <Glyph
- basis={{
- key: `caret-left`,
- weight: `bold`,
- dim: `md+`,
- classes: `text-layer-1-glyph-hl group-active:opacity-70 transition-opacity`,
- }}
- />
- {#if nav_prev_label || basis.prev.label}
- <p
- class={`font-sans text-nav_prev text-layer-1-glyph-hl group-active:opacity-60 transition-opacity`}
- >
- {nav_prev_label || basis.prev.label}
- </p>
- {:else}
- <Fill />
- {/if}
- </button>
- {/if}
- </div>
- <div
- class={`col-span-4 flex flex-row h-full justify-center items-center`}
- >
- {#if basis.title}
- <button
- class={`flex flex-row justify-center items-center`}
- on:click={async () => {
- if (basis.title.callback)
- await basis.title.callback();
- }}
- >
- {#if `value` in basis.title.label}
- <p
- class={`${fmt_cl(basis.title.label.classes)} font-sans text-nav_curr text-layer-1-glyph`}
- >
- {basis.title.label.value}
- </p>
- {/if}
- </button>
- {:else}
- <Fill />
- {/if}
- </div>
- <div
- class={`col-span-4 flex flex-row h-full justify-end items-center`}
- >
- {#if basis.option}
- <NavOption basis={basis.option} />
- {:else}
- <Fill />
- {/if}
- </div>
- </div>
- </div>
-</div>
diff --git a/apps-lib/src/lib/components/nav_option.svelte b/apps-lib/src/lib/components/nav_option.svelte
@@ -1,82 +0,0 @@
-<!-- svelte-ignore a11y-label-has-associated-control -->
-<script lang="ts">
- import {
- fmt_cl,
- Glyph,
- Loading,
- parse_layer,
- type INavBasisOption,
- } from "$lib";
-
- let el_swap: HTMLLabelElement | null = null;
-
- export let basis: INavBasisOption;
- $: basis = basis;
- $: layer = parse_layer(1);
- $: classes_disabled = basis.disabled ? `opacity-40` : ``;
-</script>
-
-{#if basis?.loading}
- <div class={`flex flex-row pr-4 justify-center items-center`}>
- <Loading />
- </div>
-{:else}
- <button
- class={`${fmt_cl(basis?.classes)} group col-span-4 flex flex-row h-full justify-end items-center ${classes_disabled}`}
- on:click={async () => {
- if (!basis.disabled) await basis?.callback(el_swap);
- }}
- >
- {#if `glyph` in basis && basis?.glyph}
- <Glyph
- basis={{
- classes: `group-active:opacity-70 ${basis?.glyph?.classes}`,
- ...basis?.glyph,
- }}
- />
- {/if}
- {#if `label` in basis && basis?.label}
- <div
- class={`flex flex-row justify-start items-center ${basis?.label && `glyph` in basis?.label && basis.label?.glyph ? `pr-2` : `pr-4`}`}
- >
- {#if `swap` in basis?.label}
- <label
- bind:this={el_swap}
- class={`swap${basis?.label?.swap?.toggle ? ` swap-active` : ``}`}
- >
- <div class="swap-on">
- <p
- class={`${fmt_cl(basis?.label?.swap?.on.classes || `text-nav_prev text-layer-${layer}-glyph-hl group-active:opacity-70`)} font-sans -translate-y-[1px] el-re`}
- >
- {basis?.label?.swap?.on.value}
- </p>
- </div>
- <div class="swap-off">
- <p
- class={`${fmt_cl(basis?.label?.swap?.off.classes || `text-nav_prev text-layer-${layer}-glyph-hl group-active:opacity-70`)} font-sans -translate-y-[1px] el-re`}
- >
- {basis?.label?.swap?.off.value}
- </p>
- </div>
- </label>
- {:else if `value` in basis?.label}
- <p
- class={`${fmt_cl(basis?.label.classes)} font-sans text-nav_prev text-layer-1-glyph-hl group-active:opacity-70 el-re`}
- >
- {basis?.label.value}
- </p>
- {/if}
- {#if `glyph` in basis?.label}
- <Glyph
- basis={{
- key: basis?.label?.glyph?.key,
- classes: `text-layer-1-glyph-hl group-active:opacity-70 ${basis?.label?.glyph?.classes}`,
- weight: `bold`,
- dim: `md`,
- }}
- />
- {/if}
- </div>
- {/if}
- </button>
-{/if}
diff --git a/apps-lib/src/lib/components/nav_toolbar.svelte b/apps-lib/src/lib/components/nav_toolbar.svelte
@@ -1,66 +0,0 @@
-<script lang="ts">
- import {
- Glyph,
- LogoCircleSm,
- ls,
- PageHeader,
- route,
- type CallbackPromiseReturn,
- type IPageHeader,
- type NavigationRoute,
- } from "$lib";
-
- export let basis: {
- callback_route?: CallbackPromiseReturn<NavigationRoute | undefined>;
- page_header?: IPageHeader;
- };
-</script>
-
-<div class={`flex flex-row h-12 w-full px-6 pb-6 justify-between items-center`}>
- <button
- class={`flex flex-row gap-2 justify-start items-center`}
- on:click={async () => {
- if (basis.callback_route) {
- const route_to = await basis.callback_route();
- if (!route_to) return;
- await route(route_to);
- return;
- }
- await route(`/`);
- }}
- >
- <LogoCircleSm />
- <p
- class={`font-sansd italic font-[700] text-[1.7rem] text-layer-0-glyph lowercase`}
- >
- {`${$ls(`app.name`)}`}
- </p>
- </button>
- <button
- class={`flex flex-row justify-center items-center`}
- on:click={async () => {
- await route(`/settings`);
- }}
- >
- <Glyph
- basis={{
- classes: `text-layer-0-glyph`,
- dim: `lg`,
- weight: `bold`,
- key: `gear`,
- }}
- />
- </button>
-</div>
-{#if basis?.page_header}
- <PageHeader
- basis={{
- callback_route: basis.callback_route,
- ...basis?.page_header,
- }}
- >
- <div slot="option" class={`flex flex-row justify-start items-center`}>
- <slot name="page_header_option" />
- </div>
- </PageHeader>
-{/if}
diff --git a/apps-lib/src/lib/components/notify_glyph.svelte b/apps-lib/src/lib/components/notify_glyph.svelte
@@ -1,25 +0,0 @@
-<script lang="ts">
- import { fmt_cl, Glyph, type GlyphKey, type IGlyph } from "$lib";
- import type { ThemeLayer } from "@radroots/theme";
-
- export let basis: {
- classes?: string;
- glyph: GlyphKey | IGlyph;
- layer: ThemeLayer;
- };
-</script>
-
-<div
- class={`${fmt_cl(basis.classes)} z-10 absolute right-0 top-0 flex flex-row h-full pr-3 justify-end items-center fade-in el-re`}
->
- <Glyph
- basis={typeof basis.glyph === `string`
- ? {
- key: basis.glyph,
- dim: `xs+`,
- weight: `bold`,
- classes: `text-layer-${basis.layer}-glyph`,
- }
- : basis.glyph}
- />
-</div>
diff --git a/apps-lib/src/lib/components/overlay_loading.svelte b/apps-lib/src/lib/components/overlay_loading.svelte
@@ -0,0 +1,14 @@
+<script lang="ts">
+ import { app_loading, LoadSymbol } from "$lib";
+ import { fade } from "svelte/transition";
+</script>
+
+{#if $app_loading}
+ <div
+ in:fade={{ duration: 200 }}
+ out:fade={{ delay: 50, duration: 200 }}
+ class={`z-50 absolute top-0 left-0 flex flex-row h-[100vh] w-full justify-center items-center bg-layer-0-surface`}
+ >
+ <LoadSymbol basis={{ dim: `lg` }} />
+ </div>
+{/if}
diff --git a/apps-lib/src/lib/components/overlay_splash.svelte b/apps-lib/src/lib/components/overlay_splash.svelte
@@ -0,0 +1,14 @@
+<script lang="ts">
+ import { app_splash, LogoCircle } from "$lib";
+ import { fade } from "svelte/transition";
+</script>
+
+{#if $app_splash}
+ <div
+ in:fade={{ duration: 200 }}
+ out:fade={{ delay: 50, duration: 200 }}
+ class={`z-50 flex flex-row h-[100vh] w-full justify-center items-center bg-layer-0-surface`}
+ >
+ <LogoCircle />
+ </div>
+{/if}
diff --git a/apps-lib/src/lib/components/page_header.svelte b/apps-lib/src/lib/components/page_header.svelte
@@ -1,54 +0,0 @@
-<script lang="ts">
- import { app_layout, Fill, ph_blur, route, type IPageHeader } from "$lib";
- import { fade } from "svelte/transition";
-
- export let basis: IPageHeader;
-</script>
-
-{#if $ph_blur}
- <div
- in:fade={{ duration: 200 }}
- out:fade={{ delay: 50, duration: 200 }}
- class={`z-20 fixed top-0 left-0 flex flex-row h-nav_${$app_layout} w-full justify-center items-center bg-layer-0-surface-blur/40 backdrop-blur-lg border-b-line border-layer-0-surface-edge/30`}
- >
- <Fill />
- </div>
-{/if}
-<div
- class={`z-20 sticky top-0 flex flex-row w-full pb-4 px-6 justify-between items-center`}
->
- <div class={`flex flex-row justify-start items-center`}>
- {#if typeof basis.label === `string`}
- <p
- class={`font-sansd font-[600] text-2xl text-layer-0-glyph capitalize`}
- >
- {basis.label || ``}
- </p>
- {:else}
- <button
- class={`flex flex-row gap-1 justify-center items-center`}
- on:click={async () => {
- if (typeof basis.label !== `string`) {
- if (basis.callback_route) {
- const route_to = await basis.callback_route();
- if (!route_to) return;
- await route(route_to);
- return;
- }
- await route(
- basis.label[1].route,
- basis.label[1].route_param || undefined,
- );
- }
- }}
- >
- <p
- class={`font-sansd font-[600] text-2xl text-layer-0-glyph capitalize`}
- >
- {basis.label[0] || ``}
- </p>
- </button>
- {/if}
- </div>
- <slot name="option" />
-</div>
diff --git a/apps-lib/src/lib/components/splash_screen.svelte b/apps-lib/src/lib/components/splash_screen.svelte
@@ -1,9 +0,0 @@
-<script lang="ts">
- import { LogoCircle } from "$lib";
-</script>
-
-<div
- class={`z-50 absolute top-0 left-0 flex flex-row h-[100vh] w-full justify-center items-center bg-layer-0-surface`}
->
- <LogoCircle />
-</div>
diff --git a/apps-lib/src/lib/components/tabs.svelte b/apps-lib/src/lib/components/tabs.svelte
@@ -1,95 +0,0 @@
-<script lang="ts">
- import {
- Glyph,
- type ITabsBasis,
- app_layout,
- fmt_cl,
- sleep,
- tabs_active,
- tabs_blur,
- tabs_visible,
- } from "$lib";
- import { onDestroy, onMount } from "svelte";
-
- export let basis: ITabsBasis;
- $: basis = basis;
-
- $: classes_blur = $tabs_blur ? `bg-layer-1-surface/30` : ``;
-
- let tab_focus: number | null = null;
-
- let el: HTMLElement | null;
- let el_inner: HTMLElement | null;
-
- onMount(async () => {
- try {
- tabs_visible.set(true);
- } catch (e) {
- } finally {
- }
- });
-
- onDestroy(async () => {
- try {
- tabs_visible.set(false);
- } catch (e) {
- } finally {
- }
- });
-</script>
-
-<div
- bind:this={el}
- class={`${fmt_cl(basis?.classes)} z-10 absolute bottom-0 left-0 flex flex-col w-full justify-start items-start bg-layer-0-surface/40 backdrop-blur-md h-tabs_${$app_layout} ${classes_blur} el-re`}
->
- <div
- bind:this={el_inner}
- class={`relative flex flex-col h-full w-full justify-start items-start`}
- >
- <div
- class={`absolute top-3 left-0 grid grid-cols-12 flex flex-row w-full justify-center items-center`}
- >
- {#if $$slots.default}
- <slot />
- {:else}
- {#each basis?.list || [] as tab, tab_i}
- <button
- class={`group col-span-3 flex flex-col h-full gap-[2px] justify-start items-center el-re`}
- on:click={async () => {
- tab_focus = tab_i;
- if (!tab.hide_active) tabs_active.set(tab_i);
- await tab.callback(tab_i);
- await sleep(150);
- tab_focus = null;
- }}
- >
- <Glyph
- basis={{
- classes:
- !basis.hide_active && $tabs_active === tab_i
- ? `text-layer-2-glyph text-lineActiveBlue`
- : `text-layer-2-glyph text-lineMd`,
- key: tab.icon,
- dim: `md`,
- weight: tab.force_weight
- ? tab.force_weight
- : typeof tab_focus === `number` &&
- tab_focus === tab_i
- ? `fill`
- : !basis.hide_active &&
- $tabs_active === tab_i
- ? tab.active_weight || `fill`
- : `bold`,
- }}
- />
- <p
- class={`font-circ font-[400] text-layer-2-glyph text-xs tracking-tight`}
- >
- {tab.label || ``}
- </p>
- </button>
- {/each}
- {/if}
- </div>
- </div>
-</div>
diff --git a/apps-lib/src/lib/components/tabs_float.svelte b/apps-lib/src/lib/components/tabs_float.svelte
@@ -1,100 +0,0 @@
-<script lang="ts">
- import { page } from "$app/stores";
- import { Fill, Glyph, route } from "$lib";
-</script>
-
-<div
- class={`absolute bottom-0 left-0 h-24 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`}
- on:click={async () => {
- await route(`/`);
- }}
- >
- <Glyph
- basis={{
- classes: `text-[26px] text-layer-0-glyph/80 rotate-90`,
- weight: $page.url.pathname !== `/` ? `bold` : `fill`,
- key: `columns`,
- }}
- />
- </button>
- <button
- class={`relative col-span-1 flex flex-row justify-center items-center`}
- on:click={async () => {
- await route(`/search`);
- }}
- >
- <Glyph
- basis={{
- classes: `text-[24px] text-layer-0-glyph/80`,
- weight: $page.url.pathname.startsWith(`/search`)
- ? `fill`
- : `bold`,
- key: `magnifying-glass`,
- }}
- />
- </button>
- <button
- class={`relative col-span-1 flex flex-row justify-center items-center`}
- on:click={async () => {
- route(`/settings/profile`);
- }}
- >
- <Glyph
- basis={{
- classes: `text-[24px] text-layer-0-glyph/80`,
- weight: $page.url.pathname.startsWith(
- `/settings/profile`,
- )
- ? `fill`
- : `bold`,
- key: `user`,
- }}
- />
- </button>
- <button
- class={`relative col-span-1 flex flex-row h-full justify-center items-center`}
- on:click={async () => {
- await route(`/notifications`);
- }}
- >
- <Glyph
- basis={{
- classes: `text-[24px] text-layer-0-glyph/80`,
- weight: $page.url.pathname.startsWith(`/notifications`)
- ? `fill`
- : `bold`,
- key: `bell`,
- }}
- />
- <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`}
- >
- <Fill />
- </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`}
- on:click={async () => {}}
- >
- <Glyph
- basis={{
- classes: `text-[22px] text-layer-0-glyph/80`,
- weight: `bold`,
- key: `plus`,
- }}
- />
- </button>
- </div>
-</div>
diff --git a/apps-lib/src/lib/components/trellis.svelte b/apps-lib/src/lib/components/trellis.svelte
@@ -1,124 +0,0 @@
-<script lang="ts">
- import {
- app_layout,
- fmt_cl,
- ls,
- parse_layer,
- TrellisDefaultLabel,
- TrellisInput,
- TrellisOffset,
- TrellisSelect,
- TrellisTitle,
- TrellisTouch,
- type ITrellis,
- } from "$lib";
-
- export let basis: { args: ITrellis };
- $: ({ args } = basis);
- $: hide_border_t =
- typeof args.hide_border_top === `boolean` ? args.hide_border_top : true;
- $: hide_border_b =
- typeof args.hide_border_bottom === `boolean`
- ? args.hide_border_bottom
- : true;
- $: hide_rounded =
- typeof args.hide_rounded === `boolean` ? args.hide_rounded : false;
- $: set_title_background =
- typeof args.set_title_background === `boolean`
- ? args.set_title_background
- : false;
- $: set_default_background =
- typeof args.set_default_background === `boolean`
- ? args.set_default_background
- : false;
-</script>
-
-<div
- id={basis.args.id || ``}
- class={`${fmt_cl(args.classes)} flex flex-col`}
- data-view={basis.args.view || ``}
->
- <div
- class={`relative flex flex-col h-auto w-${$app_layout} gap-[3px] ${set_title_background ? `bg-layer-${args.layer}-surface` : ``}`}
- >
- {#if args.title && (!args.default_el || (args.default_el && args.default_el.show_title))}
- <TrellisTitle
- basis={args.title}
- layer={parse_layer(args.layer - 1)}
- />
- {/if}
- {#if args.default_el}
- <div
- class={`flex flex-col h-auto w-full justify-center items-center`}
- >
- {#if $$slots.default_el}
- <slot name="default_el" />
- {:else if args.default_el}
- <TrellisDefaultLabel
- layer={parse_layer(args.layer - 1)}
- labels={args.default_el.labels
- ? args.default_el.labels
- : [
- {
- label: `${$ls(`common.no_items_to_display`)}.`,
- },
- ]}
- />
- {/if}
- </div>
- {:else if args.list}
- <div class={`flex flex-col w-full justify-center items-center`}>
- {#each args.list as basis}
- <div
- class={`${basis.hide_field ? "hidden" : ``} group flex flex-row h-full w-full justify-end items-center bg-layer-${args.layer}-surface ${basis.full_rounded ? `rounded-touch` : ``} ${hide_rounded ? `` : `first:rounded-t-2xl last:rounded-b-2xl`} ${!basis.hide_active ? `active:bg-layer-${args.layer}-surface_a` : ``} el-re`}
- >
- <div
- class={`flex flex-row h-full w-full gap-1 items-center overflow-y-hidden`}
- >
- {#if !args.hide_offset}
- <TrellisOffset
- basis={basis.offset}
- layer={args.layer}
- />
- {/if}
- {#if $$slots.offset}
- <slot name="offset" />
- {/if}
- {#if `touch` in basis && basis.touch}
- <TrellisTouch
- basis={basis.touch}
- layer={args.layer}
- {hide_border_b}
- {hide_border_t}
- hide_active={!!basis.hide_active}
- />
- {:else if `input` in basis && basis.input}
- <TrellisInput
- basis={basis.input}
- layer={args.layer}
- {hide_border_b}
- {hide_border_t}
- />
- {:else if `select` in basis && basis.select}
- <TrellisSelect
- basis={basis.select}
- layer={args.layer}
- {hide_border_b}
- {hide_border_t}
- hide_active={!!basis.hide_active}
- />
- {/if}
- </div>
- </div>
- {/each}
- </div>
- {/if}
- </div>
- {#if $$slots.append}
- <div
- class={`flex flex-col w-full ${set_default_background ? `bg-layer-${args.layer}-surface` : ``}`}
- >
- <slot name="append" />
- </div>
- {/if}
-</div>
diff --git a/apps-lib/src/lib/components/trellis_default_label.svelte b/apps-lib/src/lib/components/trellis_default_label.svelte
@@ -1,36 +0,0 @@
-<script lang="ts">
- import { fmt_cl, type ITrellisDefaultLabel } from "$lib";
- import type { ThemeLayer } from "@radroots/theme";
-
- export let classes = ``;
- export let layer: ThemeLayer;
- export let labels: ITrellisDefaultLabel[];
-</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 `route` in label}
- <a href={label.route}>
- {label.label}
- </a>
- {:else if `callback` in label}
- <button
- class={``}
- on:click|preventDefault={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_end.svelte b/apps-lib/src/lib/components/trellis_end.svelte
@@ -1,30 +0,0 @@
-<script lang="ts">
- import { Glyph, type ITrellisBasisTouchEnd } from "$lib";
- import type { ThemeLayer } from "@radroots/theme";
-
- export let basis: ITrellisBasisTouchEnd;
- export let layer: ThemeLayer;
- export let hide_active: boolean;
-</script>
-
-<div
- class={`absolute top-0 right-0 h-full w-max flex flex-row justify-center items-center`}
->
- <button
- class={`flex pr-3`}
- on:click|preventDefault={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+`,
- weight: `bold`,
- ...basis.glyph,
- }}
- />
- {/if}
- </button>
-</div>
diff --git a/apps-lib/src/lib/components/trellis_input.svelte b/apps-lib/src/lib/components/trellis_input.svelte
@@ -1,82 +0,0 @@
-<script lang="ts">
- import {
- fmt_cl,
- fmt_trellis,
- Glyph,
- InputElement,
- Loading,
- type ITrellisBasisInput,
- } from "$lib";
- import type { ThemeLayer } from "@radroots/theme";
-
- export let basis: ITrellisBasisInput;
- export let layer: ThemeLayer;
- export let hide_border_t: boolean;
- export let hide_border_b: boolean;
-</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`}
- >
- <InputElement
- 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`}>
- <Loading
- basis={{
- dim: `glyph-send-button`,
- blades: 8,
- classes: `text-layer-${layer}-glyph el-re`,
- }}
- />
- </div>
- {:else}
- <button
- class={`group fade-in-long`}
- on:click|preventDefault={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_line.svelte b/apps-lib/src/lib/components/trellis_line.svelte
@@ -1,40 +0,0 @@
-<script lang="ts">
- import { fmt_trellis, Loading, type CallbackPromiseGeneric } from "$lib";
- import type { ThemeLayer } from "@radroots/theme";
-
- export let loading: boolean = false;
- export let layer: ThemeLayer;
- export let callback: CallbackPromiseGeneric<MouseEvent>;
- export let hide_border_t: boolean;
- export let hide_border_b: boolean;
-</script>
-
-<button
- class={`flex flex-row flex-grow overflow-x-hidden`}
- on:click={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`}
- >
- <Loading 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`}
- >
- <slot />
- </div>
- <slot name="end" />
- </div>
- {/if}
- </div>
-</button>
diff --git a/apps-lib/src/lib/components/trellis_offset.svelte b/apps-lib/src/lib/components/trellis_offset.svelte
@@ -1,70 +0,0 @@
-<script lang="ts">
- import {
- Fill,
- fmt_cl,
- Glyph,
- GlyphCircle,
- Loading,
- type ITrellisBasisOffset,
- type ITrellisBasisOffsetMod,
- } from "$lib";
- import type { ThemeLayer } from "@radroots/theme";
-
- export let basis: ITrellisBasisOffset | undefined = undefined;
- export let layer: ThemeLayer;
-
- let mod: ITrellisBasisOffsetMod = `sm`;
- $: mod = basis && 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]`}>
- <Fill />
- </div>
- {:else if mod === `glyph`}
- <div class={`flex flex-row pr-[2px]`}>
- <div class={`${fmt_cl(``)} flex flex-row h-full w-trellisOffset`}>
- <Fill />
- </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]`}
- on:click|preventDefault={async (ev) => {
- if (mod.loading) return;
- else if (typeof basis !== `boolean` && basis?.callback)
- await basis.callback(ev);
- }}
- >
- {#if mod.loading}
- <Loading 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_row_display_value.svelte b/apps-lib/src/lib/components/trellis_row_display_value.svelte
@@ -1,41 +0,0 @@
-<script lang="ts">
- import {
- fmt_cl,
- get_label_classes_kind,
- Glyph,
- type ITrellisKindDisplayValue,
- } from "$lib";
- import type { ThemeLayer } from "@radroots/theme";
-
- export let basis: ITrellisKindDisplayValue;
- export let layer: ThemeLayer;
- export let hide_active: boolean;
-</script>
-
-<button
- class={`z-10 flex flex-grow justify-end`}
- on:click|stopPropagation={async (ev) => {
- 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,
- weight: `bold`,
- 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_row_label.svelte b/apps-lib/src/lib/components/trellis_row_label.svelte
@@ -1,60 +0,0 @@
-<script lang="ts">
- import {
- ButtonGlyph,
- fmt_cl,
- get_label_classes_kind,
- type ILabelTupFields,
- } from "$lib";
- import type { ThemeLayer } from "@radroots/theme";
-
- export let basis: ILabelTupFields;
- export let layer: ThemeLayer;
- export let hide_active: boolean;
-</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`}
- >
- <ButtonGlyph 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}
- <ButtonGlyph 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_select.svelte b/apps-lib/src/lib/components/trellis_select.svelte
@@ -1,55 +0,0 @@
-<script lang="ts">
- import {
- Loading,
- SelectMenu,
- TrellisEnd,
- TrellisLine,
- TrellisRowDisplayValue,
- TrellisRowLabel,
- type ITrellisBasisSelect,
- } from "$lib";
- import type { ThemeLayer } from "@radroots/theme";
-
- export let basis: ITrellisBasisSelect;
- export let layer: ThemeLayer;
- export let hide_border_t: boolean;
- export let hide_border_b: boolean;
- export let hide_active: boolean;
-
- $: value = basis.el.value;
- $: loading = typeof basis?.loading === `boolean` ? basis.loading : false;
-</script>
-
-<TrellisLine
- {layer}
- {loading}
- {hide_border_b}
- {hide_border_t}
- callback={basis.callback}
->
- <TrellisRowLabel basis={basis.label} {layer} {hide_active} />
- {#if basis.display}
- <SelectMenu {value} basis={basis.el}>
- <svelte:fragment slot="element">
- {#if basis.display.loading}
- <div
- class={`flex flex-row h-full w-full justify-end items-center`}
- >
- <Loading basis={{ dim: `sm` }} />
- </div>
- {:else}
- <TrellisRowDisplayValue
- basis={{ ...basis.display }}
- {layer}
- {hide_active}
- />
- {/if}
- </svelte:fragment>
- </SelectMenu>
- {/if}
- <div slot="end">
- {#if basis.end && !basis.display.loading}
- <TrellisEnd basis={basis.end} {layer} {hide_active} />
- {/if}
- </div>
-</TrellisLine>
diff --git a/apps-lib/src/lib/components/trellis_title.svelte b/apps-lib/src/lib/components/trellis_title.svelte
@@ -1,62 +0,0 @@
-<script lang="ts">
- import { Fill, fmt_cl, Glyph, type ITrellisTitle, LabelSwap } from "$lib";
- import type { ThemeLayer } from "@radroots/theme";
-
- export let basis: ITrellisTitle;
- export let layer: ThemeLayer = 0;
-
- $: mod = basis && 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]` : ``}`}
- on:click|preventDefault={async () => {
- if (basis && basis.callback) await basis.callback();
- }}
- >
- {#if basis.value === true}
- <Fill />
- {: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`}
- on:click|preventDefault={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_touch.svelte b/apps-lib/src/lib/components/trellis_touch.svelte
@@ -1,34 +0,0 @@
-<script lang="ts">
- import {
- TrellisEnd,
- TrellisRowDisplayValue,
- TrellisRowLabel,
- type ITrellisBasisTouch,
- } from "$lib";
- import type { ThemeLayer } from "@radroots/theme";
- import TrellisLine from "./trellis_line.svelte";
-
- export let basis: ITrellisBasisTouch;
- export let layer: ThemeLayer;
- export let hide_border_t: boolean;
- export let hide_border_b: boolean;
- export let hide_active: boolean;
-</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}
- <svelte:fragment slot="end">
- {#if basis.end}
- <TrellisEnd basis={basis.end} {layer} {hide_active} />
- {/if}
- </svelte:fragment>
-</TrellisLine>
diff --git a/apps-lib/src/lib/el/divider.svelte b/apps-lib/src/lib/el/divider.svelte
@@ -1,15 +0,0 @@
-<script lang="ts">
- import { Fill, fmt_cl } from "$lib";
-
- export let basis:
- | {
- classes?: string;
- }
- | undefined = undefined;
-</script>
-
-<div
- class={`${fmt_cl(basis.classes)} flex flex-row h-[1px] w-full justify-start items-center bg-layer-1-edge`}
->
- <Fill />
-</div>
diff --git a/apps-lib/src/lib/el/fade.svelte b/apps-lib/src/lib/el/fade.svelte
@@ -1,11 +0,0 @@
-<script lang="ts">
- import { fade } from "svelte/transition";
-</script>
-
-<div
- class={`flex flex-row justify-start items-center`}
- in:fade={{ duration: 200 }}
- out:fade={{ delay: 50, duration: 200 }}
->
- <slot />
-</div>
diff --git a/apps-lib/src/lib/el/fill_white.svelte b/apps-lib/src/lib/el/fill_white.svelte
@@ -1,9 +0,0 @@
-<script lang="ts">
- import { Fill } from "$lib";
-</script>
-
-<div
- class={`absolute inset-0 flex flex-row justify-start items-center bg-gray-800/10`}
->
- <Fill />
-</div>
diff --git a/apps-lib/src/lib/el/glyph_circle.svelte b/apps-lib/src/lib/el/glyph_circle.svelte
@@ -1,22 +0,0 @@
-<script lang="ts">
- import {
- type IGlyphCircle,
- ButtonGlyph,
- fmt_cl,
- glyph_style_map,
- } from "$lib";
-
- export let basis: IGlyphCircle;
-
- $: styles = 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`}
- >
- <ButtonGlyph basis={basis?.glyph} />
- </div>
-{/if}
diff --git a/apps-lib/src/lib/el/image_blob.svelte b/apps-lib/src/lib/el/image_blob.svelte
@@ -1,43 +0,0 @@
-<script lang="ts">
- import type { IIdOpt } from "$lib";
- import { onDestroy, onMount } from "svelte";
-
- export let basis: IIdOpt & {
- data: Uint8Array | undefined;
- alt?: string;
- };
-
- let img_url = ``;
-
- onMount(async () => {
- try {
- if (!basis.data) return;
- img_url = URL.createObjectURL(
- new Blob([basis.data], {
- type: "image/jpeg",
- }),
- );
- } catch (e) {
- console.log(`(error) image blob `, e);
- }
- });
-
- onDestroy(async () => {
- try {
- URL.revokeObjectURL(img_url);
- } catch (e) {}
- });
-</script>
-
-{#if img_url}
- <img id={basis.id || null} src={img_url} alt={basis.alt || null} />
-{/if}
-
-<style>
- img {
- height: 100%;
- width: 100%;
- object-fit: cover;
- display: block;
- }
-</style>
diff --git a/apps-lib/src/lib/el/image_path.svelte b/apps-lib/src/lib/el/image_path.svelte
@@ -1,49 +0,0 @@
-<!-- svelte-ignore a11y-click-events-have-key-events -->
-<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
-<script lang="ts">
- import type { ICbGOpt, IClOpt, IIdOpt } from "$lib/types/client";
- import { fmt_cl } from "$lib/utils/client";
- import { onMount } from "svelte";
-
- export let basis: IClOpt &
- ICbGOpt<
- MouseEvent & {
- currentTarget: EventTarget & HTMLImageElement;
- }
- > &
- IIdOpt & {
- path?: string;
- alt?: string;
- };
-
- let img_src = ``;
-
- onMount(async () => {
- try {
- if (basis.path) img_src = basis.path;
- } catch (e) {
- } finally {
- }
- });
-</script>
-
-{#if img_src}
- <img
- id={basis?.id || null}
- class={`${fmt_cl(basis?.classes)}`}
- src={img_src}
- alt={basis?.alt || null}
- on:click|stopPropagation={async (ev) => {
- if (basis?.callback) await basis.callback(ev);
- }}
- />
-{/if}
-
-<style>
- img {
- height: 100%;
- width: 100%;
- object-fit: cover;
- display: block;
- }
-</style>
diff --git a/apps-lib/src/lib/el/input_element.svelte b/apps-lib/src/lib/el/input_element.svelte
@@ -11,7 +11,7 @@
let el: HTMLInputElement | null = null;
export let value: string = ``;
- export let basis: IInputElement;
+ export let basis: IInputElement<string>;
onMount(async () => {
try {
@@ -47,7 +47,7 @@
if (kv_val && el) el.value = kv_val;
else await kv.set(basis?.id, ``);
}
- if (basis?.on_mount) await basis?.on_mount({ el });
+ if (basis?.callback_mount) await basis?.callback_mount({ el });
} catch (e) {
console.log(`(error) kv_init `, e);
}
diff --git a/apps-lib/src/lib/el/label_swap.svelte b/apps-lib/src/lib/el/label_swap.svelte
@@ -1,32 +0,0 @@
-<!-- svelte-ignore a11y-label-has-associated-control -->
-<script lang="ts">
- import { fmt_cl, type ILabelSwap, type ILyOpt } from "$lib";
-
- export let el_swap: HTMLLabelElement | null = null;
- export let basis: ILabelSwap & ILyOpt;
- $: basis = basis;
-
- $: layer = basis?.layer ? basis.layer : 1;
-</script>
-
-<div class={`flex flex-row justify-start items-center`}>
- <label
- bind:this={el_swap}
- 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/el/load_symbol.svelte b/apps-lib/src/lib/el/load_symbol.svelte
@@ -0,0 +1,64 @@
+<script lang="ts">
+ import { type ILoadSymbol, loading_style_map } from "$lib";
+
+ export let basis: ILoadSymbol | undefined = undefined;
+ $: basis = basis;
+
+ $: styles = basis?.dim
+ ? loading_style_map.get(basis?.dim)
+ : loading_style_map.get("sm");
+ $: num_blades = 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/el/loading.svelte b/apps-lib/src/lib/el/loading.svelte
@@ -1,64 +0,0 @@
-<script lang="ts">
- import { type ILoading, loading_style_map } from "$lib";
-
- export let basis: ILoading | undefined = undefined;
- $: basis = basis;
-
- $: styles = basis?.dim
- ? loading_style_map.get(basis?.dim)
- : loading_style_map.get("sm");
- $: num_blades = 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
- class={`${num_blades === 12 ? `spinner12-blade` : `spinner8-blade`}`}
- />
- <div
- class={`${num_blades === 12 ? `spinner12-blade` : `spinner8-blade`}`}
- />
- <div
- class={`${num_blades === 12 ? `spinner12-blade` : `spinner8-blade`}`}
- />
- <div
- class={`${num_blades === 12 ? `spinner12-blade` : `spinner8-blade`}`}
- />
- <div
- class={`${num_blades === 12 ? `spinner12-blade` : `spinner8-blade`}`}
- />
- <div
- class={`${num_blades === 12 ? `spinner12-blade` : `spinner8-blade`}`}
- />
- <div
- class={`${num_blades === 12 ? `spinner12-blade` : `spinner8-blade`}`}
- />
- {#if num_blades === 12}
- <div
- class={`${num_blades === 12 ? `spinner12-blade` : `spinner8-blade`}`}
- />
- <div
- class={`${num_blades === 12 ? `spinner12-blade` : `spinner8-blade`}`}
- />
- <div
- class={`${num_blades === 12 ? `spinner12-blade` : `spinner8-blade`}`}
- />
- <div
- class={`${num_blades === 12 ? `spinner12-blade` : `spinner8-blade`}`}
- />
- <div
- class={`${num_blades === 12 ? `spinner12-blade` : `spinner8-blade`}`}
- />
- <div
- class={`${num_blades === 12 ? `spinner12-blade` : `spinner8-blade`}`}
- />
- {/if}
- </div>
-</div>
diff --git a/apps-lib/src/lib/el/select_element.svelte b/apps-lib/src/lib/el/select_element.svelte
@@ -1,111 +0,0 @@
-<script lang="ts">
- import { fmt_cl, Glyph, kv, parse_layer, type ISelectElement } from "$lib";
- import { onMount } from "svelte";
-
- let el: HTMLSelectElement | null = null;
-
- export let value: string;
- export let basis: ISelectElement;
-
- $: basis = basis;
- $: id = basis?.id ? basis?.id : null;
- $: layer =
- typeof basis?.layer === `boolean`
- ? parse_layer(0)
- : parse_layer(basis.layer);
- $: classes_layer =
- typeof basis?.layer === `boolean`
- ? ``
- : !value
- ? `text-layer-${layer}-glyph_pl`
- : `text-layer-${layer}-glyph_d`;
-
- onMount(async () => {
- try {
- if (basis.id && basis.sync_init) {
- const sync_val = await kv.get(basis.id);
- await kv.set(basis.id, sync_val || ``);
- }
- } catch (e) {
- } finally {
- }
- });
-
- $: if (basis?.id && basis?.sync) {
- (async () => {
- try {
- await kv.set(basis?.id, value);
- } catch (e) {}
- })();
- }
-
- 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) await kv.set(basis?.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 justify-center items-center`}>
- <Glyph
- basis={{
- key: `caret-up-down`,
- dim: `xs`,
- weight: `bold`,
- classes: `text-layer-${layer}-glyph translate-y-[1px]`,
- }}
- />
- </div>
-{/if}
-<select
- bind:this={el}
- bind:value
- on:change={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 justify-center items-center`}>
- <Glyph
- basis={{
- key: `caret-up-down`,
- dim: `xs`,
- weight: `bold`,
- classes: `text-layer-${layer}-glyph`,
- }}
- />
- </div>
-{/if}
diff --git a/apps-lib/src/lib/el/select_menu.svelte b/apps-lib/src/lib/el/select_menu.svelte
@@ -1,64 +0,0 @@
-<script lang="ts">
- import { fmt_cl, parse_layer, type ISelectElement } from "$lib";
-
- export let value: string;
- export let basis: ISelectElement;
- $: basis = basis;
-
- let el_wrap: HTMLDivElement | null = null;
- let el_select: HTMLSelectElement | null = null;
- $: layer =
- typeof basis?.layer === `boolean`
- ? parse_layer(0)
- : parse_layer(basis.layer);
- $: classes_layer =
- 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
- on:change={async (e) => {
- const opt = basis.options
- .map((i) => i.entries)
- .reduce((_, j) => j, [])
- .find((k) => 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>
- <div class={`z-10 flex flex-row h-full w-full`}>
- <slot name="element" />
- </div>
-</div>
diff --git a/apps-lib/src/lib/el/textarea_element.svelte b/apps-lib/src/lib/el/textarea_element.svelte
@@ -1,97 +0,0 @@
-<script lang="ts">
- import {
- type ITextAreaElement,
- fmt_cl,
- fmt_textarea_value,
- kv,
- parse_layer,
- value_constrain_textarea,
- } from "$lib";
- import { onMount } from "svelte";
-
- let el: HTMLTextAreaElement | null = null;
-
- export let value: string = ``;
- export let basis: ITextAreaElement;
- $: basis = basis;
-
- $: id = basis.id ? basis.id : null;
- $: layer =
- typeof basis.layer === `boolean` ? 0 : parse_layer(basis.layer, 1); //@todo
-
- onMount(async () => {
- try {
- await kv_init();
- } catch (e) {}
- });
-
- $: if (basis?.id && basis?.sync && value) {
- (async () => {
- try {
- await kv.set(basis?.id, value);
- } catch (e) {}
- })();
- }
-
- const kv_init = async (): Promise<void> => {
- try {
- if (!basis?.id) return;
- if (basis?.sync) {
- const kv_val = await kv.get(basis?.id);
- if (kv_val && el) el.value = fmt_textarea_value(kv_val);
- else await kv.set(basis?.id, ``);
- }
- if (basis?.on_mount) await basis?.on_mount({ el });
- } catch (e) {
- console.log(`(error) kv_init `, e);
- }
- };
-
- 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.validate_keypress
- ) {
- //@todo set styles
- }
- pass = basis?.field.validate.test(val);
- }
- if (basis?.sync) await kv.set(basis?.id, 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
- on:input={async ({ currentTarget: el }) => {
- await handle_on_input(el);
- }}
- on:blur={async ({ currentTarget: el }) => {
- if (basis.callback_blur) await basis.callback_blur({ el });
- }}
- on:focus={async ({ currentTarget: el }) => {
- if (basis.callback_focus) await basis.callback_focus({ el });
- }}
- on:keydown={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 w-full bg-layer-${layer}-surface text-layer-${layer}-glyph placeholder:text-layer-${layer}-glyph_pl caret-layer-${layer}-glyph`}
- placeholder={basis.placeholder || ``}
-/>
diff --git a/apps-lib/src/lib/el/toast.svelte b/apps-lib/src/lib/el/toast.svelte
@@ -1,55 +0,0 @@
-<script lang="ts">
- import {
- app_layout,
- fmt_cl,
- get_layout,
- Glyph,
- parse_layer,
- toast_layout_map,
- toast_style_map,
- type IToast,
- type IToastKind,
- } from "$lib";
-
- export let basis: IToast;
- $: basis = basis;
-
- let styles: IToastKind[] = basis.styles || [`simple`];
- $: styles = styles;
- $: layer = basis.layer ? parse_layer(basis.layer) : 1;
- $: layout = get_layout($app_layout);
-</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`,
- weight: `regular`,
- 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/index.ts b/apps-lib/src/lib/index.ts
@@ -1,84 +1,33 @@
-export * from "./locales/i18n";
-export * from "./types/trellis";
-export * from "./types/components";
-export * from "./types/client";
-export * from "./types/conf";
-export * from "./types/el";
-export * from "./types/nostr";
+export { default as ButtonLayout } from "./components/button_layout.svelte";
+export { default as ButtonLayoutPair } from "./components/button_layout_pair.svelte";
+export { default as EntryLine } from "./components/entry_line.svelte";
+export { default as EntryWrap } from "./components/entry_wrap.svelte";
+export { default as LabelDisplay } from "./components/label_display.svelte";
+export { default as LayoutRoot } from "./components/layout_root.svelte";
+export { default as LayoutView } from "./components/layout_view.svelte";
+export { default as LayoutWindow } from "./components/layout_window.svelte";
+export { default as LogoCircle } from "./components/logo_circle.svelte";
+export { default as LogoCircleSm } from "./components/logo_circle_sm.svelte";
+export { default as OverlayLoading } from "./components/overlay_loading.svelte";
+export { default as OverlaySplash } from "./components/overlay_splash.svelte";
export { default as Blur } from "./el/blur.svelte";
-export { default as SelectElement } from "./el/select_element.svelte";
-export { default as Toast } from "./el/toast.svelte";
-export { default as ImagePath } from "./el/image_path.svelte";
-export { default as GlyphCircle } from "./el/glyph_circle.svelte";
-export { default as TextareaElement } from "./el/textarea_element.svelte";
export { default as CssStatic } from "./el/css_static.svelte";
-export { default as Divider } from "./el/divider.svelte";
-export { default as LabelSwap } from "./el/label_swap.svelte";
-export { default as ImageBlob } from "./el/image_blob.svelte";
-export { default as SelectMenu } from "./el/select_menu.svelte";
-export { default as Glyph } from "./el/glyph.svelte";
export { default as CssStyles } from "./el/css_styles.svelte";
-export { default as Loading } from "./el/loading.svelte";
-export { default as Fade } from "./el/fade.svelte";
-export { default as InputElement } from "./el/input_element.svelte";
export { default as Fill } from "./el/fill.svelte";
-export { default as FillWhite } from "./el/fill_white.svelte";
-export * from "./stores/ndk";
+export { default as Glyph } from "./el/glyph.svelte";
+export { default as InputElement } from "./el/input_element.svelte";
+export { default as LoadSymbol } from "./el/load_symbol.svelte";
+export * from "./stores/app";
export * from "./stores/client";
+export * from "./stores/ndk";
+export * from "./types/app";
+export * from "./types/el";
+export * from "./types/interface";
+export * from "./utils/app";
+export * from "./utils/carousel";
+export * from "./utils/document";
+export * from "./utils/i18n";
+export * from "./utils/kv";
export * from "./utils/routes";
export * from "./utils/styles";
-export * from "./utils/document";
-export * from "./utils/carousel";
-export * from "./utils/numbers";
-export * from "./utils/client";
-export * from "./utils/conf";
-export * from "./utils/time";
-export * from "./utils/geo";
-export { default as TrellisLine } from "./components/trellis_line.svelte";
-export { default as EnvelopeLower } from "./components/envelope_lower.svelte";
-export { default as TrellisSelect } from "./components/trellis_select.svelte";
-export { default as TrellisInput } from "./components/trellis_input.svelte";
-export { default as InsetWhite } from "./components/inset_white.svelte";
-export { default as TrellisEnd } from "./components/trellis_end.svelte";
-export { default as ButtonGlyph } from "./components/button_glyph.svelte";
-export { default as Envelope } from "./components/envelope.svelte";
-export { default as DisplayLine } from "./components/display_line.svelte";
-export { default as GlyphTitleSelectLabel } from "./components/glyph_title_select_label.svelte";
-export { default as LayoutTrellis } from "./components/layout_trellis.svelte";
-export { default as Tabs } from "./components/tabs.svelte";
-export { default as ButtonArrow } from "./components/button_arrow.svelte";
-export { default as ButtonOptsDisplay } from "./components/button_opts_display.svelte";
-export { default as TrellisTitle } from "./components/trellis_title.svelte";
-export { default as TrellisTouch } from "./components/trellis_touch.svelte";
-export { default as Trellis } from "./components/trellis.svelte";
-export { default as Controls } from "./components/controls.svelte";
-export { default as ButtonOptsStatic } from "./components/button_opts_static.svelte";
-export { default as EntryLine } from "./components/entry_line.svelte";
-export { default as SplashScreen } from "./components/splash_screen.svelte";
-export { default as TrellisRowDisplayValue } from "./components/trellis_row_display_value.svelte";
-export { default as EnvelopeButtons } from "./components/envelope_buttons.svelte";
-export { default as LayoutWindow } from "./components/layout_window.svelte";
-export { default as EntryMultiline } from "./components/entry_multiline.svelte";
-export { default as EntryWrap } from "./components/entry_wrap.svelte";
-export { default as ButtonLayout } from "./components/button_layout.svelte";
-export { default as LayoutTrellisLine } from "./components/layout_trellis_line.svelte";
-export { default as PageHeader } from "./components/page_header.svelte";
-export { default as NotifyGlyph } from "./components/notify_glyph.svelte";
-export { default as TrellisDefaultLabel } from "./components/trellis_default_label.svelte";
-export { default as LayoutArea } from "./components/layout_area.svelte";
-export { default as BadgeInfoKey } from "./components/badge_info_key.svelte";
-export { default as EnvelopeTitled } from "./components/envelope_titled.svelte";
-export { default as ButtonLoading } from "./components/button_loading.svelte";
-export { default as NavToolbar } from "./components/nav_toolbar.svelte";
-export { default as TrellisOffset } from "./components/trellis_offset.svelte";
-export { default as LogoCircleSm } from "./components/logo_circle_sm.svelte";
-export { default as EntrySelect } from "./components/entry_select.svelte";
-export { default as Nav } from "./components/nav.svelte";
-export { default as ButtonLayoutPair } from "./components/button_layout_pair.svelte";
-export { default as TabsFloat } from "./components/tabs_float.svelte";
-export { default as LoadingView } from "./components/loading_view.svelte";
-export { default as NavOption } from "./components/nav_option.svelte";
-export { default as LogoCircle } from "./components/logo_circle.svelte";
-export { default as TrellisRowLabel } from "./components/trellis_row_label.svelte";
-export { default as ButtonGlyphSimple } from "./components/button_glyph_simple.svelte";
-export { default as LayoutView } from "./components/layout_view.svelte";
+
diff --git a/apps-lib/src/lib/locales/en/app.json b/apps-lib/src/lib/locales/en/app.json
@@ -1,24 +0,0 @@
-{
- "calendar": {
- "weekday": {
- "0": "Sunday",
- "1": "Monday",
- "2": "Tuesday",
- "3": "Wednesday",
- "4": "Thursday",
- "5": "Friday",
- "6": "Saturday"
- }
- },
- "cfg": {
- "init": {
- "greeting": "Welcome to Radroots!",
- "message": "Your device will be configured by the setup wizard.",
- "notification": {
- "no_profile_name": "Your profile will be created without a name. You can change this later in Settings > Profile",
- "welcome": "Welcome! Your device was configured. To view or change your configuration go to Settings > Configuration"
- }
- }
- },
- "name": "Radroots"
-}
-\ No newline at end of file
diff --git a/apps-lib/src/lib/locales/en/common.json b/apps-lib/src/lib/locales/en/common.json
@@ -1,169 +0,0 @@
-{
- "accept": "Accept",
- "activation": "Activation",
- "active": "Active",
- "add": "Add",
- "add_current_location": "Add current location",
- "add_map_location": "Add map location",
- "add_new": "Add new",
- "add_new_location": "Add new location",
- "agree": "Agree",
- "all_accounts": "All accounts",
- "area": "Area",
- "at": "At",
- "authenticated": "Authenticated",
- "available_balance": "Available balance",
- "back": "Back",
- "bag": "Bag",
- "bags": "Bags",
- "bank_account": "Bank account",
- "banner_photo": "Banner photo",
- "bio": "Bio",
- "business_name": "Business name",
- "cancel": "Cancel",
- "choose_a_profile_name": "Choose a profile name",
- "climate": "Climate",
- "close": "Close",
- "color_mode": "Color mode",
- "complete": "Complete",
- "configure": "Configure",
- "configure_your_device": "Configure your device",
- "connect": "Connect",
- "connected": "Connected",
- "connection": "Connection",
- "continue": "Continue",
- "coordinates": "Coordinates",
- "current_location": "Current location",
- "dark": "Dark",
- "date_created": "Date created",
- "date_modified": "Date modified",
- "delete": "Delete",
- "description": "Description",
- "details": "Details",
- "device": "Device",
- "disagree": "Disagree",
- "discard": "Discard",
- "disconnect": "Disconnect",
- "do_you_want_to_continue_q": "Do you want to continue?",
- "done": "Done",
- "edit": "Edit",
- "elevation": "Elevation",
- "end_date": "End date",
- "endpoint": "Endpoint",
- "estate": "Estate",
- "failure_to_process_the_request": "Failure to process the request",
- "farm": "Farm",
- "farm_land": "Farm land",
- "file_name": "File name",
- "file_size": "File size",
- "filters": "Filters",
- "from": "From",
- "general": "General",
- "hex": "Hex",
- "highest_price": "Highest price",
- "home": "Home",
- "inbox": "Inbox",
- "inflows": "Inflows",
- "items": "Items",
- "key": "Key",
- "keypair": "Keypair",
- "keys": "Keys",
- "label": "Label",
- "land_area": "Land area",
- "land_plot": "Land plot",
- "land_plots": "Land plots",
- "latitude": "Latitude",
- "light": "Light",
- "list": "List",
- "listing": "Listing",
- "location": "Location",
- "locations": "Locations",
- "longitude": "Longitude",
- "lot": "Lot",
- "lot_name": "Lot name",
- "lowest_price": "Lowest price",
- "make_primary": "Make primary",
- "map": "Map",
- "market": "Market",
- "message": "Message",
- "messages": "Messages",
- "month": "Month",
- "month_to_date": "Month to date",
- "name": "Name",
- "name_of_farm_or_estate": "Name of farm or estate",
- "new": "New",
- "no": "No",
- "no_items_to_display": "No items to display",
- "no_locations_saved": "No locations saved",
- "nostr": "Nostr",
- "not_connected": "Not connected",
- "notifications": "Notifications",
- "npub": "Npub",
- "nsec": "Nsec",
- "optional": "Optional",
- "options": "Options",
- "options_list": "Options list",
- "order": "Order",
- "origin": "Origin",
- "other": "Other",
- "outflows": "Outflows",
- "overview": "Overview",
- "page": "Page",
- "per": "Per",
- "personal": "Personal",
- "photo": "Photo",
- "photo_hosting": "Photo hosting",
- "photos": "Photos",
- "post": "Post",
- "preview": "Preview",
- "price": "Price",
- "process": "Process",
- "product": "Product",
- "product_location": "Product location",
- "product_name": "Product name",
- "products": "Products",
- "profile": "Profile",
- "profile_name": "Profile name",
- "profile_photo": "Profile photo",
- "profiles": "Profiles",
- "public_key": "Public key",
- "publish": "Publish",
- "quantity": "Quantity",
- "quit": "Quit",
- "reading": "Reading",
- "relay": "Relay",
- "relays": "Relays",
- "reset": "Reset",
- "return": "Return",
- "review": "Review",
- "save": "Save",
- "search": "Search",
- "secret_key": "Secret key",
- "settings": "Settings",
- "setup": "Setup",
- "setup_for_farmer": "Setup for Farmer",
- "skip": "Skip",
- "socials": "Socials",
- "soil": "Soil",
- "start_date": "Start date",
- "status": "Status",
- "subject": "Subject",
- "submit": "Submit",
- "summary": "Summary",
- "terms_of_use_agreement": "Terms of Use agreement",
- "title": "Title",
- "to": "To",
- "unlock": "Unlock",
- "update": "Update",
- "upload_url": "Upload url",
- "url": "url",
- "username": "Username",
- "using_public_key": "Using public key",
- "value": "Value",
- "view": "View",
- "wallet": "Wallet",
- "website": "Website",
- "year": "Year",
- "yes": "Yes",
- "your_name": "Your name"
-}
-\ No newline at end of file
diff --git a/apps-lib/src/lib/locales/en/currency.json b/apps-lib/src/lib/locales/en/currency.json
@@ -1,12 +0,0 @@
-{
- "eur": {
- "name": "Euro",
- "name_short": "Euro",
- "symbol": "€"
- },
- "usd": {
- "name": "United States Dollar",
- "name_short": "U.S. Dollar",
- "symbol": "$"
- }
-}
-\ No newline at end of file
diff --git a/apps-lib/src/lib/locales/en/error.json b/apps-lib/src/lib/locales/en/error.json
@@ -1,34 +0,0 @@
-{
- "client": {
- "database_read_failure": "There was an error reading the device database",
- "file_path_read_bin_undefined": "The file was not found",
- "keystore_nostr_secretkey": "The nostr key is not configured",
- "network_failure": "The requested resource is not available",
- "nostr_sync_disabled": "Sync to nostr network is disabled. Do you want to activate it?",
- "operation_failure": "There was an error processing the request",
- "page": {
- "load": "There was an error loading the page",
- "status": {
- "404": "The page was not found"
- }
- },
- "request_failure": "The request was not successful",
- "request_unhandled": "The request did not complete",
- "unhandled": "There was an error during your request"
- },
- "device": {
- "configuration_failure": "There was an error configuring the device",
- "public_key_not_derived": "Error deriving public key"
- },
- "geolocation": {
- "request": {
- "current": "Geolocation request failure"
- },
- "result_missing": "The geolocation data is not available"
- },
- "radroots": {
- "account_required_upload": "To post photos using Radroots hosting you must request a profile name registration. There is no cost to register, do you want to continue?",
- "account_required_upload_cancel": "Change Host",
- "account_required_upload_ok": "Ok"
- }
-}
-\ No newline at end of file
diff --git a/apps-lib/src/lib/locales/en/eula.json b/apps-lib/src/lib/locales/en/eula.json
@@ -1,47 +0,0 @@
-{
- "acceptance_of_terms": {
- "body": "By using our Application, you signify your acceptance of this EULA. If you do not agree to this EULA, you may not use our Application.",
- "title": "Acceptance of Terms"
- },
- "changes": {
- "body": "We reserve the right to update or modify this EULA at any time and without prior notice. Your continued use of our application following any changes to this EULA will be deemed to be your acceptance of such changes.",
- "title": "Changes to EULA"
- },
- "consequences_of_violation": {
- "body": "Any violation of this EULA, including the prohibited content and conduct outlined above, may result in the termination of your access to our application.",
- "title": "Consequences of Violation"
- },
- "contact": {
- "body": "If you have any questions about this EULA, please contact us at info@radroots.org",
- "title": "Contact Information"
- },
- "disclaimer": {
- "body": "Our application is provided \"as is\" and \"as available\" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and fitness for a particular purpose. We do not guarantee that our application will be uninterrupted or error-free. In no event shall Radroots Inc. be liable for any damages whatsoever, including but not limited to direct, indirect, special, incidental, or consequential damages, arising out of or in connection with the use or inability to use our application.",
- "title": "Disclaimer of Warranties and Limitation of Liability"
- },
- "error": {
- "required": "The user agreement is required to use the application"
- },
- "introduction": {
- "body": "This End User License Agreement (\"EULA\") is a legal agreement between you and Radroots Inc. for the use of our mobile application Radroots. By installing, accessing, or using our application, you agree to be bound by the terms and conditions of this EULA.",
- "title": "Introduction"
- },
- "prohibited_conduct": {
- "body_li_0_0": "Harasses or bullies others",
- "body_li_0_1": "Impersonates others",
- "body_li_0_2": "Is intended to intimidate or threaten others",
- "body_li_0_3": "Is intended to promote or incite violence",
- "title": "You also agree not to engage in any conduct that:"
- },
- "prohibited_content": {
- "body_0_title": "You agree not to use our application to create, upload, post, send, or store any content that:",
- "body_li_0_0": "Is illegal, infringing, or fraudulent",
- "body_li_0_1": "Is pornographic, obscene, or offensive",
- "body_li_0_2": "Is discriminatory or promotes hate speech",
- "body_li_0_3": "Is harmful to minors",
- "body_li_0_4": "Is intended to harass or bully others",
- "body_li_0_5": "Is intended to impersonate others",
- "title": "Prohibited Content and Conduct"
- },
- "title": "End User License Agreement"
-}
-\ No newline at end of file
diff --git a/apps-lib/src/lib/locales/en/icu.json b/apps-lib/src/lib/locales/en/icu.json
@@ -1,85 +0,0 @@
-{
- "*_as": "{value} as",
- "*_available": "{value} Available",
- "*_copied": "{value} copied",
- "*_description": "{value} description",
- "*_details": "{value} details",
- "*_failure": "{value} failure",
- "*_list": "{value} list",
- "*_month": "{value} month",
- "*_name": "{value} name",
- "*_order": "{value} order",
- "*_price": "{value} price",
- "*_quantity": "{value} quantity",
- "*_sold": "{value} sold",
- "*_summary": "{value} summary",
- "*_the": "{value} the",
- "*_title": "{value} title",
- "*_total": "{value} total",
- "*_your_device": "{value} your device",
- "a_*_is_required": "A {value} is required",
- "add_*": "Add {value}",
- "add_a_*": "Add a {value}",
- "add_existing_*": "Add existing {value}",
- "as_*": "As {value}",
- "choose_*": "Choose {value}",
- "choose_a_*": "Choose a {}",
- "choose_on_*": "Choose on {value}",
- "click_to_*": "Click to {value}",
- "click_to_add_a_*": "Click to add a {value}",
- "configure_*": "Configure {value}",
- "connect_*": "Connect {value}",
- "connected_*": "Connected {value}",
- "create_new_*": "Create new {value}",
- "default_*": "Default {value}",
- "delete_*": "Delete {value}",
- "disconnect_*": "Disconnect {value}",
- "edit_*": "Edit {value}",
- "enter_*": "Enter {value}",
- "enter_*_per_order": "Enter {value} per order",
- "enter_a_*": "Enter a {value}",
- "enter_new_*": "Enter new {value}",
- "enter_the_*": "Enter the {value}",
- "error_loading_*": "Error loading {value}",
- "failure_*": "Failure {value}",
- "failure_saving_*_to_the_database": "Failure saving {value} to the database",
- "go_*": "Go {value}",
- "invalid_*": "Invalid {value}",
- "invalid_*_entry": "Invalid {value} entry",
- "last_*": "Last {value}",
- "listing_*": "Listing {value}",
- "month_of_*": "Month of {value}",
- "name_your_*": "Name your {value}",
- "new_*": "New {value}",
- "no_*": "No {value}",
- "no_*_published": "No {value} published",
- "no_*_selected": "No {value} selected",
- "no_*_to_display": "No {value} to display",
- "nostr_*": "Nostr {value}",
- "post_*": "Post {value}",
- "primary_*": "Primary {value}",
- "reading_*": "Reading {value}",
- "set_as_*": "Set as {value}",
- "show_*": "Show {value}",
- "the_*": "The {value}",
- "the_*_is_available": "The {value} is available",
- "the_*_is_incomplete": "The {value} is incomplete",
- "the_*_is_missing": "The {value} is missing",
- "the_*_is_registered": "The {value} is registered",
- "the_*_is_required": "The {value} is missing",
- "the_current_entry_*_will_be_deleted": "The current entry \"{value}\" will be deleted",
- "the_listing_will_be_created_without_a_*": "The listing will be created without a {value}",
- "there_are_changes_to_the_*": "There are changes to the {value}",
- "there_was_a_failure_while_*": "There was a failure while {value}",
- "this_*": "This {value}",
- "toggle_*": "Toggle {value}",
- "total_*": "Total {value}",
- "unable_to_save_*": "Unable to save {value}",
- "unconnected_*": "Unconnected {value}",
- "uploading_*_photos": "Uploading {value} photos",
- "use_existing_*": "Use existing {value}",
- "valid_*": "Valid {value}",
- "view_*": "View {value}",
- "view_the_*": "View the {value}",
- "your_*": "Your {value}"
-}
-\ No newline at end of file
diff --git a/apps-lib/src/lib/locales/en/legal.json b/apps-lib/src/lib/locales/en/legal.json
@@ -1,5 +0,0 @@
-{
- "eula": {
- "document_name": "Terms of Use agreement"
- }
-}
-\ No newline at end of file
diff --git a/apps-lib/src/lib/locales/en/measurement.json b/apps-lib/src/lib/locales/en/measurement.json
@@ -1,32 +0,0 @@
-{
- "area": {
- "ac": "Acre",
- "ac_ab": "Ac.",
- "ha": "Hectare",
- "ha_ab": "Ha.",
- "m2": "Square metre",
- "m2_ab": "Sq. M."
- },
- "length": {
- "ft": "Foot",
- "ft_ab": "Ft.",
- "m": "Metre",
- "m_ab": "M."
- },
- "mass": {
- "unit": {
- "g": "Gram",
- "g_ab": "g.",
- "g_pl": "Grams",
- "hg": "100 Gram",
- "hg_ab": "100g.",
- "hg_pl": "100 Grams",
- "kg": "Kilogram",
- "kg_ab": "kg.",
- "kg_pl": "Kilograms",
- "lb": "Pound",
- "lb_ab": "lb.",
- "lb_pl": "Pounds"
- }
- }
-}
-\ No newline at end of file
diff --git a/apps-lib/src/lib/locales/en/models.json b/apps-lib/src/lib/locales/en/models.json
@@ -1,333 +0,0 @@
-{
- "location_gcs": {
- "fields": {
- "lat": {
- "label": "Location Latitude"
- },
- "lng": {
- "label": "Location Latitude"
- },
- "geohash": {
- "label": "Location Geohash"
- },
- "kind": {
- "label": "Location Kind"
- },
- "label": {
- "label": "Location Label"
- },
- "area": {
- "label": "Location Area"
- },
- "elevation": {
- "label": "Location Elevation"
- },
- "soil": {
- "label": "Location Soil"
- },
- "climate": {
- "label": "Location Climate"
- },
- "gc_id": {
- "label": "Location Gc Id"
- },
- "gc_name": {
- "label": "Location Gc Name"
- },
- "gc_admin1_id": {
- "label": "Location Gc Admin1 Id"
- },
- "gc_admin1_name": {
- "label": "Location Gc Admin1 Name"
- },
- "gc_country_id": {
- "label": "Location Gc Country Id"
- },
- "gc_country_name": {
- "label": "Location Gc Country Name"
- }
- },
- "schema": {
- "lat.required": "The location latitude is required",
- "lat.min": "The location latitude must be greater than -90",
- "lat.max": "The location latitude must be less than 90",
- "lng.required": "The location latitude is required",
- "lng.min": "The location latitude must be greater than -180",
- "lng.max": "The location latitude must be less than 180",
- "geohash.required": "The location geohash is required",
- "geohash.length": "The location geohash must be 9 characters",
- "kind.required": "The location kind is required",
- "label.type": "The location label is invalid",
- "area.type": "The location area is invalid",
- "area.nonnegative": "The location area nonnegative is incomplete",
- "area.finite": "The location area must be a finite number",
- "elevation.type": "The location elevation is invalid",
- "elevation.int": "The location elevation must be an integer",
- "elevation.nonnegative": "The location elevation nonnegative is incomplete",
- "soil.type": "The location soil is invalid",
- "climate.type": "The location climate is invalid",
- "gc_id.type": "The location gc id is invalid",
- "gc_name.type": "The location gc name is invalid",
- "gc_admin1_id.type": "The location gc admin1 id is invalid",
- "gc_admin1_name.type": "The location gc admin1 name is invalid",
- "gc_country_id.type": "The location gc country id is invalid",
- "gc_country_name.type": "The location gc country name is invalid"
- }
- },
- "log_error": {
- "fields": {
- "error": {
- "label": "Log Error"
- },
- "message": {
- "label": "Log Message"
- },
- "stack_trace": {
- "label": "Log Stack Trace"
- },
- "cause": {
- "label": "Log Cause"
- },
- "app_system": {
- "label": "Log App System"
- },
- "app_version": {
- "label": "Log App Version"
- },
- "nostr_pubkey": {
- "label": "Log Nostr Pubkey"
- },
- "data": {
- "label": "Log Data"
- }
- },
- "schema": {
- "error.required": "The log error is required",
- "message.required": "The log message is required",
- "stack_trace.type": "The log stack trace is invalid",
- "cause.type": "The log cause is invalid",
- "app_system.required": "The log app system is required",
- "app_version.required": "The log app version is required",
- "nostr_pubkey.required": "The log nostr pubkey is required",
- "data.type": "The log data is invalid"
- }
- },
- "media_upload": {
- "fields": {
- "file_path": {
- "label": "File Path"
- },
- "mime_type": {
- "label": "Mime Type"
- },
- "res_base": {
- "label": "Resource Endpoint"
- },
- "res_path": {
- "label": "Resource Path"
- },
- "label": {
- "label": "Label"
- },
- "description": {
- "label": "Description"
- }
- },
- "schema": {
- "file_path.required": "The media file path is required",
- "mime_type.required": "The media mime type is required",
- "res_base.required": "The media resource endpoint is required",
- "res_base.url": "The media resource endpoint is incorrectly formatted",
- "res_base.regex": "The media resource endpoint requires an http protocol",
- "res_path.required": "The media resource path is required",
- "label.type": "The media label is invalid",
- "description.type": "The media description is invalid"
- }
- },
- "nostr_profile": {
- "fields": {
- "public_key": {
- "label": "Profile Public Key"
- },
- "name": {
- "label": "Profile Name"
- },
- "display_name": {
- "label": "Profile Display Name"
- },
- "about": {
- "label": "Profile About"
- },
- "website": {
- "label": "Profile Website"
- },
- "picture": {
- "label": "Profile Picture"
- },
- "banner": {
- "label": "Profile Banner"
- },
- "nip05": {
- "label": "Profile Nip-05"
- },
- "lud06": {
- "label": "Profile Lud-06"
- },
- "lud16": {
- "label": "Profile Lud-16"
- }
- },
- "schema": {
- "public_key.required": "The profile public key is required",
- "public_key.length": "The profile public key must be 64 characters",
- "name.type": "The profile name is invalid",
- "display_name.type": "The profile display name is invalid",
- "about.type": "The profile about is invalid",
- "website.type": "The profile website is invalid",
- "website.url": "The profile website url is incomplete",
- "picture.type": "The profile picture is invalid",
- "picture.url": "The profile picture url is incomplete",
- "banner.type": "The profile banner is invalid",
- "banner.url": "The profile banner url is incomplete",
- "nip05.type": "The profile nip-05 is invalid",
- "nip05.email": "The profile nip-05 is incorrectly formatted",
- "lud06.type": "The profile lud-06 is invalid",
- "lud16.type": "The profile lud-16 is invalid"
- }
- },
- "nostr_relay": {
- "fields": {
- "url": {
- "label": "Relay Endpoint"
- },
- "relay_id": {
- "label": "Relay Id"
- },
- "name": {
- "label": "Relay Name"
- },
- "description": {
- "label": "Relay Description"
- },
- "pubkey": {
- "label": "Administrator"
- },
- "contact": {
- "label": "Administrator Contact"
- },
- "supported_nips": {
- "label": "Supported Nips"
- },
- "software": {
- "label": "Software"
- },
- "version": {
- "label": "Software Version"
- },
- "data": {
- "label": "Additional Information"
- }
- },
- "schema": {
- "url.required": "The relay relay endpoint is required",
- "url.url": "The relay relay endpoint is incorrectly formatted",
- "url.regex": "The relay relay endpoint requires a websocket protocol",
- "relay_id.type": "The relay relay id is invalid",
- "name.type": "The relay name is invalid",
- "description.type": "The relay description is invalid",
- "pubkey.type": "The relay Administrator is invalid",
- "contact.type": "The relay Administrator contact is invalid",
- "supported_nips.type": "The relay supported nips is invalid",
- "software.type": "The relay software is invalid",
- "version.type": "The relay Software version is invalid",
- "data.type": "The relay Additional information is invalid"
- }
- },
- "trade_product": {
- "fields": {
- "key": {
- "label": "Product Kind"
- },
- "category": {
- "label": "Product Category"
- },
- "title": {
- "label": "Product Title"
- },
- "summary": {
- "label": "Product Description"
- },
- "process": {
- "label": "Processing Method"
- },
- "lot": {
- "label": "Product Lot"
- },
- "profile": {
- "label": "Flavor Profile"
- },
- "year": {
- "label": "Production Year"
- },
- "qty_amt": {
- "label": "Quantity Amount"
- },
- "qty_unit": {
- "label": "Quantity Unit"
- },
- "qty_label": {
- "label": "Quantity Name"
- },
- "qty_avail": {
- "label": "Quantity Available"
- },
- "price_amt": {
- "label": "Price Amount"
- },
- "price_currency": {
- "label": "Price Currency"
- },
- "price_qty_amt": {
- "label": "Price Quantity"
- },
- "price_qty_unit": {
- "label": "Price Quantity Unit"
- },
- "notes": {
- "label": "Notes"
- }
- },
- "schema": {
- "key.required": "The product kind is required",
- "category.required": "The product category is required",
- "title.required": "The product title is required",
- "summary.required": "The product description is required",
- "process.required": "The product processing method is required",
- "lot.required": "The product lot is required",
- "lot.min": "The product lot must be more than 1 character",
- "lot.max": "The product lot must be less than 120 characters",
- "profile.required": "The product flavor profile is required",
- "year.required": "The product production year is required",
- "year.int": "The product production year must be an integer",
- "year.positive": "The product production year must be positive",
- "qty_amt.required": "The product quantity amount is required",
- "qty_amt.int": "The product quantity amount must be an integer",
- "qty_amt.positive": "The product quantity amount must be positive",
- "qty_unit.required": "The product quantity unit is required",
- "qty_label.type": "The product quantity name is invalid",
- "qty_avail.type": "The product quantity available is invalid",
- "qty_avail.int": "The product quantity available must be an integer",
- "qty_avail.positive": "The product quantity available must be positive",
- "price_amt.required": "The product price amount is required",
- "price_amt.positive": "The product price amount must be positive",
- "price_amt.finite": "The product price amount must be a finite number",
- "price_currency.required": "The product price currency is required",
- "price_currency.length": "The product price currency must be 3 characters",
- "price_qty_amt.required": "The product price quantity is required",
- "price_qty_amt.int": "The product price quantity must be an integer",
- "price_qty_amt.positive": "The product price quantity must be positive",
- "price_qty_unit.required": "The product price quantity unit is required",
- "notes.type": "The product notes is invalid"
- }
- }
-}
-\ No newline at end of file
diff --git a/apps-lib/src/lib/locales/en/radroots-org.json b/apps-lib/src/lib/locales/en/radroots-org.json
@@ -1,13 +0,0 @@
-{
- "error": {
- "*-model-account-schema-active": "Invalid active specification",
- "*-model-account-schema-nip_05": "Invalid profile name",
- "*-model-account-schema-nostr_relays": "Invalid nostr relays",
- "*-model-account-schema-public_key": "Invalid public key",
- "*-models-account-add-err": "The account could not be created",
- "*-models-account-delete-err": "The account could not be deleted",
- "*-models-account-get-err": "The account could not be found",
- "*-models-account-nip_05-unique": "The profile name is already registered",
- "*-models-account-update-err": "The account could not be updated"
- }
-}
-\ No newline at end of file
diff --git a/apps-lib/src/lib/locales/en/trade.json b/apps-lib/src/lib/locales/en/trade.json
@@ -1,111 +0,0 @@
-{
- "glossary": {
- "lot": "Lot",
- "process": "Process",
- "profile": "Profile"
- },
- "product": {
- "fields": {
- "price_amt": {
- "err_invalid": "Enter the price"
- }
- },
- "key": {
- "cacao": {
- "name": "Cacao",
- "process": {
- "chocolate": "Chocolate",
- "cocoa_butter": "Cocoa Butter",
- "cocoa_powder": "Cocoa Powder",
- "dried": "Dried",
- "fermented": "Fermented",
- "raw": "Raw",
- "roasted": "Roasted"
- }
- },
- "coffee": {
- "name": "Coffee",
- "process": {
- "carbonic_maceration": "Carbonic Maceration",
- "dry": "Dry",
- "honey": "Honey",
- "natural": "Natural",
- "pulped_natural": "Pulped Natural",
- "semi_washed": "Semi-Washed",
- "washed": "Washed",
- "wet_hulled": "Wet-Hulled"
- },
- "profile": {
- "apricot": "Apricot",
- "banana": "Banana",
- "bergamot": "Bergamot",
- "berry": "Berry",
- "black cherry": "Black Cherry",
- "black currant": "Black Currant",
- "black tea": "Black Tea",
- "blueberry": "Blueberry",
- "brown sugar": "Brown Sugar",
- "caramel": "Caramel",
- "cherry": "Cherry",
- "chocolate": "Chocolate",
- "cola": "Cola",
- "cranberry": "Cranberry",
- "ctrius": "Ctrius",
- "dark chocolate": "Dark Chocolate",
- "dried dates": "Dried Dates",
- "dried fig": "Dried Fig",
- "golden raisin": "Golden Raisin",
- "grape": "Grape",
- "grapefruit": "Grapefruit",
- "green apple": "Green Apple",
- "green grape": "Green Grape",
- "green tea": "Green Tea",
- "jasmine honeysuckle": "Jasmine Honeysuckle",
- "lemon": "Lemon",
- "licorice/anise": "Licorice/Anise",
- "lychee": "Lychee",
- "magnolia": "Magnolia",
- "mandarin": "Mandarin",
- "mango": "Mango",
- "maple syrup": "Maple Syrup",
- "marshmallow": "Marshmallow",
- "milk chocolate": "Milk Chocolate",
- "natural": "Natural",
- "nectarine": "Nectarine",
- "nougat": "Nougat",
- "nut": "Nut",
- "orange": "Orange",
- "orange blossom": "Orange Blossom",
- "peach": "Peach",
- "pineapple": "Pineapple",
- "plum": "Plum",
- "prune": "Prune",
- "raisin": "Raisin",
- "raspberry": "Raspberry",
- "red apple": "Red Apple",
- "red currant": "Red Currant",
- "red grape": "Red Grape",
- "roses": "Roses",
- "star fruit": "Star Fruit",
- "stronefruit": "Stronefruit",
- "sugar cane": "Sugar Cane",
- "sweet bread pastry": "Sweet Bread Pastry",
- "tamarind": "Tamarind",
- "tropical fruit": "Tropical Fruit",
- "vanilla": "Vanilla",
- "white grape": "White Grape"
- }
- },
- "maca": {
- "name": "Maca",
- "process": {
- "capsules": "Capsules",
- "gelatinized": "Gelatinized",
- "powdered": "Powdered",
- "raw": "Raw",
- "roasted": "Roasted"
- }
- }
- }
- }
-}
-\ No newline at end of file
diff --git a/apps-lib/src/lib/locales/i18n.ts b/apps-lib/src/lib/locales/i18n.ts
@@ -1,47 +0,0 @@
-import i18n from '@sveltekit-i18n/base';
-import type { Config } from '@sveltekit-i18n/parser-icu';
-import parser from '@sveltekit-i18n/parser-icu';
-import locales_keys from './locales.json';
-
-type Locale = keyof typeof locales_keys;
-
-type LanguageConfig = {
- default?: string;
- value?: string;
-};
-
-const locales_files = [`app`, `common`, `currency`, `error`, `eula`, `icu`, `measurement`, `models`, `radroots-org`, `trade`] as const;
-const translations_keys: Record<Locale, any> = {
- en: { locales_keys },
-};
-export const default_locale: Locale = `en`;
-
-const config: Config<LanguageConfig> = {
- initLocale: default_locale,
- translations: translations_keys,
- parser: parser(),
- loaders: [
- ...Object.keys(translations_keys).map((locale) => locales_files.map(key => ({
- locale,
- key,
- loader: async () => (await import(`./${locale}/${key}.json`)).default
- }))),
- ].flat()
-};
-
-const {
- t: ls,
- loading: translations_loading,
- locales,
- locale,
- translations,
- loadTranslations: load_translations
-} = new i18n(config);
-
-translations_loading.subscribe(async ($loading) => {
- if ($loading) await translations_loading.toPromise();
-});
-
-export {
- load_translations, locale, locales, ls, translations, translations_loading
-};
diff --git a/apps-lib/src/lib/locales/locales.json b/apps-lib/src/lib/locales/locales.json
@@ -1,3 +0,0 @@
-{
- "en": "English"
-}
-\ No newline at end of file
diff --git a/apps-lib/src/lib/stores/app.ts b/apps-lib/src/lib/stores/app.ts
@@ -0,0 +1,20 @@
+import type { AppConfigType, AppLayoutKey, IToast } from "$lib";
+import type { ColorMode, ThemeKey } from "@radroots/theme";
+import { writable } from "svelte/store";
+
+export const app_layout = writable<AppLayoutKey>(`mobile_base`);
+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_win = writable<{ h: number, w: number }>({ h: 0, w: 0 });
+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>(`os`);
+export const app_nostrkey = writable<string>(``);
+export const app_nostr_profiles = writable<string[]>([]);
diff --git a/apps-lib/src/lib/stores/client.ts b/apps-lib/src/lib/stores/client.ts
@@ -1,5 +1,4 @@
-import { type AppConfigType, type AppLayoutKey, type IToast, type NavigationPreviousParam, } from "$lib";
-import type { ColorMode, ThemeKey } from "@radroots/theme";
+import { type NavigationPreviousParam } from "$lib";
import { writable } from "svelte/store";
import { queryParam, queryParameters } from "sveltekit-search-params";
@@ -17,29 +16,12 @@ export const qp_lng = queryParam<string>("lng");
export let kv: Keyva;
if (typeof window !== 'undefined') kv = new Keyva({ name: kv_name });
-export const app_layout = writable<AppLayoutKey>(`mobile_base`);
-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_win = writable<{ h: number, w: number }>({ h: 0, w: 0 });
-export const app_notify = writable<string>(``);
-export const app_toast = writable<IToast | false>(false);
-export const app_submit_route = writable<NavigationPreviousParam | undefined>(undefined);
-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>(`os`);
-export const app_nostr_key = writable<string>(``);
-export const app_nostr_profiles = writable<string[]>([]);
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[]>([]);
+export const nav_prev = writable<NavigationPreviousParam<string>[]>([]);
export const layout_view_cover = writable<boolean>(false);
diff --git a/apps-lib/src/lib/types/app.ts b/apps-lib/src/lib/types/app.ts
@@ -0,0 +1,163 @@
+export type GlyphKey = |
+ `images-square` |
+ `bell` |
+ `columns` |
+ `bold` |
+ `article` |
+ `grid-four` |
+ `link-simple` |
+ `seal-check` |
+ `selection-foreground` |
+ `image-square` |
+ `image-broken` |
+ `funnel` |
+ `users-three` |
+ `note-blank` |
+ `user-circle-plus` |
+ `user-circle` |
+ `receipt` |
+ `invoice` |
+ `note` |
+ `arrow-left` |
+ `arrows-down-up` |
+ `basket` |
+ `arrow-right` |
+ `upload-simple` |
+ `printer` |
+ `download-simple` |
+ `list` |
+ `asterisk` |
+ `asterisk-simple` |
+ `subtitles-slash` |
+ `cardholder` |
+ `globe-x` |
+ `exclamation-mark` |
+ `network-x` |
+ `x-circle` |
+ `address-book-tabs` |
+ `paper-plane-tilt` |
+ `note-pencil` |
+ `share-fat` |
+ `folder` |
+ `trash` |
+ `plus-circle` |
+ `currency-${GlyphKeyCurrency}` |
+ `arrow-down` |
+ `caret-circle-down` |
+ `caret-circle-up` |
+ `shopping-bag-open` |
+ `coffee-bean` |
+ `compass` |
+ `map-pin-simple` |
+ `handbag-simple` |
+ `devices` |
+ `lock-key` |
+ `gear` |
+ `gear-fine` |
+ `bell-simple` |
+ `envelope` |
+ `house-line` |
+ `arrows-left-right` |
+ `list-plus` |
+ `squares-four` |
+ `list-plus` |
+ `app-window` |
+ `circle-notch` |
+ `subtract-square` |
+ `device-tablet-speaker` |
+ `weather-cloud` |
+ `warning` |
+ `circle-notch` |
+ `minus` |
+ `key` |
+ `arrow-u-up-left` |
+ `arrow-counter-clockwise` |
+ `circle` |
+ `check-circle` |
+ `circle-dashed` |
+ `dots-three` |
+ `cards-three` |
+ `lightning` |
+ `cards` |
+ `note-pencil` |
+ `tray` |
+ `calendar-dots` |
+ `notepad` |
+ `network` |
+ `calendar-blank` |
+ `chats-circle` |
+ `plant` |
+ `farm` |
+ `magnifying-glass` |
+ `chat-circle-dots` |
+ `dots-three-outline` |
+ `copy` |
+ `circles-four` |
+ `waveform` |
+ `film-strip` |
+ `arrow-up` |
+ `arrow-circle-up` |
+ `plus` |
+ `funnel-simple` |
+ `user` |
+ `camera` |
+ `check` |
+ `file` |
+ `share-network` |
+ `question` |
+ `minus-circle` |
+ `globe-simple` |
+ `globe` |
+ `warning-circle` |
+ `x` |
+ `info` |
+ `caret-${GeometryCardinalDirection}` |
+ `caret-up-down`;
+export type GlyphKeyCurrency = `dollar` | `eur`;
+
+export type AppConfigType = `farmer` | `personal`
+export type AppLayoutKey = 'mobile_base' | 'mobile_y';
+
+export type CallbackPromiseGeneric<T> = (value: T) => Promise<void>;
+export type CallbackPromiseReturn<T> = () => Promise<T>;
+export type CallbackPromise = () => Promise<void>;
+
+export type ElementCallbackValue = CallbackPromiseGeneric<{ value: string; pass: boolean; }>;
+export type ElementCallbackValueKeydown<T extends HTMLElement> = CallbackPromiseGeneric<{ key: string; key_s: boolean; el: T }>;
+export type ElementCallbackValueBlur<T extends HTMLElement> = CallbackPromiseGeneric<{ el: T }>;
+export type ElementCallbackValueFocus<T extends HTMLElement> = CallbackPromiseGeneric<{ el: T }>;
+export type ElementCallbackMount<T extends HTMLElement> = CallbackPromiseGeneric<{ el: T }>;
+
+export type EntryStyle = `guide` | `line`;
+
+export type GeometryScreenPositionHorizontal = `left` | `center` | `right`;
+export type GeometryScreenPositionVertical = `top` | `center` | `bottom`;
+export type GeometryScreenPosition = `${GeometryScreenPositionVertical}-${GeometryScreenPositionHorizontal}`;
+export type GeometryCardinalDirection = `up` | `down` | `left` | `right`;
+export type GeometryDimension =
+ `xs` |
+ `sm` |
+ `md` |
+ `lg` |
+ `xl`;
+export type GeometryGlyphDimension =
+ | `${GeometryDimension}`
+ | `${GeometryDimension}-`
+ | `${GeometryDimension}--`
+ | `${GeometryDimension}+`;
+
+export type GlyphWeight = `light` | `regular` | `fill` | `bold`; // `thin` `duotone`
+
+export type LoadingBlades = 8 | 12;
+export type LoadingDimension = GeometryDimension | `glyph-send-button`; //@todo remove
+
+export type LayerGlyphBasisKind = `_a` | `_d` | `_pl`;
+
+export type NavigationRouteParamNostrPublicKey = `nostr_pk`;
+export type NavigationRouteParamRecordKey = `rkey`;
+export type NavigationRouteParamId = `id`;
+export type NavigationRouteParamLat = `lat`;
+export type NavigationRouteParamLng = `lng`;
+export type NavigationRouteParamKey = NavigationRouteParamNostrPublicKey | NavigationRouteParamId | NavigationRouteParamRecordKey | NavigationRouteParamLat | NavigationRouteParamLng;
+export type NavigationParamTuple = [NavigationRouteParamKey, string];
+export type NavigationPreviousParam<T extends string> = { route: T, label?: string; params?: NavigationParamTuple[] }
diff --git a/apps-lib/src/lib/types/client.ts b/apps-lib/src/lib/types/client.ts
@@ -1,198 +0,0 @@
-import { type IGlyph, type NavigationRoute } from "$lib";
-import type { ThemeLayer } from "@radroots/theme";
-
-export type AnchorRoute = `/${string}`;
-export type NavigationRouteParamNostrPublicKey = `nostr_pk`;
-export type NavigationRouteParamRecordKey = `rkey`;
-export type NavigationRouteParamId = `id`;
-export type NavigationRouteParamLat = `lat`;
-export type NavigationRouteParamLng = `lng`;
-export type NavigationRouteParamKey = NavigationRouteParamNostrPublicKey | NavigationRouteParamId | NavigationRouteParamRecordKey | NavigationRouteParamLat | NavigationRouteParamLng;
-export type NavigationParamTuple = [NavigationRouteParamKey, string];
-export type NavigationPreviousParam = { route: NavigationRoute, label?: string; params?: NavigationParamTuple[] }
-
-export type GeometryScreenPositionHorizontal = `left` | `center` | `right`;
-export type GeometryScreenPositionVertical = `top` | `center` | `bottom`;
-export type GeometryScreenPosition = `${GeometryScreenPositionVertical}-${GeometryScreenPositionHorizontal}`;
-export type GeometryCardinalDirection = `up` | `down` | `left` | `right`;
-export type GeometryDimension =
- `xs` |
- `sm` |
- `md` |
- `lg` |
- `xl`;
-export type GeometryGlyphDimension =
- | `${GeometryDimension}`
- | `${GeometryDimension}-`
- | `${GeometryDimension}--`
- | `${GeometryDimension}+`;
-
-
-//export type CallbackPromiseGenericReturn<T1, T2> = (value: T1) => Promise<T2>;
-export type CallbackPromiseGeneric<T> = (value: T) => Promise<void>;
-export type CallbackPromiseReturn<T> = () => Promise<T>;
-export type CallbackPromise = () => Promise<void>;
-
-export type IRoute = {
- route: NavigationRoute;
-};
-
-export type IRouteOpt = {
- route?: NavigationRoute;
-};
-
-export type ILoadingOpt = {
- loading?: boolean;
-};
-
-export type ICbGR<T> = ICbG<T> | IRoute
-
-export type IId = {
- id: string;
-};
-
-export type IIdOpt = {
- id?: string;
-};
-
-export type IIdWrapOpt = {
- id_wrap?: string;
-};
-
-export type ICb = {
- callback: CallbackPromise;
-};
-
-export type ICbOpt = {
- callback?: CallbackPromise;
-};
-
-export type ICbG<T> = {
- callback: CallbackPromiseGeneric<T>;
-};
-
-export type ICbGOpt<T> = {
- callback?: CallbackPromiseGeneric<T>;
-};
-
-export type ICbROpt = ICbOpt | IRouteOpt
-
-export type IClWrapOpt = {
- classes_wrap?: string;
-};
-
-export type IClOpt = {
- classes?: string;
-};
-
-export type ILy = {
- layer: ThemeLayer;
-};
-
-export type ILyOpt = {
- layer?: ThemeLayer;
-};
-
-export type ILyTs = {
- layer: ThemeLayer | false;
-};
-
-export type ILyOptTs = {
- layer?: ThemeLayer | false;
-};
-
-export type IGl = {
- glyph: IGlyph;
-}
-
-export type IGlOpt = {
- glyph?: IGlyph;
-}
-
-export type ILabelFieldsOpt = {
- label: {
- value?: string;
- classes?: string;
- };
-};
-
-export type ILabelOptFieldsOpt = {
- label?: {
- value?: string;
- classes?: string;
- };
-};
-
-export type IGlyphFields = {
- value: string;
- classes?: string;
-};
-
-export type ILabel = {
- label: ILableFields;
-};
-
-export type ILabelValue = {
- label: IClOpt & {
- value: string;
- };
-};
-
-
-export type ILabelOpt = {
- label?: ILableFields;
-};
-
-export type ILabelTup = {
- label: ILabelTupFields;
-};
-
-export type ILabelTupFields = {
- left?: ILableFields[];
- right?: ILableFields[];
-};
-
-export type ILableFieldsSwap = {
- toggle: boolean;
- on: IClOpt & {
- value: string;
- },
- off: IClOpt & {
- value: string;
- },
-};
-
-export type ILabelSwap = {
- swap: ILableFieldsSwap;
-}
-
-export type ILableFields = & {
- classes_wrap?: string
- classes?: string;
- kind?: LayerGlyphBasisKind;
- hide_truncate?: boolean;
- hide_active?: boolean;
-} & (
- ({
- value: string;
- } | ILabelSwap)
- | IGl
- );
-
-export type LayerGlyphBasisKind = `_a` | `_d` | `_pl`;
-
-export type LabelFieldKind = `link` | `on` | `shade`;
-
-export type IToastKind = `simple`;
-
-export type IToast = IClOpt &
- ILabel & IGlOpt & {
- styles?: IToastKind[];
- layer?: ThemeLayer;
- position?: GeometryScreenPosition;
- };
-
-export type AppConfigType = `farmer` | `personal`
-export type GeolocationLatitudeFmtOption = 'dms' | 'd' | 'dm';
-
-export type UploadFilePresignedUrl = { url: string; storage_key: string; file_name: string }
-\ No newline at end of file
diff --git a/apps-lib/src/lib/types/components.ts b/apps-lib/src/lib/types/components.ts
@@ -1,134 +0,0 @@
-import type { CallbackPromise, CallbackPromiseGeneric, CallbackPromiseReturn, GlyphKey, GlyphWeight, ICb, ICbG, ICbOpt, IClOpt, IDisabledOpt, IGl, IGlOpt, IGlyph, IIdOpt, IIdWrapOpt, IInputElement, ILabel, ILabelFieldsOpt, ILabelOpt, ILabelOptFieldsOpt, ILabelValue, ILoadingOpt, ILyOpt, ILyOptTs, ISelectElement, ITextAreaElement, NavigationParamTuple, NavigationRoute } from "$lib";
-import type { TransitionConfig } from "svelte/transition";
-
-export type ITabsBasisList = IClOpt & {
- icon: GlyphKey;
- active_weight?: GlyphWeight;
- force_weight?: GlyphWeight
- indicator?: string;
- hide_active?: boolean;
- callback: CallbackPromiseGeneric<number>;
- label?: string;
-};
-
-export type ITabsBasis = IClOpt & {
- list?: ITabsBasisList[];
- blur?: boolean;
- hide_active?: boolean;
-};
-
-export type IFormField = {
- validate: RegExp;
- charset: RegExp;
- validate_keypress?: boolean;
-};
-
-export type IEntryStyle = `guide` | `line`;
-export type IEntryWrap = IClOpt & IIdOpt & ILyOptTs & {
- style?: IEntryStyle;
- style_a?: true;
- no_pad?: true;
- fade?: {
- in?: TransitionConfig;
- out?: TransitionConfig;
- };
-}
-
-export type IEntryLine = ILoadingOpt & {
- wrap?: IEntryWrap;
- el: IInputElement;
- notify_inline?: {
- glyph: GlyphKey | IGlyph;
- };
-};
-
-
-
-export type IEntryMultiLine = {
- wrap?: IEntryWrap;
- el: ITextAreaElement;
- notify_inline?: {
- glyph: GlyphKey | IGlyph;
- };
-}
-
-export type IEntrySelectOption = IDisabledOpt & {
- value: string;
- label?: string;
- selected?: boolean;
-};
-
-export type IEntrySelect = ILoadingOpt & {
- wrap: IEntryWrap;
- el: ISelectElement;
- hide_arrows?: boolean;
- /*IIdOpt & IClOpt & ICbGOpt<string> & {
- label?: string;
- hidden?: boolean;
- sync?: boolean;
- options: IEntrySelectOption[];
- }*/
-};
-
-
-export type IEnvelopeBasis = ILyOpt &
- IClOpt & IEnvelopeKind & {
- visible: boolean;
- close: CallbackPromise;
- transparent?: boolean;
- };
-
-export type IEnvelopeKind = (
- {
- titled: IEnvelopeTitledBasis;
- });
-
-export type IEnvelopeTitledBasis = {
- hide_border?: boolean;
- previous?: ILabelOptFieldsOpt;
- heading?: ILabelOptFieldsOpt;
- submit?: ICb & (ILabelFieldsOpt | IGl) & {
- valid?: boolean;
- }
-};
-
-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 = {
- prev: ICbOpt & ILoadingOpt & {
- label?: string;
- route: NavigationRoute | [NavigationRoute, NavigationParamTuple[]];
- prevent_route?: {
- callback: CallbackPromise;
- };
- kind?: 'arrow'
- };
- title?: ICbOpt & ILabel;
- option?: INavBasisOption;
-};
-
-
-export type IDisplayLine = IIdWrapOpt & IClOpt & ILabelValue & ILyOpt & {
- style?: IEntryStyle
-}
-
-export type IPageHeader = {
- callback_route?: CallbackPromiseReturn<NavigationRoute | undefined>;
- label:
- | string
- | [
- string,
- {
- route: NavigationRoute;
- route_param?: NavigationParamTuple[];
- },
- ];
-};
-\ No newline at end of file
diff --git a/apps-lib/src/lib/types/conf.ts b/apps-lib/src/lib/types/conf.ts
@@ -1,9 +0,0 @@
-export type AppLayoutKey = 'mobile_base' | 'mobile_y';
-
-export type ClientWindow = {
- app: {
- layout: Record<AppLayoutKey, {
- h: number;
- }>;
- }
-};
-\ No newline at end of file
diff --git a/apps-lib/src/lib/types/el.ts b/apps-lib/src/lib/types/el.ts
@@ -1,198 +1,30 @@
-import type { CallbackPromiseGeneric, GeometryCardinalDirection, GeometryDimension, GeometryGlyphDimension, ICbGOpt, ICbOpt, IClOpt, IFormField, IId, IIdOpt, ILyOptTs } from "$lib";
-import type { ThemeLayer } from "@radroots/theme";
+import type { ElementCallbackMount, ElementCallbackValue, ElementCallbackValueBlur, ElementCallbackValueKeydown, FormField, GeometryGlyphDimension, GeometryScreenPosition, GlyphKey, GlyphWeight, ICbOpt, IClOpt, IGlOpt, IIdGOpt, IIdOpt, ILabel, ILyOpt } from "$lib";
-export type GlyphKeyCurrency = `dollar` | `eur`;
-
-export type GlyphKey = |
- `images-square` |
- `bell` |
- `columns` |
- `bold` |
- `article` |
- `grid-four` |
- `link-simple` |
- `seal-check` |
- `selection-foreground` |
- `image-square` |
- `image-broken` |
- `funnel` |
- `users-three` |
- `note-blank` |
- `user-circle-plus` |
- `user-circle` |
- `receipt` |
- `invoice` |
- `note` |
- `arrow-left` |
- `arrows-down-up` |
- `basket` |
- `arrow-right` |
- `upload-simple` |
- `printer` |
- `download-simple` |
- `list` |
- `asterisk` |
- `asterisk-simple` |
- `subtitles-slash` |
- `cardholder` |
- `globe-x` |
- `exclamation-mark` |
- `network-x` |
- `x-circle` |
- `address-book-tabs` |
- `paper-plane-tilt` |
- `note-pencil` |
- `share-fat` |
- `folder` |
- `trash` |
- `plus-circle` |
- `currency-${GlyphKeyCurrency}` |
- `arrow-down` |
- `caret-circle-down` |
- `caret-circle-up` |
- `shopping-bag-open` |
- `coffee-bean` |
- `compass` |
- `map-pin-simple` |
- `handbag-simple` |
- `devices` |
- `lock-key` |
- `gear` |
- `gear-fine` |
- `bell-simple` |
- `envelope` |
- `house-line` |
- `arrows-left-right` |
- `list-plus` |
- `squares-four` |
- `list-plus` |
- `app-window` |
- `circle-notch` |
- `subtract-square` |
- `device-tablet-speaker` |
- `weather-cloud` |
- `warning` |
- `circle-notch` |
- `minus` |
- `key` |
- `arrow-u-up-left` |
- `arrow-counter-clockwise` |
- `circle` |
- `check-circle` |
- `circle-dashed` |
- `dots-three` |
- `cards-three` |
- `lightning` |
- `cards` |
- `note-pencil` |
- `tray` |
- `calendar-dots` |
- `notepad` |
- `network` |
- `calendar-blank` |
- `chats-circle` |
- `plant` |
- `farm` |
- `magnifying-glass` |
- `chat-circle-dots` |
- `dots-three-outline` |
- `copy` |
- `circles-four` |
- `waveform` |
- `film-strip` |
- `arrow-up` |
- `arrow-circle-up` |
- `plus` |
- `funnel-simple` |
- `user` |
- `camera` |
- `check` |
- `file` |
- `share-network` |
- `question` |
- `minus-circle` |
- `globe-simple` |
- `globe` |
- `warning-circle` |
- `x` |
- `info` |
- `caret-${GeometryCardinalDirection}` |
- `caret-up-down`;
-
-export type GlyphWeight = `light` | `regular` | `fill` | `bold`; // `thin` `duotone`
-
-export type ElementCallbackValue = CallbackPromiseGeneric<{ value: string; pass: boolean; }>;
-export type ElementCallbackValueKeydown<T extends HTMLElement> = CallbackPromiseGeneric<{ key: string; key_s: boolean; el: T }>;
-export type ElementCallbackValueBlur<T extends HTMLElement> = CallbackPromiseGeneric<{ el: T }>;
-export type ElementCallbackValueFocus<T extends HTMLElement> = CallbackPromiseGeneric<{ el: T }>;
-export type ElementCallbackMount<T extends HTMLElement> = CallbackPromiseGeneric<{ el: T }>;
+export type IToastKind = `simple`;
+export type IToast = IClOpt &
+ ILabel & IGlOpt & ILyOpt & {
+ styles?: IToastKind[];
+ position?: GeometryScreenPosition;
+ };
-export type IGlyph = ICbOpt & IIdOpt & {
- layer?: ThemeLayer;
- classes?: string;
+export type IGlyph = ICbOpt & IIdOpt & ILyOpt & IClOpt & {
weight?: GlyphWeight;
key: GlyphKey;
dim?: GeometryGlyphDimension;
};
-export type IGlyphCircle = {
- classes_wrap: string;
- glyph: IGlyph
-};
-
-export type ILoadingBlades = 8 | 12;
-export type ILoadingDimension = GeometryDimension | `glyph-send-button`;
-
-export type ILoading = {
- classes?: string;
- color?: 'white';
- blades?: ILoadingBlades;
- dim?: ILoadingDimension;
-};
-
-export type IDisabledOpt = {
- disabled?: boolean;
-}
-
-export type ISelectOption<T extends string> = IDisabledOpt & {
- value: T;
- label: string;
-};
-
-export type ISelectElement = IIdOpt & IClOpt & ILyOptTs &
- ICbGOpt<ISelectOption<string>> & {
- sync?: boolean;
- sync_init?: boolean;
- options: { group?: string | true; entries: ISelectOption<string>[] }[];
- show_arrows?: 'l' | 'r';
- };
-
-export type IInputElement = IId & IClOpt & ILyOptTs & {
+export type IInputElement<T extends string> = IIdGOpt<T> & IClOpt & ILyOpt & {
placeholder?: string;
label?: string;
hidden?: boolean;
validate?: RegExp;
sync?: boolean;
- field?: IFormField;
+ field?: FormField;
callback?: ElementCallbackValue,
callback_keydown?: ElementCallbackValueKeydown<HTMLInputElement>,
callback_blur?: ElementCallbackValueBlur<HTMLInputElement>;
callback_focus?: ElementCallbackValueBlur<HTMLInputElement>;
- on_mount?: ElementCallbackMount<HTMLInputElement>;
-};
-
-export type ITextAreaElement = IId & IClOpt & ILyOptTs & {
- placeholder?: string;
- label?: string;
- hidden?: boolean;
- validate?: RegExp;
- sync?: true;
- field?: IFormField;
- callback?: ElementCallbackValue,
- callback_keydown?: ElementCallbackValueKeydown<HTMLTextAreaElement>,
- callback_blur?: ElementCallbackValueBlur<HTMLTextAreaElement>;
- callback_focus?: ElementCallbackValueBlur<HTMLTextAreaElement>;
- on_mount?: ElementCallbackMount<HTMLTextAreaElement>;
+ callback_mount?: ElementCallbackMount<HTMLInputElement>;
};
\ No newline at end of file
diff --git a/apps-lib/src/lib/types/interface.ts b/apps-lib/src/lib/types/interface.ts
@@ -0,0 +1,133 @@
+import type { CallbackPromise, EntryStyle, GlyphKey, IGlyph, IInputElement, LayerGlyphBasisKind, LoadingBlades, LoadingDimension } from "$lib";
+import type { ThemeLayer } from "@radroots/theme";
+import type { TransitionConfig } from "svelte/transition";
+
+export type IDisabledOpt = {
+ disabled?: boolean | never;
+}
+
+export type IBasis<T> = {
+ basis: T;
+};
+
+export type ICb = {
+ callback: CallbackPromise | never;
+};
+
+export type ICbOpt = Partial<ICb>;
+
+export type ICl = {
+ classes: string | never;
+};
+
+export type IClOpt = Partial<ICl>;
+
+
+export type IId = {
+ id: string | never;
+};
+
+export type IIdOpt = Partial<IId>;
+
+export type IGl = {
+ glyph: IGlyph | never;
+};
+
+export type IGlOpt = Partial<IGl>;
+
+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 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 ILoadSymbol = IClOpt & {
+ color?: 'white';
+ blades?: LoadingBlades;
+ dim?: LoadingDimension;
+};
+
+export type IIdG<T extends string> = {
+ id: T | never;
+};
+
+export type FormField = {
+ validate: RegExp;
+ charset: RegExp;
+ validate_keypress?: boolean;
+};
+
+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?: TransitionConfig;
+ out?: TransitionConfig;
+ };
+}
+
+export type IEntryLine = ILoadingOpt & {
+ wrap?: IEntryWrap;
+ el: IInputElement<string>;
+ notify_inline?: {
+ glyph: GlyphKey | IGlyph;
+ };
+};
diff --git a/apps-lib/src/lib/types/nostr.ts b/apps-lib/src/lib/types/nostr.ts
@@ -1,4 +0,0 @@
-import type { NDKEvent } from "@nostr-dev-kit/ndk";
-import type { ExtendedBaseType, NDKEventStore } from "@nostr-dev-kit/ndk-svelte";
-
-export type NostrEventStore = NDKEventStore<ExtendedBaseType<NDKEvent>>
-\ No newline at end of file
diff --git a/apps-lib/src/lib/types/trellis.ts b/apps-lib/src/lib/types/trellis.ts
@@ -1,122 +0,0 @@
-import type { CallbackPromise, GlyphKey, ICbGOpt, ICbOpt, ICbROpt, IClOpt, IGl, IGlOpt, IGlyph, IGlyphCircle, IInputElement, ILabel, ILabelOpt, ILabelTup, ILoadingOpt, ILy, ISelectElement } from "$lib";
-
-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 ITrellisTitle = ICbOpt &
- IClOpt & {
- mod?: ITrellisBasisOffsetMod,
- value: string | true;
- link?: ICbOpt &
- IClOpt &
- IGlOpt & ILabelOpt;
- };
-
-export type ITrellisDescription = string | true;
-
-export type ITrellisDefault = {
- labels?: ITrellisDefaultLabel[];
- show_title?: boolean;
-};
-
-export type ITrellisDefaultLabel = ICbROpt & {
- label: string;
- classes?: string;
-};
-
-export type ITrellisStyles = {
- hide_rounded?: boolean;
- hide_border_top?: boolean;
- hide_border_bottom?: boolean;
- set_title_background?: boolean;
- set_default_background?: boolean;
-};
-
-export type ITrellisBasisOffsetModKey = 'sm' | 'glyph';
-export type ITrellisBasisOffsetMod = ITrellisBasisOffsetModKey | (({ glyph: IGlyph } | { glyph_circle: IGlyphCircle }) & {
- loading?: boolean;
-});
-
-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 ITrellisBasisTouchEnd = ICbGOpt<MouseEvent> & IGl;
-
-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: IInputElement;
- 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: ISelectElement & { value: string; };
- };
diff --git a/apps-lib/src/lib/utils/app.ts b/apps-lib/src/lib/utils/app.ts
@@ -0,0 +1,91 @@
+import { page } from "$app/stores";
+import type { CallbackPromise, NavigationParamTuple } from "$lib";
+import type { ColorMode, ThemeKey, ThemeLayer } from "@radroots/theme";
+import { get } from "svelte/store";
+
+export const get_store = get;
+
+export const sleep = async (ms: number): Promise<void> => {
+ await new Promise((resolve) => setTimeout(resolve, ms));
+};
+
+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 => {
+ const pref = location.pathname.slice(1, -1).replaceAll(`-`, `_`).replaceAll(`/`, `-`).replaceAll(`--`, `-`);
+ return `*${pref}${id ? `-${id}` : ``}`
+};
+
+export const fmt_cl = (classes?: string): string => {
+ return classes ? classes : ``;
+};
+
+export const parse_layer = (layer?: number, layer_default?: ThemeLayer): ThemeLayer => {
+ switch (layer) {
+ case 0:
+ case 1:
+ case 2:
+ return layer;
+ default:
+ return layer_default ? layer_default : 0;
+ };
+};
+
+export const encode_qp = (params_list?: NavigationParamTuple[]): string => {
+ const params = (params_list || []).filter(i => i[0] && i[1])
+ if (!params.length) return ``;
+ return params.map(([k, v], index) => `${index === 0 ? `?` : ``}&${k.trim()}=${encodeURI(v.trim())}`).join(``).trim();
+};
+
+export const encode_qp_route = <T extends string>(route: T, params_list?: NavigationParamTuple[]): string => {
+ return `${route}/${encode_qp(params_list)}`.replaceAll(`//`, `/`)
+};
+
+export const catch_err = async (e: unknown, func: string, callback: (opts: {
+ name: string;
+ message: string;
+ stack: string;
+ url: string;
+ func: string;
+}) => Promise<void>): Promise<void> => {
+ const $page = get_store(page) as any;
+ 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 exe_iter = async (callback: CallbackPromise, num: number = 1, delay: number = 400): Promise<void> => {
+ try {
+ const iter_fn = (count: number) => {
+ if (count > 0) {
+ callback();
+ if (count > 1) {
+ setTimeout(() => {
+ iter_fn(count - 1);
+ }, delay);
+ }
+ }
+ };
+ iter_fn(num);
+ } catch (e) {
+ console.log(`(error) exe_iter `, e);
+ }
+};
+
+export const value_constrain = (regex_charset: RegExp, value: string): string => {
+ return value
+ .split(``)
+ .filter((char) => regex_charset.test(char))
+ .join(``);
+};
diff --git a/apps-lib/src/lib/utils/carousel.ts b/apps-lib/src/lib/utils/carousel.ts
@@ -3,10 +3,9 @@ import {
carousel_index,
carousel_index_max,
carousel_num,
- exe_iter
+ exe_iter,
+ get_store
} from "$lib";
-import { get as get_store } from 'svelte/store';
-
const CAROUSEL_DELAY_MS = 150;
const get_slide_container = <T extends string>(
@@ -26,14 +25,16 @@ const get_slide_item = <T extends string>(view: T): Element | undefined => {
const carousel_dec_handler = async <T extends string>(
view: T,
): Promise<void> => {
- if (get_store(carousel_active)) return;
+ 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;
- carousel_index.set(Math.max(get_store(carousel_index) - 1, 0));
+ const $carousel_index = get_store(carousel_index);
+ carousel_index.set(Math.max($carousel_index - 1, 0));
}
carousel_active.set(false);
};
@@ -41,15 +42,18 @@ const carousel_dec_handler = async <T extends string>(
const carousel_inc_handler = async <T extends string>(
view: T,
): Promise<void> => {
- if (get_store(carousel_active)) return;
+ 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(get_store(carousel_index) + 1, get_store(carousel_index_max)),
+ Math.min($carousel_index + 1, $carousel_index_max),
);
}
carousel_active.set(false);
@@ -59,9 +63,9 @@ export const carousel_inc = async <T extends string>(
view: T,
duration: number = CAROUSEL_DELAY_MS
): Promise<void> => {
- const num = get_store(carousel_num);
+ const $carousel_num = get_store(carousel_num);
carousel_num.set(1);
- await exe_iter(async () => carousel_inc_handler(view), num, duration);
+ await exe_iter(async () => carousel_inc_handler(view), $carousel_num, duration);
};
@@ -69,9 +73,9 @@ export const carousel_dec = async <T extends string>(
view: T,
duration: number = CAROUSEL_DELAY_MS
): Promise<void> => {
- const num = get_store(carousel_num);
+ const $carousel_num = get_store(carousel_num);
carousel_num.set(1);
- await exe_iter(async () => carousel_dec_handler(view), num, duration);
+ await exe_iter(async () => carousel_dec_handler(view), $carousel_num, duration);
};
export const carousel_init = async <T extends string>(view: T, num_max: number,
diff --git a/apps-lib/src/lib/utils/client.ts b/apps-lib/src/lib/utils/client.ts
@@ -1,323 +0,0 @@
-import { goto } from "$app/navigation";
-import { page } from "$app/stores";
-import { app_toast, locale, ls, nav_prev, TOAST_MS, type AnchorRoute, type AppConfigType, type AppLayoutKey, type CallbackPromise, type CallbackPromiseGeneric, type GeolocationLatitudeFmtOption, type GlyphKey, type IToast, type LabelFieldKind, type LayerGlyphBasisKind, type NavigationParamTuple, type NavigationRoute, type NavigationRouteParamKey } from "$lib";
-import type { ColorMode, ThemeKey, ThemeLayer } from "@radroots/theme";
-import { get } from "svelte/store";
-
-export const ascii = {
- bullet: '•',
- dash: `—`,
- up: `↑`,
- down: `↓`
-}
-
-export const get_store = get;
-
-export const sleep = async (ms: number): Promise<void> => {
- await new Promise((resolve) => setTimeout(resolve, ms));
-};
-
-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 toggle_color_mode = (color_mode: ColorMode): ColorMode => {
- return color_mode === `light` ? `dark` : `light`;
-};
-
-export const fmt_cl = (classes?: string): string => {
- return classes ? classes : ``;
-};
-
-export const get_label_classes = (layer: ThemeLayer, glyph_kind: LayerGlyphBasisKind | undefined, hide_active: boolean): string => {
- return `text-layer-${layer}-glyph${glyph_kind ? `${glyph_kind}` : `_d`} ${hide_active ? `` : `group-active:text-layer-${layer}-glyph_a`}`
-};
-
-export const get_label_classes_kind = (layer: ThemeLayer, label_kind: LabelFieldKind | undefined, hide_active: boolean): string => {
- return `text-layer-${layer}-glyph${label_kind ? `-${label_kind}` : ``} ${hide_active ? `` : `group-active:text-layer-${layer}-glyph${label_kind ? `-${label_kind}_a` : `_a`}`}`
-};
-
-export const parse_layer = (layer?: number, layer_default?: ThemeLayer): ThemeLayer => {
- switch (layer) {
- case 0:
- case 1:
- case 2:
- return layer;
- default:
- return layer_default ? layer_default : 0;
- };
-};
-
-export const fmt_trellis = (hide_border_t: boolean, hide_border_b: boolean): string => {
- return `${hide_border_t ? `group-first:border-t-0` : `group-first:border-t-line`} ${hide_border_b ? `group-last:border-b-0` : `group-last:border-b-line`}`;
-};
-
-export const encode_qp = (params_list?: NavigationParamTuple[]): string => {
- const params = (params_list || []).filter(i => i[0] && i[1])
- if (!params.length) return ``;
- return params.map(([k, v], index) => `${index === 0 ? `?` : ``}&${k.trim()}=${encodeURI(v.trim())}`).join(``).trim();
-};
-
-export const encode_qp_route = (route: NavigationRoute, params_list?: NavigationParamTuple[]): string => {
- return `${route}/${encode_qp(params_list)}`.replaceAll(`//`, `/`)
-};
-
-export const decode_qp = (query_param: string): AnchorRoute => {
- const route = decodeURI(query_param).replaceAll(`//`, `/`);
- return `/${route.charAt(0) === `/` ? route.slice(1) : route}`;
-};
-
-export function parse_qp(param: string): NavigationRouteParamKey | undefined {
- switch (param) {
- case "nostr_pk":
- case "id":
- case "rkey":
- case "lat":
- case "lng":
- return param;
- default:
- return undefined;
- };
-};
-
-export function time_now_ms(): number {
- return Math.floor(new Date().getTime() / 1000);
-};
-
-export const fmt_id = (id?: string): string => {
- const pref = location.pathname.slice(1, -1).replaceAll(`-`, `_`).replaceAll(`/`, `-`).replaceAll(`--`, `-`);
- return `*${pref}${id ? `-${id}` : ``}`
-};
-
-export const fmt_capitalize = (val: string): string => {
- const fmt = val.split(` `).map(i => `${i.charAt(0).toUpperCase()}${i.slice(1)}`).join(` `);
- return fmt;
-};
-
-export const zoom_step = (num: number, op: `inc` | `dec`): number => {
- const int_num = Math.round(num);
- if (op === 'inc') return Math.min(int_num + 1, 14);
- return Math.max(int_num - 1, 0);
-};
-
-export const int_step = (num: number, op: `+` | `-`, bounds?: number): number => {
- const int_num = Math.round(num);
- if (op === '+') return Math.min(int_num + 1, bounds || Number.POSITIVE_INFINITY);
- return Math.max(int_num - 1, bounds || 0);
-};
-
-export const clipboard_copy = async (text: string, callback?: CallbackPromiseGeneric<string>): Promise<void> => {
- try {
- navigator.clipboard.writeText(text).then(async () => {
- if (callback) await callback(text);
- });
- } catch (e) {
- console.log(`(error) clipboard_copy `, e);
- }
-};
-
-export const as_glyph_key = (val: string): GlyphKey => {
- return val as GlyphKey;
-}
-
-export const route = async (nav_route: NavigationRoute, params_list?: NavigationParamTuple[]): Promise<void> => {
- try {
- if (params_list && params_list.length) await goto(encode_qp_route(nav_route, params_list));
- else await goto(nav_route);
- } catch (e) {
- console.log(`(error) route `, e);
- }
-}
-
-export const route_sync = (nav_route: NavigationRoute): void => {
- route(nav_route);
-};
-
-export const get_layout = (val: string | false): AppLayoutKey => {
- switch (val) {
- case `mobile_base`:
- case `mobile_y`:
- return val;
- default:
- return `mobile_base`;
- };
-};
-
-export const view_effect = <T extends string>(view: T): void => {
- for (const el of document.querySelectorAll(`[data-view]`))
- el.classList.toggle(
- `hidden`,
- el.getAttribute(`data-view`) !== view,
- );
-};
-
-export const init_toast = (): void => {
- app_toast.set(false);
-};
-
-export const show_toast = async (opts: {
- args: IToast | string;
- callback?: CallbackPromise;
-}): Promise<void> => {
- try {
- const basis: IToast = typeof opts.args === `string`
- ? {
- layer: 1,
- label: {
- value: opts.args,
- },
- }
- : opts.args;
- app_toast.set(basis);
- await sleep(TOAST_MS);
- init_toast();
- if (opts.callback) await opts.callback();
- } catch (e) {
- console.log(`(error) show_toast `, e);
- }
-};
-
-export const value_constrain = (regex_charset: RegExp, value: string): string => {
- return value
- .split(``)
- .filter((char) => regex_charset.test(char))
- .join(``);
-};
-
-export const fmt_textarea_value = (value: string): string => {
- return value.replace(/ /g, `\u00A0`);
-};
-
-export const value_constrain_textarea = (regex_charset: RegExp, value: string): string => {
- return value
- .replace(/\u00A0/g, ` `)
- .split(/[\n]/)
- .map(line => line
- .split(``)
- .filter((char) => regex_charset.test(char))
- .join(``)
- )
- .join("\n");
-};
-
-export const parse_cfg_type = (value?: string): AppConfigType => {
- switch (value) {
- case `farmer`:
- case `personal`:
- return value;
- default:
- return `personal`
- };
-};
-
-export const route_prev = async (route_fallback: NavigationRoute = `/`, params_fallback: NavigationParamTuple[] = []): Promise<void> => {
- try {
- let route_to = encode_qp_route(route_fallback, params_fallback);
- const $nav_prev = get_store(nav_prev);
- if ($nav_prev.length) {
- const nav_prev_li = $nav_prev[$nav_prev.length - 1];
- nav_prev.set([...$nav_prev.slice(0, -1)]);
- if (nav_prev_li)
- route_to = encode_qp_route(
- nav_prev_li.route,
- nav_prev_li.params,
- );
- }
- await goto(route_to);
- } catch (e) {
- console.log(`(error) route_prev `, e);
- }
-};
-
-export const fmt_geol_latitude = (lat: number, fmt_opt: GeolocationLatitudeFmtOption, precision: number = 5): string => {
- const _locale = get_store(locale);
- const options: Intl.NumberFormatOptions = {
- minimumFractionDigits: 2,
- maximumFractionDigits: 2,
- };
- const fmt_deg = new Intl.NumberFormat(_locale, { maximumFractionDigits: 0 });
- const fmt_min = new Intl.NumberFormat(_locale, options);
- const fmt_sec = new Intl.NumberFormat(_locale, options);
- if (fmt_opt === 'dms') {
- const deg = Math.floor(Math.abs(lat));
- const min = Math.floor((Math.abs(lat) - deg) * 60);
- const sec = ((Math.abs(lat) - deg - min / 60) * 3600);
- return `${fmt_deg.format(deg)}° ${fmt_min.format(min)}' ${fmt_sec.format(sec)}" ${lat >= 0 ? 'N' : 'S'}`;
- } else if (fmt_opt === 'dm') {
- const deg = Math.floor(Math.abs(lat));
- const min = (Math.abs(lat) - deg) * 60;
- return `${fmt_deg.format(deg)}° ${fmt_min.format(min)}' ${lat >= 0 ? 'N' : 'S'}`;
- } else {
- return `${lat.toLocaleString(_locale, { maximumFractionDigits: precision })}° ${lat >= 0 ? 'N' : 'S'}`;
- }
-};
-
-export const fmt_geol_longitude = (lng: number, fmt_opt: GeolocationLatitudeFmtOption, precision: number = 5): string => {
- const _locale = get_store(locale);
- const options: Intl.NumberFormatOptions = {
- minimumFractionDigits: 2,
- maximumFractionDigits: 2,
- };
- const fmt_deg = new Intl.NumberFormat(_locale, { maximumFractionDigits: 0 });
- const fmt_min = new Intl.NumberFormat(_locale, options);
- const fmt_sec = new Intl.NumberFormat(_locale, options);
- if (fmt_opt === 'dms') {
- const degrees = Math.floor(Math.abs(lng));
- const minutes = Math.floor((Math.abs(lng) - degrees) * 60);
- const seconds = ((Math.abs(lng) - degrees - minutes / 60) * 3600);
- return `${fmt_deg.format(degrees)}° ${fmt_min.format(minutes)}' ${fmt_sec.format(seconds)}" ${lng >= 0 ? 'E' : 'W'}`;
- } else if (fmt_opt === 'dm') {
- const degrees = Math.floor(Math.abs(lng));
- const minutes = (Math.abs(lng) - degrees) * 60;
- return `${fmt_deg.format(degrees)}° ${fmt_min.format(minutes)}' ${lng >= 0 ? 'E' : 'W'}`;
- } else {
- return `${lng.toLocaleString(_locale, { maximumFractionDigits: precision })}° ${lng >= 0 ? 'E' : 'W'}`;
- }
-};
-
-export const fmt_geol_point = (lat: number, lng: number, precision: number = 4): [string, string] => {
- return [fmt_geol_latitude(lat, `d`, precision), fmt_geol_longitude(lng, `d`, precision)];
-};
-
-export const exe_iter = async (callback: CallbackPromise, num: number = 1, delay: number = 400): Promise<void> => {
- try {
- const iter_fn = (count: number) => {
- if (count > 0) {
- callback();
- if (count > 1) {
- setTimeout(() => {
- iter_fn(count - 1);
- }, delay);
- }
- }
- };
- iter_fn(num);
- } catch (e) {
- console.log(`(error) exe_iter `, e);
- }
-};
-
-export const fmt_list_oxford = (list: string[], loc_key?: string): string => {
- if (list.length > 1 && loc_key) return `${list.slice(0, -1).map(i => `${loc_key}${i}`).join(', ')} ${`${get_store(ls)(`common.and`)}`} ${`${loc_key}${list[list.length - 1]}`}`;
- else if (list.length > 1) return `${list.slice(0, -1).join(', ')} ${`${get_store(ls)(`common.and`)}`} ${list[list.length - 1]}`;
- return list[0];
-};
-
-export const catch_err = async (e: unknown, fn_name: string): Promise<void> => {
- const $page = get_store(page) as any;
- if (e instanceof Error) {
- const { name, message, stack, cause } = e
- console.log(`(catch_err) ${$page.url.pathname} ${name} ${message} ${stack} ${cause}`)
- } else {
- console.log(`(catch_err) `, e)
- }
-};
-
-export const debounce_input = (func: Function, delay: number) => {
- let timer: ReturnType<typeof setTimeout>;
- return function (this: any, ...args: any) {
- clearTimeout(timer);
- timer = setTimeout(() => func.apply(this, args), delay);
- };
-};
diff --git a/apps-lib/src/lib/utils/conf.ts b/apps-lib/src/lib/utils/conf.ts
@@ -1,16 +0,0 @@
-import type { ClientWindow } from "$lib";
-
-export const TOAST_MS = 1500;
-
-export const wind: ClientWindow = {
- app: {
- layout: {
- mobile_base: {
- h: 600
- },
- mobile_y: {
- h: 750
- }
- }
- }
-};
-\ No newline at end of file
diff --git a/apps-lib/src/lib/utils/document.ts b/apps-lib/src/lib/utils/document.ts
@@ -39,3 +39,11 @@ export const els_id_pref_index = (id_pref: string, num_index: number, orientatio
return undefined;
};
+export const view_effect = <T extends string>(view: T): void => {
+ for (const el of document.querySelectorAll(`[data-view]`))
+ el.classList.toggle(
+ `hidden`,
+ el.getAttribute(`data-view`) !== view,
+ );
+};
+
diff --git a/apps-lib/src/lib/utils/geo.ts b/apps-lib/src/lib/utils/geo.ts
@@ -1,12 +0,0 @@
-export const fmt_geo_direction = (opts: { lat: number } | { lng: number }): string => {
- if ('lat' in opts) {
- const lat = opts.lat;
- const direction = lat >= 0 ? 'N' : 'S';
- return `° ${direction}`;
- } else {
- const lng = opts.lng;
- const direction = lng >= 0 ? 'E' : 'W';
- return `° ${direction}`;
- }
-};
-
diff --git a/apps-lib/src/lib/utils/i18n.ts b/apps-lib/src/lib/utils/i18n.ts
@@ -0,0 +1,22 @@
+import i18n, { type Loader } from '@sveltekit-i18n/base';
+import type { Config, Parser } from '@sveltekit-i18n/parser-icu';
+import parser from '@sveltekit-i18n/parser-icu';
+
+type LanguageConfig = {
+ default?: string;
+ value?: string;
+};
+export const i18n_conf = <T extends string>(opts: {
+ default_locale: T;
+ translations: Record<T, any>;
+ loaders: Loader.LoaderModule[]
+}): i18n<Parser.Params<LanguageConfig>> => {
+ const { default_locale: initLocale, translations, loaders } = opts;
+ const config: Config<LanguageConfig> = {
+ initLocale,
+ translations,
+ parser: parser(),
+ loaders,
+ };
+ return new i18n(config);
+};
+\ No newline at end of file
diff --git a/apps-lib/src/lib/utils/kv.ts b/apps-lib/src/lib/utils/kv.ts
@@ -0,0 +1,19 @@
+import { fmt_id, kv } from "$lib";
+
+export const kv_init = async (): Promise<void> => {
+ const range = Keyva.prefix(`*`);
+ const kv_list = await kv.each({ range }, `keys`);
+ await Promise.all(kv_list.map((i) => kv.delete(i)));
+};
+
+export const kv_init_page = async (): Promise<void> => {
+ const kv_pref = fmt_id();
+ const range = Keyva.prefix(kv_pref);
+ const kv_list = await kv.each({ range }, `keys`);
+ await Promise.all(kv_list.map((i) => kv.delete(i)));
+};
+
+export const kv_sync = async (list: [string, string][]): Promise<void> => {
+ for (const [key, val] of list) await kv.set(key, val);
+};
+
diff --git a/apps-lib/src/lib/utils/numbers.ts b/apps-lib/src/lib/utils/numbers.ts
@@ -1,13 +0,0 @@
-import { locale } from "$lib/locales/i18n";
-import { get as get_store } from "svelte/store";
-
-export const fmt_price = (currency: string, value: string): string => {
- const value_num = parseFloat(value);
- const res = new Intl.NumberFormat(get_store(locale), {
- style: 'currency',
- currency,
- minimumFractionDigits: 2,
- maximumFractionDigits: 2
- }).format(value_num);
- return res;
-};
diff --git a/apps-lib/src/lib/utils/routes.ts b/apps-lib/src/lib/utils/routes.ts
@@ -1,51 +1,11 @@
export type NavigationRoute =
| "/"
- | "/farm/land"
- | "/farm/land/add"
- | "/farm/land/view"
- | "/models/location-gcs"
- | "/models/nostr-profile"
- | "/models/nostr-profile/edit/field"
- | "/models/nostr-profile/view"
- | "/models/nostr-relay"
- | "/models/nostr-relay/view"
- | "/models/trade-product"
- | "/models/trade-product/add"
- | "/models/trade-product/view"
- | "/notifications"
- | "/search"
- | "/settings"
- | "/settings/nostr"
- | "/settings/profile"
- | "/settings/profile/edit"
- | "/test"
- | "/cfg/error"
- | "/cfg/init";
+ | "/cfg";
export function parse_route(route: string): NavigationRoute {
switch (route) {
case "/":
- case "/farm/land":
- case "/farm/land/add":
- case "/farm/land/view":
- case "/models/location-gcs":
- case "/models/nostr-profile":
- case "/models/nostr-profile/edit/field":
- case "/models/nostr-profile/view":
- case "/models/nostr-relay":
- case "/models/nostr-relay/view":
- case "/models/trade-product":
- case "/models/trade-product/add":
- case "/models/trade-product/view":
- case "/notifications":
- case "/search":
- case "/settings":
- case "/settings/nostr":
- case "/settings/profile":
- case "/settings/profile/edit":
- case "/test":
- case "/cfg/error":
- case "/cfg/init":
+ case "/cfg":
return route;
default:
return "/";
diff --git a/apps-lib/src/lib/utils/styles.ts b/apps-lib/src/lib/utils/styles.ts
@@ -1,4 +1,4 @@
-import type { AppLayoutKey, GeometryGlyphDimension, ILoadingDimension, IToastKind } from "$lib";
+import type { AppLayoutKey, GeometryGlyphDimension, IToastKind, LoadingDimension } from "$lib";
export const glyph_style_map: Map<GeometryGlyphDimension, { gl_1: number; dim_1?: number; }> = new Map([
["xs--", { gl_1: 12 }],
@@ -17,7 +17,7 @@ export const glyph_style_map: Map<GeometryGlyphDimension, { gl_1: number; dim_1?
["xl+", { gl_1: 40 }],
]);
-export const loading_style_map: Map<ILoadingDimension, { dim_1: number; gl_2: number }> = new Map([
+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 }],
diff --git a/apps-lib/src/lib/utils/time.ts b/apps-lib/src/lib/utils/time.ts
@@ -1,37 +0,0 @@
-import { locale } from "$lib";
-import { DateTime, type DateTimeFormatOptions } from "luxon";
-import { get } from "svelte/store";
-
-const time_fmt: Record<string, DateTimeFormatOptions> = {
- default: DateTime.DATE_SHORT,
- abbrev: DateTime.DATE_MED,
- file_info: DateTime.DATETIME_SHORT_WITH_SECONDS,
- time_24: DateTime.TIME_24_SIMPLE
-};
-
-export function time_fmt_epoch_s(epoch_s: number | undefined, fmt_key: keyof typeof time_fmt = `default`): string {
- const dt = DateTime.fromSeconds(epoch_s);
- if (!dt.isValid) return ``;
- const time = dt.setLocale(get(locale)).toLocaleString(time_fmt[fmt_key]);
- return time;
-};
-
-export function time_iso(iso: string | undefined, fmt_key: keyof typeof time_fmt = `default`): string {
- const dt = DateTime.fromISO(iso);
- if (!dt.isValid) return ``;
- const time = dt.setLocale(get(locale)).toLocaleString(time_fmt[fmt_key]);
- return time;
-};
-
-
-export function time_iso_fmt(iso: string | undefined, fmt_str: string): string {
- const dt = DateTime.fromISO(iso);
- if (!dt.isValid) return ``;
- const time = dt.setLocale(get(locale)).toFormat(fmt_str);
- return time;
-};
-
-export function format_month_abbrev(month_num: number): string {
- if (month_num < 1 || month_num > 12) return ``;
- return DateTime.fromObject({ month: month_num }).setLocale(get(locale)).toFormat('MMM');
-}
-\ No newline at end of file