web_lib

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

commit febf3469932e19d3898042beea887a23b4e914dd
parent aa4fdf81fe99a5d56b27dd9f899839cc7df7083a
Author: triesap <137732411+triesap@users.noreply.github.com>
Date:   Sun, 27 Oct 2024 14:30:51 +0000

apps-lib: edit entry multiline basis type. add handler functions to input and multiline elements. add value constrain textarea util to handle non breaking spaces

Diffstat:
Mapps-lib/src/lib/components/entry_multiline.svelte | 4++--
Mapps-lib/src/lib/el/input_element.svelte | 50+++++++++++++++++++++++++++++++++-----------------
Mapps-lib/src/lib/el/textarea_element.svelte | 58+++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Mapps-lib/src/lib/locales/en/common.json | 1+
Mapps-lib/src/lib/types/components.ts | 5+++--
Mapps-lib/src/lib/types/el.ts | 3++-
Mapps-lib/src/lib/utils/client.ts | 9+++++++++
7 files changed, 107 insertions(+), 23 deletions(-)

diff --git a/apps-lib/src/lib/components/entry_multiline.svelte b/apps-lib/src/lib/components/entry_multiline.svelte @@ -21,8 +21,8 @@ </script> <div - id={basis.id_wrap || null} - class={`${fmt_cl(basis.classes_wrap)} relative el-re entry-textarea-wrap ${classes_layer}`} + 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} diff --git a/apps-lib/src/lib/el/input_element.svelte b/apps-lib/src/lib/el/input_element.svelte @@ -19,6 +19,14 @@ onMount(async () => { try { + await kv_init(); + } catch (e) { + console.log(`e input mount`, e); + } + }); + + const kv_init = async (): Promise<void> => { + try { if (basis?.id) { if (basis?.sync_init) await kv.set( @@ -35,9 +43,31 @@ } if (basis?.on_mount) await basis?.on_mount(el); } catch (e) { - console.log(`e input mount`, e); + console.log(`(error) kv_init `, e); } - }); + }; + + const handle_on_input = async (el: HTMLInputElement): Promise<void> => { + try { + let pass = true; + let val = el?.value; + if (basis?.field && el) { + val = value_constrain(basis?.field.charset, val); + el.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> <input @@ -47,21 +77,7 @@ class={`${fmt_cl(basis?.classes)} el-input 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 && el) { - val = value_constrain(basis?.field.charset, val); - el.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 }); + await handle_on_input(el); }} on:keydown={async (ev) => { if (basis?.callback_keydown) diff --git a/apps-lib/src/lib/el/textarea_element.svelte b/apps-lib/src/lib/el/textarea_element.svelte @@ -1,5 +1,11 @@ <script lang="ts"> - import { type ITextAreaElement, fmt_cl, kv, parse_layer } from "$lib"; + import { + type ITextAreaElement, + fmt_cl, + kv, + parse_layer, + value_constrain_textarea, + } from "$lib"; import { onMount } from "svelte"; let el: HTMLTextAreaElement | null = null; @@ -13,6 +19,8 @@ onMount(async () => { try { + await kv_init(); + /* if (basis.id) { if (basis.sync_init) await kv.set( @@ -28,8 +36,53 @@ } } if (basis.on_mount) await basis.on_mount(el); + */ } catch (e) {} }); + + const kv_init = async (): Promise<void> => { + 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) el.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 = 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 @@ -39,6 +92,8 @@ 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 || ""} on:input={async ({ currentTarget: el }) => { + await handle_on_input(el); + /* let pass = true; let val = el.value; if (basis.field) { @@ -56,6 +111,7 @@ 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) diff --git a/apps-lib/src/lib/locales/en/common.json b/apps-lib/src/lib/locales/en/common.json @@ -70,6 +70,7 @@ "page": "Page", "per": "Per", "personal": "Personal", + "photo": "Photo", "photos": "Photos", "post": "Post", "preview": "Preview", diff --git a/apps-lib/src/lib/types/components.ts b/apps-lib/src/lib/types/components.ts @@ -1,4 +1,4 @@ -import type { CallbackPromise, CallbackPromiseGeneric, GlyphKey, GlyphWeight, ICb, ICbG, ICbGOpt, ICbOpt, IClOpt, IClWrapOpt, IGl, IGlOpt, IGlyph, IIdOpt, IIdWrapOpt, IInputElement, ILabel, ILabelFieldsOpt, ILabelOpt, ILabelOptFieldsOpt, ILabelValue, ILoadingOpt, ILyOpt, ILyOptTs, ITextAreaElement, NavigationParamTuple, NavigationRoute } from "$lib"; +import type { CallbackPromise, CallbackPromiseGeneric, GlyphKey, GlyphWeight, ICb, ICbG, ICbGOpt, ICbOpt, IClOpt, IGl, IGlOpt, IGlyph, IIdOpt, IIdWrapOpt, IInputElement, ILabel, ILabelFieldsOpt, ILabelOpt, ILabelOptFieldsOpt, ILabelValue, ILoadingOpt, ILyOpt, ILyOptTs, ITextAreaElement, NavigationParamTuple, NavigationRoute } from "$lib"; export type ITabsBasisList = IClOpt & { icon: GlyphKey; @@ -38,7 +38,8 @@ export type IEntryLine = ILoadingOpt & { -export type IEntryMultiLine = IIdWrapOpt & IClWrapOpt & { +export type IEntryMultiLine = { + wrap?: IEntryWrap; el: ITextAreaElement; notify_inline?: { glyph: GlyphKey | IGlyph; diff --git a/apps-lib/src/lib/types/el.ts b/apps-lib/src/lib/types/el.ts @@ -4,6 +4,7 @@ import type { ThemeLayer } from "@radroots/theme"; export type GlyphKeyCurrency = `dollar` | `eur`; export type GlyphKey = | + `image-broken` | `funnel` | `users-three` | `note-blank` | @@ -171,7 +172,7 @@ export type ITextAreaElement = IId & IClOpt & ILyOptTs & { /*notify_inline?: { glyph: GlyphKey | IGlyph; };*/ - callback?: CallbackPromiseGeneric<{ val: string; pass: boolean; }>; + callback?: CallbackPromiseGeneric<{ value: 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/utils/client.ts b/apps-lib/src/lib/utils/client.ts @@ -174,6 +174,15 @@ export const value_constrain = (regex_charset: RegExp, value: string): string => .join(""); }; +export const value_constrain_textarea = (regex_charset: RegExp, value: string): string => { + return value + .replace(/\u00A0/g, ` `) + .split("") + .filter((char) => regex_charset.test(char)) + .join("") + .replace(/ /g, `\u00A0`); +}; + export const parse_cfg_type = (value?: string): AppConfigType => { switch (value) { case `farmer`: