web_lib

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

commit 7c03b931d4ad30756f49ada8eaaeea67d26c792b
parent b5e6740c36dae4c42d79426a3e96406faade370e
Author: triesap <137732411+triesap@users.noreply.github.com>
Date:   Fri, 25 Oct 2024 11:46:01 +0000

apps-lib: add exe iter util and update carousel increment and decrement utils. edit loading el adding 8 blade default style. edit layout trellis line basis. add/edit locales, stores, utils, styles, types

Diffstat:
Mapps-lib/src/lib/components/button_arrow.svelte | 4++--
Rapps-lib/src/lib/ui/glyph.svelte -> apps-lib/src/lib/components/button_glyph.svelte | 0
Mapps-lib/src/lib/components/entry_option.svelte | 7+++----
Mapps-lib/src/lib/components/envelope_titled.svelte | 4++--
Mapps-lib/src/lib/components/layout_trellis_line.svelte | 82++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Mapps-lib/src/lib/components/layout_window.svelte | 2+-
Mapps-lib/src/lib/components/trellis_input.svelte | 2+-
Mapps-lib/src/lib/components/trellis_offset.svelte | 2+-
Mapps-lib/src/lib/components/trellis_row_label.svelte | 6+++---
Mapps-lib/src/lib/components/trellis_title.svelte | 2+-
Mapps-lib/src/lib/components/trellis_touch.svelte | 4++--
Rapps-lib/src/lib/ui/blur.svelte -> apps-lib/src/lib/el/blur.svelte | 0
Rapps-lib/src/lib/ui/css_static.svelte -> apps-lib/src/lib/el/css_static.svelte | 0
Rapps-lib/src/lib/ui/css_styles.svelte -> apps-lib/src/lib/el/css_styles.svelte | 0
Rapps-lib/src/lib/ui/divider.svelte -> apps-lib/src/lib/el/divider.svelte | 0
Rapps-lib/src/lib/ui/fill.svelte -> apps-lib/src/lib/el/fill.svelte | 0
Rapps-lib/src/lib/ui/fill_white.svelte -> apps-lib/src/lib/el/fill_white.svelte | 0
Rapps-lib/src/lib/ui/glyph_el.svelte -> apps-lib/src/lib/el/glyph.svelte | 0
Aapps-lib/src/lib/el/glyph_circle.svelte | 22++++++++++++++++++++++
Rapps-lib/src/lib/ui/input_element.svelte -> apps-lib/src/lib/el/input_element.svelte | 0
Rapps-lib/src/lib/ui/label_swap.svelte -> apps-lib/src/lib/el/label_swap.svelte | 0
Aapps-lib/src/lib/el/loading.svelte | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rapps-lib/src/lib/ui/select_element.svelte -> apps-lib/src/lib/el/select_element.svelte | 0
Rapps-lib/src/lib/ui/textarea_element.svelte -> apps-lib/src/lib/el/textarea_element.svelte | 0
Rapps-lib/src/lib/ui/toast.svelte -> apps-lib/src/lib/el/toast.svelte | 0
Mapps-lib/src/lib/index.ts | 32++++++++++++++++----------------
Mapps-lib/src/lib/locales/en/common.json | 8+++++++-
Mapps-lib/src/lib/locales/en/error.json | 4++--
Mapps-lib/src/lib/locales/en/icu.json | 5++++-
Mapps-lib/src/lib/locales/en/model.json | 24++++++++++++------------
Mapps-lib/src/lib/stores/client.ts | 1+
Mapps-lib/src/lib/types/client.ts | 1+
Aapps-lib/src/lib/types/el.ts | 180+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dapps-lib/src/lib/types/ui.ts | 180-------------------------------------------------------------------------------
Dapps-lib/src/lib/ui/glyph_circle.svelte | 17-----------------
Dapps-lib/src/lib/ui/loading.svelte | 58----------------------------------------------------------
Mapps-lib/src/lib/utils/carousel.ts | 30++++++++++++++++++++++++------
Mapps-lib/src/lib/utils/client.ts | 68+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Mapps-lib/src/lib/utils/routes.ts | 2++
39 files changed, 464 insertions(+), 347 deletions(-)

