web_lib

Common web application libraries
git clone https://radroots.dev/git/web_lib.git
Log | Files | Refs | LICENSE

commit bf8ca89de9d42da997abf5fc3cf42a5a61489290
parent 1eebd22f9a8458418e58cd0a6a9d904a78168844
Author: triesap <137732411+triesap@users.noreply.github.com>
Date:   Sun,  6 Oct 2024 07:13:33 +0000

apps-lib: add textarea element ui, edit components, add locales

Diffstat:
Mapps-lib/src/lib/components/input_select.svelte | 2+-
Mapps-lib/src/lib/components/layout_trellis_line.svelte | 6++++--
Mapps-lib/src/lib/components/nav_option.svelte | 95++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Mapps-lib/src/lib/index.ts | 1+
Mapps-lib/src/lib/locales/en/common.json | 5+++++
Mapps-lib/src/lib/locales/en/icu.json | 4++++
Mapps-lib/src/lib/locales/en/model_fields.json | 2++
Mapps-lib/src/lib/types/ui.ts | 17+++++++++++++++++
Mapps-lib/src/lib/ui/css_static.svelte | 2+-
Mapps-lib/src/lib/ui/input_element.svelte | 18------------------
Aapps-lib/src/lib/ui/textarea_element.svelte | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
11 files changed, 150 insertions(+), 66 deletions(-)

diff --git a/apps-lib/src/lib/components/input_select.svelte b/apps-lib/src/lib/components/input_select.svelte @@ -40,7 +40,7 @@ > {#if basis.loading} <div class={`flex flex-row w-full justify-center items-center`}> - <Loading basis={{ dim: `xs` }} /> + <Loading basis={{ dim: `sm`, blades: 6 }} /> </div> {:else} <select diff --git a/apps-lib/src/lib/components/layout_trellis_line.svelte b/apps-lib/src/lib/components/layout_trellis_line.svelte @@ -7,8 +7,10 @@ $: basis = basis; </script> -<div class={`flex flex-col w-full gap-1 justify-start items-center`}> - <div class={`flex flex-row w-full px-2 gap-2 justify-start items-center`}> +<div class={`flex flex-col w-trellis_line gap-1 justify-start items-center`}> + <div + class={`flex flex-row h-5 w-full px-2 gap-2 justify-start items-center`} + > {#if `value` in basis.label} <p class={`${fmt_cl(basis.label.classes)} font-sans font-[400] uppercase text-layer-2-glyph text-sm`} diff --git a/apps-lib/src/lib/components/nav_option.svelte b/apps-lib/src/lib/components/nav_option.svelte @@ -14,65 +14,72 @@ $: basis = basis; $: layer = parse_layer(1); + + //$: classes_wrap = + // `label` in basis && ; </script> -{#if basis.loading} +{#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 pr-6 justify-end items-center`} + class={`${fmt_cl(basis?.classes)} group col-span-4 flex flex-row h-full justify-end items-center`} on:click={async () => { - await basis.callback(el_swap); + await basis?.callback(el_swap); }} > - {#if `glyph` in basis && basis.glyph} + {#if `glyph` in basis && basis?.glyph} <Glyph basis={{ - classes: `group-active:opacity-70 ${basis.glyph.classes}`, - ...basis.glyph, + classes: `group-active:opacity-70 ${basis?.glyph?.classes}`, + ...basis?.glyph, }} /> {/if} - {#if `label` in basis && basis.label} - {#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-navPrevious text-layer-${layer}-glyph-hl group-active:opacity-60`)} font-sans -translate-y-[1px] transition-all`} - > - {basis.label.swap.on.value} - </p> - </div> - <div class="swap-off"> - <p - class={`${fmt_cl(basis.label.swap.off.classes || `text-navPrevious text-layer-${layer}-glyph-hl group-active:opacity-60`)} font-sans -translate-y-[1px] transition-all`} - > - {basis.label.swap.off.value} - </p> - </div> - </label> - {:else if `value` in basis.label} - <p - class={`${fmt_cl(basis.label.classes)} font-sans text-navPrevious text-layer-1-glyph-hl group-active:opacity-60 transition-opacity`} - > - {basis.label.value} - </p> - {/if} - {#if `glyph` in basis.label && basis.label.glyph} - <Glyph - basis={{ - key: basis.label.glyph.key, - classes: `text-layer-1-glyph-hl group-active:opacity-60 ${basis.label.glyph.classes}`, - weight: `bold`, - dim: `md`, - }} - /> - {/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-navPrevious text-layer-${layer}-glyph-hl group-active:opacity-60`)} font-sans -translate-y-[1px] transition-all`} + > + {basis?.label?.swap?.on.value} + </p> + </div> + <div class="swap-off"> + <p + class={`${fmt_cl(basis?.label?.swap?.off.classes || `text-navPrevious text-layer-${layer}-glyph-hl group-active:opacity-60`)} font-sans -translate-y-[1px] transition-all`} + > + {basis?.label?.swap?.off.value} + </p> + </div> + </label> + {:else if `value` in basis?.label} + <p + class={`${fmt_cl(basis?.label.classes)} font-sans text-navPrevious text-layer-1-glyph-hl group-active:opacity-60 transition-opacity`} + > + {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-60 ${basis?.label?.glyph?.classes}`, + weight: `bold`, + dim: `md`, + }} + /> + {/if} + </div> {/if} </button> {/if} diff --git a/apps-lib/src/lib/index.ts b/apps-lib/src/lib/index.ts @@ -3,6 +3,7 @@ export { default as Blur } from "./ui/blur.svelte"; export { default as SelectElement } from "./ui/select_element.svelte"; export { default as Toast } from "./ui/toast.svelte"; export { default as GlyphCircle } from "./ui/glyph_circle.svelte"; +export { default as TextareaElement } from "./ui/textarea_element.svelte"; export { default as CssStatic } from "./ui/css_static.svelte"; export { default as Divider } from "./ui/divider.svelte"; export { default as LabelSwap } from "./ui/label_swap.svelte"; diff --git a/apps-lib/src/lib/locales/en/common.json b/apps-lib/src/lib/locales/en/common.json @@ -1,4 +1,9 @@ { + "lot": "Lot", + "lot_name": "Lot name", + "product_name": "Product name", + "summary": "Summary", + "title": "Title", "list": "List", "add_map_location": "Add map location", "connect": "Connect", diff --git a/apps-lib/src/lib/locales/en/icu.json b/apps-lib/src/lib/locales/en/icu.json @@ -1,4 +1,8 @@ { + "total_*": "Total {value}", + "*_details": "{value} details", + "listing_*": "Listing {value}", + "enter_the_*": "Enter the {value}", "show_*": "Show {value}", "invalid_*": "Invalid {value}", "disconnect_*": "Disconnect {value}", diff --git a/apps-lib/src/lib/locales/en/model_fields.json b/apps-lib/src/lib/locales/en/model_fields.json @@ -4,6 +4,8 @@ "geohash": "Geohash", "label": "Label", "key": "Key", + "title": "", + "summary": "", "process": "Process", "lot": "Lot", "profile": "Profile", diff --git a/apps-lib/src/lib/types/ui.ts b/apps-lib/src/lib/types/ui.ts @@ -142,4 +142,21 @@ export type IInputElement = IClOpt & ILyOptTs & { callback?: CallbackPromiseGeneric<{ val: string; pass: boolean; }>; callback_keydown?: CallbackPromiseGeneric<{ key: string; }>; on_mount?: CallbackPromiseGeneric<HTMLInputElement>; +}; + +export type ITextAreaElement = IClOpt & ILyOptTs & { + id: string; + placeholder?: string; + label?: string; + hidden?: boolean; + validate?: RegExp; + sync?: true; + sync_init?: true | string; + field?: IFormField; + /*notify_inline?: { + glyph: GlyphKey | IGlyph; + };*/ + callback?: CallbackPromiseGeneric<{ val: string; pass: boolean; }>; + callback_keydown?: CallbackPromiseGeneric<{ key: string; }>; + on_mount?: CallbackPromiseGeneric<HTMLTextAreaElement>; }; \ No newline at end of file diff --git a/apps-lib/src/lib/ui/css_static.svelte b/apps-lib/src/lib/ui/css_static.svelte @@ -1 +1 @@ -<div class="hidden bg-layer-0-surface active:bg-layer-0-surface group-active:bg-layer-0-surface focus:bg-layer-0-surface group-focus:bg-layer-0-surface border-layer-0-surface active:border-layer-0-surface group-active:border-layer-0-surface focus:border-layer-0-surface group-focus:border-layer-0-surface bg-layer-0-surface_a active:bg-layer-0-surface_a group-active:bg-layer-0-surface_a focus:bg-layer-0-surface_a group-focus:bg-layer-0-surface_a border-layer-0-surface_a active:border-layer-0-surface_a group-active:border-layer-0-surface_a focus:border-layer-0-surface_a group-focus:border-layer-0-surface_a bg-layer-0-surface-edge active:bg-layer-0-surface-edge group-active:bg-layer-0-surface-edge focus:bg-layer-0-surface-edge group-focus:bg-layer-0-surface-edge border-layer-0-surface-edge active:border-layer-0-surface-edge group-active:border-layer-0-surface-edge focus:border-layer-0-surface-edge group-focus:border-layer-0-surface-edge bg-layer-0-surface-blur active:bg-layer-0-surface-blur group-active:bg-layer-0-surface-blur focus:bg-layer-0-surface-blur group-focus:bg-layer-0-surface-blur border-layer-0-surface-blur active:border-layer-0-surface-blur group-active:border-layer-0-surface-blur focus:border-layer-0-surface-blur group-focus:border-layer-0-surface-blur bg-layer-1-surface active:bg-layer-1-surface group-active:bg-layer-1-surface focus:bg-layer-1-surface group-focus:bg-layer-1-surface border-layer-1-surface active:border-layer-1-surface group-active:border-layer-1-surface focus:border-layer-1-surface group-focus:border-layer-1-surface bg-layer-1-surface_a active:bg-layer-1-surface_a group-active:bg-layer-1-surface_a focus:bg-layer-1-surface_a group-focus:bg-layer-1-surface_a border-layer-1-surface_a active:border-layer-1-surface_a group-active:border-layer-1-surface_a focus:border-layer-1-surface_a group-focus:border-layer-1-surface_a bg-layer-1-surface-edge active:bg-layer-1-surface-edge group-active:bg-layer-1-surface-edge focus:bg-layer-1-surface-edge group-focus:bg-layer-1-surface-edge border-layer-1-surface-edge active:border-layer-1-surface-edge group-active:border-layer-1-surface-edge focus:border-layer-1-surface-edge group-focus:border-layer-1-surface-edge bg-layer-1-surface-err active:bg-layer-1-surface-err group-active:bg-layer-1-surface-err focus:bg-layer-1-surface-err group-focus:bg-layer-1-surface-err border-layer-1-surface-err active:border-layer-1-surface-err group-active:border-layer-1-surface-err focus:border-layer-1-surface-err group-focus:border-layer-1-surface-err bg-layer-2-surface active:bg-layer-2-surface group-active:bg-layer-2-surface focus:bg-layer-2-surface group-focus:bg-layer-2-surface border-layer-2-surface active:border-layer-2-surface group-active:border-layer-2-surface focus:border-layer-2-surface group-focus:border-layer-2-surface bg-layer-2-surface_a active:bg-layer-2-surface_a group-active:bg-layer-2-surface_a focus:bg-layer-2-surface_a group-focus:bg-layer-2-surface_a border-layer-2-surface_a active:border-layer-2-surface_a group-active:border-layer-2-surface_a focus:border-layer-2-surface_a group-focus:border-layer-2-surface_a bg-layer-2-surface-edge active:bg-layer-2-surface-edge group-active:bg-layer-2-surface-edge focus:bg-layer-2-surface-edge group-focus:bg-layer-2-surface-edge border-layer-2-surface-edge active:border-layer-2-surface-edge group-active:border-layer-2-surface-edge focus:border-layer-2-surface-edge group-focus:border-layer-2-surface-edge text-layer-0-glyph active:text-layer-0-glyph group-active:text-layer-0-glyph focus:text-layer-0-glyph group-focus:text-layer-0-glyph text-layer-0-glyph_a active:text-layer-0-glyph_a group-active:text-layer-0-glyph_a focus:text-layer-0-glyph_a group-focus:text-layer-0-glyph_a text-layer-0-glyph-hl active:text-layer-0-glyph-hl group-active:text-layer-0-glyph-hl focus:text-layer-0-glyph-hl group-focus:text-layer-0-glyph-hl text-layer-0-glyph-hl_a active:text-layer-0-glyph-hl_a group-active:text-layer-0-glyph-hl_a focus:text-layer-0-glyph-hl_a group-focus:text-layer-0-glyph-hl_a text-layer-0-glyph-shade active:text-layer-0-glyph-shade group-active:text-layer-0-glyph-shade focus:text-layer-0-glyph-shade group-focus:text-layer-0-glyph-shade text-layer-0-glyph-label active:text-layer-0-glyph-label group-active:text-layer-0-glyph-label focus:text-layer-0-glyph-label group-focus:text-layer-0-glyph-label text-layer-1-glyph active:text-layer-1-glyph group-active:text-layer-1-glyph focus:text-layer-1-glyph group-focus:text-layer-1-glyph text-layer-1-glyph_a active:text-layer-1-glyph_a group-active:text-layer-1-glyph_a focus:text-layer-1-glyph_a group-focus:text-layer-1-glyph_a text-layer-1-glyph_pl active:text-layer-1-glyph_pl group-active:text-layer-1-glyph_pl focus:text-layer-1-glyph_pl group-focus:text-layer-1-glyph_pl text-layer-1-glyph-hl active:text-layer-1-glyph-hl group-active:text-layer-1-glyph-hl focus:text-layer-1-glyph-hl group-focus:text-layer-1-glyph-hl text-layer-1-glyph-hl_a active:text-layer-1-glyph-hl_a group-active:text-layer-1-glyph-hl_a focus:text-layer-1-glyph-hl_a group-focus:text-layer-1-glyph-hl_a text-layer-1-glyph-shade active:text-layer-1-glyph-shade group-active:text-layer-1-glyph-shade focus:text-layer-1-glyph-shade group-focus:text-layer-1-glyph-shade text-layer-1-glyph-label active:text-layer-1-glyph-label group-active:text-layer-1-glyph-label focus:text-layer-1-glyph-label group-focus:text-layer-1-glyph-label text-layer-2-glyph active:text-layer-2-glyph group-active:text-layer-2-glyph focus:text-layer-2-glyph group-focus:text-layer-2-glyph text-layer-2-glyph_a active:text-layer-2-glyph_a group-active:text-layer-2-glyph_a focus:text-layer-2-glyph_a group-focus:text-layer-2-glyph_a text-layer-2-glyph_pl active:text-layer-2-glyph_pl group-active:text-layer-2-glyph_pl focus:text-layer-2-glyph_pl group-focus:text-layer-2-glyph_pl text-layer-2-glyph-hl active:text-layer-2-glyph-hl group-active:text-layer-2-glyph-hl focus:text-layer-2-glyph-hl group-focus:text-layer-2-glyph-hl text-layer-2-glyph-hl_a active:text-layer-2-glyph-hl_a group-active:text-layer-2-glyph-hl_a focus:text-layer-2-glyph-hl_a group-focus:text-layer-2-glyph-hl_a text-layer-2-glyph-shade active:text-layer-2-glyph-shade group-active:text-layer-2-glyph-shade focus:text-layer-2-glyph-shade group-focus:text-layer-2-glyph-shade"></div> +<div class="hidden bg-layer-0-surface active:bg-layer-0-surface group-active:bg-layer-0-surface focus:bg-layer-0-surface group-focus:bg-layer-0-surface border-layer-0-surface active:border-layer-0-surface group-active:border-layer-0-surface focus:border-layer-0-surface group-focus:border-layer-0-surface bg-layer-0-surface_a active:bg-layer-0-surface_a group-active:bg-layer-0-surface_a focus:bg-layer-0-surface_a group-focus:bg-layer-0-surface_a border-layer-0-surface_a active:border-layer-0-surface_a group-active:border-layer-0-surface_a focus:border-layer-0-surface_a group-focus:border-layer-0-surface_a bg-layer-0-surface-edge active:bg-layer-0-surface-edge group-active:bg-layer-0-surface-edge focus:bg-layer-0-surface-edge group-focus:bg-layer-0-surface-edge border-layer-0-surface-edge active:border-layer-0-surface-edge group-active:border-layer-0-surface-edge focus:border-layer-0-surface-edge group-focus:border-layer-0-surface-edge bg-layer-0-surface-blur active:bg-layer-0-surface-blur group-active:bg-layer-0-surface-blur focus:bg-layer-0-surface-blur group-focus:bg-layer-0-surface-blur border-layer-0-surface-blur active:border-layer-0-surface-blur group-active:border-layer-0-surface-blur focus:border-layer-0-surface-blur group-focus:border-layer-0-surface-blur bg-layer-1-surface active:bg-layer-1-surface group-active:bg-layer-1-surface focus:bg-layer-1-surface group-focus:bg-layer-1-surface border-layer-1-surface active:border-layer-1-surface group-active:border-layer-1-surface focus:border-layer-1-surface group-focus:border-layer-1-surface bg-layer-1-surface_a active:bg-layer-1-surface_a group-active:bg-layer-1-surface_a focus:bg-layer-1-surface_a group-focus:bg-layer-1-surface_a border-layer-1-surface_a active:border-layer-1-surface_a group-active:border-layer-1-surface_a focus:border-layer-1-surface_a group-focus:border-layer-1-surface_a bg-layer-1-surface-edge active:bg-layer-1-surface-edge group-active:bg-layer-1-surface-edge focus:bg-layer-1-surface-edge group-focus:bg-layer-1-surface-edge border-layer-1-surface-edge active:border-layer-1-surface-edge group-active:border-layer-1-surface-edge focus:border-layer-1-surface-edge group-focus:border-layer-1-surface-edge bg-layer-1-surface-err active:bg-layer-1-surface-err group-active:bg-layer-1-surface-err focus:bg-layer-1-surface-err group-focus:bg-layer-1-surface-err border-layer-1-surface-err active:border-layer-1-surface-err group-active:border-layer-1-surface-err focus:border-layer-1-surface-err group-focus:border-layer-1-surface-err bg-layer-1-surface-focus active:bg-layer-1-surface-focus group-active:bg-layer-1-surface-focus focus:bg-layer-1-surface-focus group-focus:bg-layer-1-surface-focus border-layer-1-surface-focus active:border-layer-1-surface-focus group-active:border-layer-1-surface-focus focus:border-layer-1-surface-focus group-focus:border-layer-1-surface-focus bg-layer-2-surface active:bg-layer-2-surface group-active:bg-layer-2-surface focus:bg-layer-2-surface group-focus:bg-layer-2-surface border-layer-2-surface active:border-layer-2-surface group-active:border-layer-2-surface focus:border-layer-2-surface group-focus:border-layer-2-surface bg-layer-2-surface_a active:bg-layer-2-surface_a group-active:bg-layer-2-surface_a focus:bg-layer-2-surface_a group-focus:bg-layer-2-surface_a border-layer-2-surface_a active:border-layer-2-surface_a group-active:border-layer-2-surface_a focus:border-layer-2-surface_a group-focus:border-layer-2-surface_a bg-layer-2-surface-edge active:bg-layer-2-surface-edge group-active:bg-layer-2-surface-edge focus:bg-layer-2-surface-edge group-focus:bg-layer-2-surface-edge border-layer-2-surface-edge active:border-layer-2-surface-edge group-active:border-layer-2-surface-edge focus:border-layer-2-surface-edge group-focus:border-layer-2-surface-edge text-layer-0-glyph active:text-layer-0-glyph group-active:text-layer-0-glyph focus:text-layer-0-glyph group-focus:text-layer-0-glyph text-layer-0-glyph_a active:text-layer-0-glyph_a group-active:text-layer-0-glyph_a focus:text-layer-0-glyph_a group-focus:text-layer-0-glyph_a text-layer-0-glyph-hl active:text-layer-0-glyph-hl group-active:text-layer-0-glyph-hl focus:text-layer-0-glyph-hl group-focus:text-layer-0-glyph-hl text-layer-0-glyph-hl_a active:text-layer-0-glyph-hl_a group-active:text-layer-0-glyph-hl_a focus:text-layer-0-glyph-hl_a group-focus:text-layer-0-glyph-hl_a text-layer-0-glyph-shade active:text-layer-0-glyph-shade group-active:text-layer-0-glyph-shade focus:text-layer-0-glyph-shade group-focus:text-layer-0-glyph-shade text-layer-0-glyph-label active:text-layer-0-glyph-label group-active:text-layer-0-glyph-label focus:text-layer-0-glyph-label group-focus:text-layer-0-glyph-label text-layer-1-glyph active:text-layer-1-glyph group-active:text-layer-1-glyph focus:text-layer-1-glyph group-focus:text-layer-1-glyph text-layer-1-glyph_a active:text-layer-1-glyph_a group-active:text-layer-1-glyph_a focus:text-layer-1-glyph_a group-focus:text-layer-1-glyph_a text-layer-1-glyph_pl active:text-layer-1-glyph_pl group-active:text-layer-1-glyph_pl focus:text-layer-1-glyph_pl group-focus:text-layer-1-glyph_pl text-layer-1-glyph-hl active:text-layer-1-glyph-hl group-active:text-layer-1-glyph-hl focus:text-layer-1-glyph-hl group-focus:text-layer-1-glyph-hl text-layer-1-glyph-hl_a active:text-layer-1-glyph-hl_a group-active:text-layer-1-glyph-hl_a focus:text-layer-1-glyph-hl_a group-focus:text-layer-1-glyph-hl_a text-layer-1-glyph-shade active:text-layer-1-glyph-shade group-active:text-layer-1-glyph-shade focus:text-layer-1-glyph-shade group-focus:text-layer-1-glyph-shade text-layer-1-glyph-label active:text-layer-1-glyph-label group-active:text-layer-1-glyph-label focus:text-layer-1-glyph-label group-focus:text-layer-1-glyph-label text-layer-2-glyph active:text-layer-2-glyph group-active:text-layer-2-glyph focus:text-layer-2-glyph group-focus:text-layer-2-glyph text-layer-2-glyph_a active:text-layer-2-glyph_a group-active:text-layer-2-glyph_a focus:text-layer-2-glyph_a group-focus:text-layer-2-glyph_a text-layer-2-glyph_pl active:text-layer-2-glyph_pl group-active:text-layer-2-glyph_pl focus:text-layer-2-glyph_pl group-focus:text-layer-2-glyph_pl text-layer-2-glyph-hl active:text-layer-2-glyph-hl group-active:text-layer-2-glyph-hl focus:text-layer-2-glyph-hl group-focus:text-layer-2-glyph-hl text-layer-2-glyph-hl_a active:text-layer-2-glyph-hl_a group-active:text-layer-2-glyph-hl_a focus:text-layer-2-glyph-hl_a group-focus:text-layer-2-glyph-hl_a text-layer-2-glyph-shade active:text-layer-2-glyph-shade group-active:text-layer-2-glyph-shade focus:text-layer-2-glyph-shade group-focus:text-layer-2-glyph-shade"></div> diff --git a/apps-lib/src/lib/ui/input_element.svelte b/apps-lib/src/lib/ui/input_element.svelte @@ -13,7 +13,6 @@ onMount(async () => { try { - console.log(JSON.stringify(basis, null, 4), `basis`); if (basis.id) { if (basis.sync_init) await kv.set( @@ -63,20 +62,3 @@ await basis.callback_keydown({ key: ev.key }); }} /> - -<!-- - <input - class={`${fmt_cl(basis.classes)} input flex flex-row p-[0px] border-[0px] focus:border-0 outline-[0px] focus:outline-0 text-layer-${layer}-glyph placeholder:text-layer-${layer}-glyph_pl placeholder:font-[300] caret-layer-${layer}-glyph bg-transparent`} - placeholder={basis.placeholder || ``} - value={basis.value} - bind:this={el} - on:input={async (ev) => { - if (basis.callback_value) - await basis.callback_value([ev.currentTarget.value, el]); - }} - on:keydown={async (ev) => { - if (basis.callback_keydown) - await basis.callback_keydown([ev.key, ev.currentTarget.value]); - }} -/> ---> diff --git a/apps-lib/src/lib/ui/textarea_element.svelte b/apps-lib/src/lib/ui/textarea_element.svelte @@ -0,0 +1,64 @@ +<script lang="ts"> + import { type ITextAreaElement, fmt_cl, kv, parse_layer } from "$lib"; + import { onMount } from "svelte"; + + let el: HTMLTextAreaElement | null = null; + + 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 { + if (basis.id) { + if (basis.sync_init) + await kv.set( + basis.id, + typeof basis.sync_init === `string` + ? basis.sync_init + : ``, + ); + if (basis.sync) { + const kv_val = await kv.get(basis.id); + if (kv_val) el.value = kv_val; + else await kv.set(basis.id, ``); + } + } + if (basis.on_mount) await basis.on_mount(el); + } catch (e) {} + }); +</script> + +<textarea + bind:this={el} + {id} + contenteditable="true" + class={`${fmt_cl(basis.classes)} form-textarea bg-layer-${layer}-surface text-layer-${layer}-glyph placeholder:text-layer-${layer}-glyph_pl caret-layer-${layer}-glyph`} + placeholder={basis.placeholder || ""} + on:input={async ({ currentTarget: el }) => { + let pass = true; + let val = el.value; + if (basis.field) { + val = el.value + .split("") + .filter((char) => basis.field.charset.test(char)) + .join(""); + if ( + !basis.field.validate.test(val) && + basis.field.validate_keypress + ) { + pass = false; + } + } + el.value = val; + if (basis.sync) await kv.set(basis.id, val); + if (basis.callback) await basis.callback({ val, pass }); + }} + on:keydown={async (ev) => { + if (basis.callback_keydown) + await basis.callback_keydown({ key: ev.key }); + }} +/>