diff --git a/apps-lib/src/lib/components/button_arrow.svelte b/apps-lib/src/lib/components/button_arrow.svelte @@ -1,5 +1,5 @@ <script lang="ts"> - import { GlyphEl, type CallbackPromise } from "$lib"; + import { Glyph, type CallbackPromise } from "$lib"; import { onDestroy, onMount } from "svelte"; export let basis: { @@ -40,7 +40,7 @@ await basis.callback(); }} > - <GlyphEl + <Glyph basis={{ classes: `text-layer-0-glyph`, dim: `sm`, diff --git a/apps-lib/src/lib/ui/glyph.svelte b/apps-lib/src/lib/components/button_glyph.svelte diff --git a/apps-lib/src/lib/components/entry_option.svelte b/apps-lib/src/lib/components/entry_option.svelte @@ -31,14 +31,13 @@ }); </script> -<div +<button id={basis.id_wrap || null} - tabindex={-1} class={`${fmt_cl(basis.classes_wrap)} relative el-re entry-line-wrap ${classes_layer}`} > {#if basis.loading} <div class={`flex flex-row w-full justify-center items-center`}> - <Loading basis={{ dim: `sm`, blades: 6 }} /> + <Loading basis={{ dim: `sm`, blades: 8 }} /> </div> {:else} <select @@ -77,4 +76,4 @@ /> </div> {/if} -</div> +</button> diff --git a/apps-lib/src/lib/components/envelope_titled.svelte b/apps-lib/src/lib/components/envelope_titled.svelte @@ -1,9 +1,9 @@ <script lang="ts"> import { + ButtonGlyph, type CallbackPromise, Fill, fmt_cl, - Glyph, type IEnvelopeTitledBasis, t, } from "$lib"; @@ -68,7 +68,7 @@ }} > {#if `glyph` in basis.submit} - <Glyph basis={basis.submit?.glyph} /> + <ButtonGlyph basis={basis.submit?.glyph} /> {:else if `label` in basis.submit} <p class={`font-sans text-envelopeTitleAction ${classes_submit} transition-all`} diff --git a/apps-lib/src/lib/components/layout_trellis_line.svelte b/apps-lib/src/lib/components/layout_trellis_line.svelte @@ -1,46 +1,56 @@ <script lang="ts"> - import { fmt_cl, type ICb, type IClOpt, type ILabel } from "$lib"; + import { + fmt_cl, + type ICb, + type IClOpt, + type ILabel, + type ILabelOpt, + } from "$lib"; - export let basis: ILabel & - IClOpt & { - notify?: IClOpt & ICb & ILabel; - }; + export let basis: + | (ILabelOpt & + IClOpt & { + notify?: IClOpt & ICb & ILabel; + }) + | undefined = undefined; $: basis = basis; </script> <div - class={`${fmt_cl(basis.classes)} flex flex-col w-trellis_line gap-[0.375rem] justify-start items-center`} + class={`${fmt_cl(basis?.classes)} 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`} - > - {basis.label.value} - </p> - {/if} - {#if basis.notify} - <div - class={`${fmt_cl(basis.notify.classes)} flex flex-row justify-start items-center fade-in transition-all`} - > - <button - class={`flex flex-row justify-center items-center`} - on:click={async () => { - await basis.notify?.callback(); - }} + {#if (basis?.label && `value` in basis?.label) || basis?.notify} + <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`} > - {#if `value` in basis.notify.label} - <p - class={`${fmt_cl(basis.notify.label.classes)} font-sans font-[500] uppercase text-layer-2-glyph/80 text-xs`} - > - {basis.notify.label.value} - </p> - {/if} - </button> - </div> - {/if} - </div> + {basis?.label.value} + </p> + {/if} + {#if basis?.notify} + <div + class={`${fmt_cl(basis?.notify.classes)} flex flex-row justify-start items-center fade-in transition-all`} + > + <button + class={`flex flex-row justify-center items-center`} + on:click={async () => { + await basis?.notify?.callback(); + }} + > + {#if `value` in basis?.notify.label} + <p + class={`${fmt_cl(basis?.notify.label.classes)} font-sans font-[500] uppercase text-layer-2-glyph/80 text-xs`} + > + {basis?.notify.label.value} + </p> + {/if} + </button> + </div> + {/if} + </div> + {/if} <slot /> </div> diff --git a/apps-lib/src/lib/components/layout_window.svelte b/apps-lib/src/lib/components/layout_window.svelte @@ -3,7 +3,7 @@ </script> <div - class={`relative flex flex-col h-[100vh] w-full overflow-x-hidden overflow-y-hidden bg-layer-0-surface ${$app_tilt ? `scale-[96%] translate-y-4 rounded-t-[3.5rem]` : ``} delay-75 duration-200 ease-in-out transition-all`} + class={`relative flex flex-col h-[100vh] w-full overflow-x-hidden overflow-y-hidden bg-layer-0-surface ${$app_tilt ? `scale-[96%] translate-y-4 rounded-t-[3.5rem]` : ``} delay-75 duration-200 el-re`} > <div class={`flex flex-col h-full w-full`}> <slot /> diff --git a/apps-lib/src/lib/components/trellis_input.svelte b/apps-lib/src/lib/components/trellis_input.svelte @@ -47,7 +47,7 @@ <Loading basis={{ dim: `glyph-send-button`, - blades: 6, + blades: 8, classes: `text-layer-${layer}-glyph transition-all`, }} /> diff --git a/apps-lib/src/lib/components/trellis_offset.svelte b/apps-lib/src/lib/components/trellis_offset.svelte @@ -41,7 +41,7 @@ }} > {#if mod.loading} - <Loading basis={{ blades: 6, dim: `xs` }} /> + <Loading basis={{ blades: 8, dim: `xs` }} /> {:else if `glyph` in mod} <Glyph basis={{ diff --git a/apps-lib/src/lib/components/trellis_row_label.svelte b/apps-lib/src/lib/components/trellis_row_label.svelte @@ -1,8 +1,8 @@ <script lang="ts"> import { + ButtonGlyph, fmt_cl, get_label_classes, - Glyph, type ILabelTupFields, } from "$lib"; import type { ThemeLayer } from "@radroots/theme"; @@ -25,7 +25,7 @@ <div class={`flex flex-row justify-start items-center pr-2`} > - <Glyph basis={{ ...title_l.glyph }} /> + <ButtonGlyph basis={{ ...title_l.glyph }} /> </div> {:else if `value` in title_l} <p @@ -47,7 +47,7 @@ class={`${fmt_cl(title_r.classes_wrap)} flex flex-row h-full w-trellis_value gap-1 items-center ${title_r.hide_truncate ? `` : `truncate`}`} > {#if `glyph` in title_r} - <Glyph basis={{ ...title_r.glyph }} /> + <ButtonGlyph basis={{ ...title_r.glyph }} /> {:else if `value` in title_r} <p class={`${fmt_cl(title_r.classes)} ${get_label_classes(layer, title_r.kind, hide_active)} ${title_r.hide_truncate ? `` : `truncate`} font-sans text-line_display transition-all`} diff --git a/apps-lib/src/lib/components/trellis_title.svelte b/apps-lib/src/lib/components/trellis_title.svelte @@ -3,7 +3,7 @@ import type { ThemeLayer } from "@radroots/theme"; export let basis: ITrellisTitle; - export let layer: ThemeLayer; + export let layer: ThemeLayer = 0; $: mod = basis && basis.mod ? basis.mod : `sm`; </script> diff --git a/apps-lib/src/lib/components/trellis_touch.svelte b/apps-lib/src/lib/components/trellis_touch.svelte @@ -18,10 +18,10 @@ <div class={`flex flex-row flex-grow overflow-x-hidden`}> <div - class={`${fmt_trellis(hide_border_b, hide_border_t)} flex flex-row h-full w-full justify-center items-center border-t-line border-layer-${layer}-surface-edge/40 transition-all`} + class={`${fmt_trellis(hide_border_b, hide_border_t)} flex flex-row h-full w-full justify-center items-center border-t-line border-layer-${layer}-surface-edge el-re`} > <button - class={`relative group flex flex-row h-line w-full pr-[2px] justify-between items-center transition-all`} + class={`relative group flex flex-row h-line w-full pr-[2px] justify-between items-center el-re`} on:click={async (ev) => { await sleep(100); if (basis.callback) await basis.callback(ev); diff --git a/apps-lib/src/lib/ui/blur.svelte b/apps-lib/src/lib/el/blur.svelte diff --git a/apps-lib/src/lib/ui/css_static.svelte b/apps-lib/src/lib/el/css_static.svelte diff --git a/apps-lib/src/lib/ui/css_styles.svelte b/apps-lib/src/lib/el/css_styles.svelte diff --git a/apps-lib/src/lib/ui/divider.svelte b/apps-lib/src/lib/el/divider.svelte diff --git a/apps-lib/src/lib/ui/fill.svelte b/apps-lib/src/lib/el/fill.svelte diff --git a/apps-lib/src/lib/ui/fill_white.svelte b/apps-lib/src/lib/el/fill_white.svelte diff --git a/apps-lib/src/lib/ui/glyph_el.svelte b/apps-lib/src/lib/el/glyph.svelte diff --git a/apps-lib/src/lib/el/glyph_circle.svelte b/apps-lib/src/lib/el/glyph_circle.svelte @@ -0,0 +1,22 @@ +<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 transition-all`} + > + <ButtonGlyph basis={basis?.glyph} /> + </div> +{/if} diff --git a/apps-lib/src/lib/ui/input_element.svelte b/apps-lib/src/lib/el/input_element.svelte diff --git a/apps-lib/src/lib/ui/label_swap.svelte b/apps-lib/src/lib/el/label_swap.svelte diff --git a/apps-lib/src/lib/el/loading.svelte b/apps-lib/src/lib/el/loading.svelte @@ -0,0 +1,64 @@ +<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 transition-all`} +> + <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/ui/select_element.svelte b/apps-lib/src/lib/el/select_element.svelte diff --git a/apps-lib/src/lib/ui/textarea_element.svelte b/apps-lib/src/lib/el/textarea_element.svelte diff --git a/apps-lib/src/lib/ui/toast.svelte b/apps-lib/src/lib/el/toast.svelte diff --git a/apps-lib/src/lib/index.ts b/apps-lib/src/lib/index.ts @@ -1,25 +1,24 @@ export * from "./locales/i18n"; -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 GlyphEl } from "./ui/glyph_el.svelte"; -export { default as Divider } from "./ui/divider.svelte"; -export { default as LabelSwap } from "./ui/label_swap.svelte"; -export { default as Glyph } from "./ui/glyph.svelte"; -export { default as CssStyles } from "./ui/css_styles.svelte"; -export { default as Loading } from "./ui/loading.svelte"; -export { default as InputElement } from "./ui/input_element.svelte"; -export { default as Fill } from "./ui/fill.svelte"; -export { default as FillWhite } from "./ui/fill_white.svelte"; export * from "./types/trellis"; export * from "./types/components"; export * from "./types/client"; export * from "./types/conf"; -export * from "./types/ui"; +export * from "./types/el"; export * from "./types/nostr"; +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 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 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 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 * from "./stores/client"; export * from "./utils/routes"; @@ -33,6 +32,7 @@ export * from "./utils/geo"; export { default as EnvelopeLower } from "./components/envelope_lower.svelte"; export { default as TrellisInput } from "./components/trellis_input.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 LayoutTrellis } from "./components/layout_trellis.svelte"; diff --git a/apps-lib/src/lib/locales/en/common.json b/apps-lib/src/lib/locales/en/common.json @@ -1,5 +1,4 @@ { - "do_you_want_to_continue_q": "Do you want to continue?", "accept": "Accept", "activation": "Activation", "active": "Active", @@ -26,6 +25,7 @@ "device": "Device", "disagree": "Disagree", "disconnect": "Disconnect", + "do_you_want_to_continue_q": "Do you want to continue?", "done": "Done", "edit": "Edit", "end_date": "End date", @@ -39,10 +39,12 @@ "key": "Key", "keypair": "Keypair", "keys": "Keys", + "latitude": "Latitude", "list": "List", "listing": "Listing", "location": "Location", "locations": "Locations", + "longitude": "Longitude", "lot": "Lot", "lot_name": "Lot name", "lowest_price": "Lowest price", @@ -59,7 +61,9 @@ "npub": "Npub", "nsec": "Nsec", "optional": "Optional", + "options": "Options", "options_list": "Options list", + "origin": "Origin", "other": "Other", "outflows": "Outflows", "overview": "Overview", @@ -79,11 +83,13 @@ "profile_name": "Profile name", "profiles": "Profiles", "public_key": "Public key", + "publish": "Publish", "quantity": "Quantity", "quit": "Quit", "relay": "Relay", "relays": "Relays", "reset": "Reset", + "return": "Return", "review": "Review", "secret_key": "Secret key", "settings": "Settings", diff --git a/apps-lib/src/lib/locales/en/error.json b/apps-lib/src/lib/locales/en/error.json @@ -2,10 +2,10 @@ "client": { "network_failure": "The requested resource is not available", "page": { + "load": "There was an error loading the page", "status": { "404": "The page was not found" - }, - "load": "There was an error loading the page" + } }, "request_failure": "The request was not successful", "unhandled": "There was an error during your request" diff --git a/apps-lib/src/lib/locales/en/icu.json b/apps-lib/src/lib/locales/en/icu.json @@ -1,11 +1,11 @@ { - "*_list": "{value} list", "*_as": "{value} as", "*_available": "{value} Available", "*_copied": "{value} copied", "*_description": "{value} description", "*_details": "{value} details", "*_failure": "{value} failure", + "*_list": "{value} list", "*_name": "{value} name", "*_summary": "{value} summary", "*_title": "{value} title", @@ -20,6 +20,7 @@ "connect_*": "Connect {value}", "connected_*": "Connected {value}", "create_new_*": "Create new {value}", + "default_*": "Default {value}", "delete_*": "Delete {value}", "disconnect_*": "Disconnect {value}", "edit_*": "Edit {value}", @@ -29,6 +30,7 @@ "enter_number_of_*_per_order": "Enter number of {value} per order", "enter_the_*": "Enter the {value}", "error_loading_*": "Error loading {value}", + "failure_saving_*_to_the_database": "Failure saving {value} to the database", "go_*": "Go {value}", "invalid_*": "Invalid {value}", "invalid_*_entry": "Invalid {value} entry", @@ -45,6 +47,7 @@ "post_*": "Post {value}", "set_as_*": "Set as {value}", "show_*": "Show {value}", + "the_*": "The {value}", "the_*_is_available": "The {value} is available", "the_*_is_missing": "The {value} is missing", "the_*_is_registered": "The {value} is registered", diff --git a/apps-lib/src/lib/locales/en/model.json b/apps-lib/src/lib/locales/en/model.json @@ -1,15 +1,15 @@ { "location_gcs": { - "geohash": "Geohash", - "label": "Label", - "lat": "Latitude", - "lng": "Longitude", - "gc_id": "", - "gc_name": "", "gc_admin1_id": "", "gc_admin1_name": "", "gc_country_id": "", - "gc_country_name": "" + "gc_country_name": "", + "gc_id": "", + "gc_name": "", + "geohash": "Geohash", + "label": "Label", + "lat": "Latitude", + "lng": "Longitude" }, "nostr_profile": { "about": "About", @@ -29,11 +29,11 @@ "description": "Relay description", "name": "Relay name", "pubkey": "Administrator", + "relay_id": "", "software": "Software", "supported_nips": "Supported NIPs", "url": "Relay endpoint", - "version": "Software version", - "relay_id": "" + "version": "Software version" }, "trade_product": { "key": "Product name", @@ -41,6 +41,8 @@ "notes": "Notes", "price_amt": "Price", "price_currency": "Currency", + "price_qty_amt": "", + "price_qty_unit": "", "process": "Processing method", "profile": "Flavor profile", "qty_amt": "Quantity", @@ -49,8 +51,6 @@ "qty_unit": "Quantity unit", "summary": "Listing summary", "title": "Listing title", - "year": "Year", - "price_qty_amt": "", - "price_qty_unit": "" + "year": "Year" } } \ No newline at end of file diff --git a/apps-lib/src/lib/stores/client.ts b/apps-lib/src/lib/stores/client.ts @@ -48,6 +48,7 @@ export const tabs_active = writable<number>(0); export const carousel_active = writable<boolean>(false); export const carousel_index = writable<number>(0); export const carousel_index_max = writable<number>(0); +export const carousel_num = writable<number>(1); export const nostr_ndk_configured = writable<boolean>(false); export const nostr_relays_poll_documents = writable<boolean>(false); diff --git a/apps-lib/src/lib/types/client.ts b/apps-lib/src/lib/types/client.ts @@ -191,3 +191,4 @@ export type IToast = IClOpt & }; export type AppConfigType = `farmer` | `personal` +export type GeolocationLatitudeFmtOption = 'dms' | 'd' | 'dm'; diff --git a/apps-lib/src/lib/types/el.ts b/apps-lib/src/lib/types/el.ts @@ -0,0 +1,179 @@ +import type { CallbackPromiseGeneric, GeometryCardinalDirection, GeometryDimension, GeometryGlyphDimension, ICbGOpt, ICbOpt, IClOpt, IFormField, IId, IIdOpt, ILy, ILyOptTs } from "$lib"; +import type { ThemeLayer } from "@radroots/theme"; + +export type GlyphKeyCurrency = `dollar` | `eur`; + +export type GlyphKey = | + `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-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 IGlyph = ICbOpt & IIdOpt & { + layer?: ThemeLayer; + classes?: string; + 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 ISelectOption<T extends string> = { + value: T; + label: string; + disabled?: boolean; +}; + +export type ISelectElement = ILy & + ICbGOpt<ISelectOption<string>> & { + id?: string; + classes?: string; + mask?: boolean; + options: { group?: string | true; entries: ISelectOption<string>[] }[]; + }; + +export type IInputElement = IId & IClOpt & ILyOptTs & { + placeholder?: string; + label?: string; + hidden?: boolean; + validate?: RegExp; + sync?: true; + sync_init?: true | string; + field?: IFormField; + /*notify_inline?: { + glyph: GlyphKey | IGlyph; + };*/ + callback?: CallbackPromiseGeneric<{ value: string; pass: boolean; }>; + callback_keydown?: CallbackPromiseGeneric<{ key: string; el: HTMLInputElement }>; + on_mount?: CallbackPromiseGeneric<HTMLInputElement>; +}; + +export type ITextAreaElement = IId & IClOpt & ILyOptTs & { + 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/types/ui.ts b/apps-lib/src/lib/types/ui.ts @@ -1,179 +0,0 @@ -import type { CallbackPromiseGeneric, GeometryCardinalDirection, GeometryDimension, GeometryGlyphDimension, ICbGOpt, ICbOpt, IClOpt, IFormField, IId, IIdOpt, ILy, ILyOptTs } from "$lib"; -import type { ThemeLayer } from "@radroots/theme"; - -export type GlyphKeyCurrency = `dollar` | `eur`; - -export type GlyphKey = | - `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-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 IGlyph = ICbOpt & IIdOpt & { - layer?: ThemeLayer; - classes?: string; - weight?: GlyphWeight; - key: GlyphKey; - dim?: GeometryGlyphDimension; -}; - -export type IGlyphCircle = { - classes_wrap: string; - glyph: IGlyph -}; - -export type ILoadingBlades = 6 | 12; - -export type ILoadingDimension = GeometryDimension | `glyph-send-button`; - -export type ILoading = { - classes?: string; - color?: 'white'; - blades?: ILoadingBlades; - dim?: ILoadingDimension; -}; - -export type ISelectOption<T extends string> = { - value: T; - label: string; - disabled?: boolean; -}; - -export type ISelectElement = ILy & - ICbGOpt<ISelectOption<string>> & { - id?: string; - classes?: string; - mask?: boolean; - options: { group?: string | true; entries: ISelectOption<string>[] }[]; - }; - -export type IInputElement = IId & IClOpt & ILyOptTs & { - placeholder?: string; - label?: string; - hidden?: boolean; - validate?: RegExp; - sync?: true; - sync_init?: true | string; - field?: IFormField; - /*notify_inline?: { - glyph: GlyphKey | IGlyph; - };*/ - callback?: CallbackPromiseGeneric<{ value: string; pass: boolean; }>; - callback_keydown?: CallbackPromiseGeneric<{ key: string; el: HTMLInputElement }>; - on_mount?: CallbackPromiseGeneric<HTMLInputElement>; -}; - -export type ITextAreaElement = IId & IClOpt & ILyOptTs & { - 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/glyph_circle.svelte b/apps-lib/src/lib/ui/glyph_circle.svelte @@ -1,17 +0,0 @@ -<script lang="ts"> - import { type IGlyphCircle, fmt_cl, Glyph, 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 transition-all`} - > - <Glyph basis={basis?.glyph} /> - </div> -{/if} diff --git a/apps-lib/src/lib/ui/loading.svelte b/apps-lib/src/lib/ui/loading.svelte @@ -1,58 +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 || 12; -</script> - -<div - class={`relative flex flex-row justify-center items-center h-[${styles?.dim_1}px] w-[${styles?.dim_1}px] fade-in transition-all`} -> - <div - class={`${num_blades === 12 ? `spinner12 center` : `spinner6 center`} text-[${styles?.gl_2 || styles?.dim_1}px]`} - > - <div - class={`${num_blades === 12 ? `spinner12-blade` : `spinner6-blade`}`} - /> - <div - class={`${num_blades === 12 ? `spinner12-blade` : `spinner6-blade`}`} - /> - <div - class={`${num_blades === 12 ? `spinner12-blade` : `spinner6-blade`}`} - /> - <div - class={`${num_blades === 12 ? `spinner12-blade` : `spinner6-blade`}`} - /> - <div - class={`${num_blades === 12 ? `spinner12-blade` : `spinner6-blade`}`} - /> - <div - class={`${num_blades === 12 ? `spinner12-blade` : `spinner6-blade`}`} - /> - {#if num_blades === 12} - <div - class={`${num_blades === 12 ? `spinner12-blade` : `spinner6-blade`}`} - /> - <div - class={`${num_blades === 12 ? `spinner12-blade` : `spinner6-blade`}`} - /> - <div - class={`${num_blades === 12 ? `spinner12-blade` : `spinner6-blade`}`} - /> - <div - class={`${num_blades === 12 ? `spinner12-blade` : `spinner6-blade`}`} - /> - <div - class={`${num_blades === 12 ? `spinner12-blade` : `spinner6-blade`}`} - /> - <div - class={`${num_blades === 12 ? `spinner12-blade` : `spinner6-blade`}`} - /> - {/if} - </div> -</div> diff --git a/apps-lib/src/lib/utils/carousel.ts b/apps-lib/src/lib/utils/carousel.ts @@ -2,11 +2,12 @@ import { carousel_active, carousel_index, carousel_index_max, - sleep + carousel_num, + exe_iter } from "$lib"; import { get as get_store } from 'svelte/store'; -const SLIDE_DURATION_MS = 400; +const CAROUSEL_DELAY_MS = 150; const get_slide_container = <T extends string>( view: T, @@ -22,7 +23,7 @@ const get_slide_item = <T extends string>(view: T): Element | undefined => { return el ? el : undefined; }; -export const carousel_prev = async <T extends string>( +const carousel_dec_handler = async <T extends string>( view: T, ): Promise<void> => { if (get_store(carousel_active)) return; @@ -34,11 +35,10 @@ export const carousel_prev = async <T extends string>( slide_container.scrollLeft -= slide_w; carousel_index.set(Math.max(get_store(carousel_index) - 1, 0)); } - await sleep(SLIDE_DURATION_MS); carousel_active.set(false); }; -export const carousel_next = async <T extends string>( +const carousel_inc_handler = async <T extends string>( view: T, ): Promise<void> => { if (get_store(carousel_active)) return; @@ -52,6 +52,24 @@ export const carousel_next = async <T extends string>( Math.min(get_store(carousel_index) + 1, get_store(carousel_index_max)), ); } - await sleep(SLIDE_DURATION_MS); carousel_active.set(false); }; + +export const carousel_inc = async <T extends string>( + view: T, + duration: number = CAROUSEL_DELAY_MS +): Promise<void> => { + const num = get_store(carousel_num) || 1; + carousel_num.set(1); + await exe_iter(async () => carousel_inc_handler(view), num, duration); +}; + + +export const carousel_dec = async <T extends string>( + view: T, + duration: number = CAROUSEL_DELAY_MS +): Promise<void> => { + const num = get_store(carousel_num) || 1; + carousel_num.set(1); + await exe_iter(async () => carousel_dec_handler(view), num, duration); +}; diff --git a/apps-lib/src/lib/utils/client.ts b/apps-lib/src/lib/utils/client.ts @@ -1,8 +1,10 @@ import { goto } from "$app/navigation"; -import { app_toast, nav_prev, TOAST_MS, type AnchorRoute, type AppConfigType, type AppLayoutKey, type CallbackPromise, type CallbackPromiseGeneric, type GlyphKey, type IToast, type LabelFieldKind, type NavigationParamTuple, type NavigationRoute, type NavigationRouteParamKey } from "$lib"; +import { app_toast, locale, nav_prev, TOAST_MS, type AnchorRoute, type AppConfigType, type AppLayoutKey, type CallbackPromise, type CallbackPromiseGeneric, type GeolocationLatitudeFmtOption, type GlyphKey, type IToast, type LabelFieldKind, type NavigationParamTuple, type NavigationRoute, type NavigationRouteParamKey } from "$lib"; import type { ColorMode, ThemeKey, ThemeLayer } from "@radroots/theme"; + import { get as get_store } from "svelte/store"; + export const sleep = async (ms: number): Promise<void> => { await new Promise((resolve) => setTimeout(resolve, ms)); }; @@ -199,3 +201,67 @@ export const route_prev = async (route_fallback: NavigationRoute = `/`, params_f console.log(`(error) route_prev `, e); } }; + +export const fmt_geol_latitude = (lat: number, fmt_opt: GeolocationLatitudeFmtOption): 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: 5 })}° ${lat >= 0 ? 'N' : 'S'}`; + } +}; + +export const fmt_geol_longitude = (lng: number, fmt_opt: GeolocationLatitudeFmtOption): 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: 5 })}° ${lng >= 0 ? 'E' : 'W'}`; + } +}; + +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); + } +}; diff --git a/apps-lib/src/lib/utils/routes.ts b/apps-lib/src/lib/utils/routes.ts @@ -9,6 +9,7 @@ export type NavigationRoute = | "/models/trade-product" | "/models/trade-product/add" | "/settings" + | "/test" | "/cfg/error" | "/cfg/init"; @@ -24,6 +25,7 @@ export function parse_route(route: string): NavigationRoute { case "/models/trade-product": case "/models/trade-product/add": case "/settings": + case "/test": case "/cfg/error": case "/cfg/init": return route;