web_lib

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

commit eb762ba6b84f803ca5903169cfa1a403703453e6
parent 448148b55b9b61490b2299cebb99bc0160c48216
Author: triesap <137732411+triesap@users.noreply.github.com>
Date:   Mon, 28 Oct 2024 15:28:09 +0000

apps-lib: add image blob element. add badge info key and button layout components. edit button layout pair. edit envelope lower add nested scoll container and close handler. add/edit locales, utils

Diffstat:
Aapps-lib/src/lib/components/badge_info_key.svelte | 18++++++++++++++++++
Dapps-lib/src/lib/components/button_carousel_pair.svelte | 56--------------------------------------------------------
Aapps-lib/src/lib/components/button_layout.svelte | 29+++++++++++++++++++++++++++++
Aapps-lib/src/lib/components/button_layout_pair.svelte | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Mapps-lib/src/lib/components/envelope_lower.svelte | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
Mapps-lib/src/lib/el/css_static.svelte | 4++--
Aapps-lib/src/lib/el/image_blob.svelte | 42++++++++++++++++++++++++++++++++++++++++++
Mapps-lib/src/lib/index.ts | 5++++-
Mapps-lib/src/lib/locales/en/common.json | 1+
Mapps-lib/src/lib/locales/en/icu.json | 2+-
Mapps-lib/src/lib/locales/en/trade.json | 18+++++++++---------
Mapps-lib/src/lib/utils/time.ts | 5+++--
12 files changed, 216 insertions(+), 89 deletions(-)

diff --git a/apps-lib/src/lib/components/badge_info_key.svelte b/apps-lib/src/lib/components/badge_info_key.svelte @@ -0,0 +1,18 @@ +<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_carousel_pair.svelte b/apps-lib/src/lib/components/button_carousel_pair.svelte @@ -1,56 +0,0 @@ -<script lang="ts"> - import { app_layout, Fill, t, type CallbackPromise } from "$lib"; - - export let basis: { - continue: { - disabled?: boolean; - label?: string; - callback: CallbackPromise; - }; - back?: { - visible: boolean; - disabled?: boolean; - label?: string; - callback: CallbackPromise; - }; - }; -</script> - -<div class={`flex flex-col justify-center items-center`}> - <button - class={`group flex flex-row h-touch_guide w-${$app_layout} justify-center items-center bg-layer-1-surface round-40 ${basis.continue.disabled ? `opacity-60` : `touch-layer-1`} transition-all`} - on:click|stopPropagation={async () => { - if (!basis.continue.disabled) await basis.continue.callback(); - }} - > - <p - class={`font-sans font-[600] tracking-wide text-layer-1-glyph/80 ${basis.continue.disabled ? `` : `group-active:text-layer-1-glyph/40 `}transition-all`} - > - {basis.continue.label || `${$t(`common.continue`)}`} - </p> - </button> - {#if basis.back} - <div class={`flex flex-col justify-center items-center transition-all`}> - {#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 () => { - if (!basis.back?.disabled) await basis.back?.callback(); - }} - > - <p - class={`font-sans font-[600] tracking-wide text-layer-1-glyph-shade ${basis.back?.disabled ? `` : `group-active:text-layer-1-glyph/40`} transition-all`} - > - {basis.back?.label || `${$t(`common.back`)}`} - </p> - </button> - {:else} - <div - class={`flex flex-row h-4 w-full justify-start items-center`} - > - <Fill /> - </div> - {/if} - </div> - {/if} -</div> diff --git a/apps-lib/src/lib/components/button_layout.svelte b/apps-lib/src/lib/components/button_layout.svelte @@ -0,0 +1,29 @@ +<script lang="ts"> + import { + app_layout, + parse_layer, + type CallbackPromise, + type ILyOpt, + } from "$lib"; + + export let basis: ILyOpt & { + disabled?: boolean; + label: string; + callback: CallbackPromise; + }; + + $: layer = parse_layer(basis.layer, 1); +</script> + +<button + class={`group flex flex-row h-touch_guide w-${$app_layout} justify-center items-center bg-layer-${layer}-surface round-44 ${basis.disabled ? `opacity-60` : `touch-layer-${layer}`} transition-all`} + on:click|stopPropagation={async () => { + if (!basis.disabled) await basis.callback(); + }} +> + <p + class={`font-sans font-[600] tracking-wide text-layer-${layer}-glyph_d ${basis.disabled ? `` : `group-active:text-layer-${layer}-glyph/40 `}transition-all`} + > + {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 @@ -0,0 +1,52 @@ +<script lang="ts"> + import { app_layout, Fill, t, type CallbackPromise } from "$lib"; + import ButtonLayout from "./button_layout.svelte"; + + export let basis: { + continue: { + disabled?: boolean; + label?: string; + callback: CallbackPromise; + }; + back?: { + visible: boolean; + disabled?: boolean; + label?: string; + callback: CallbackPromise; + }; + }; +</script> + +<div class={`flex flex-col justify-center items-center`}> + <ButtonLayout + basis={{ + disabled: basis.continue.disabled, + label: basis.continue.label || `${$t(`common.continue`)}`, + callback: basis.continue.callback, + }} + /> + {#if basis.back} + <div class={`flex flex-col justify-center items-center transition-all`}> + {#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 () => { + if (!basis.back?.disabled) await basis.back?.callback(); + }} + > + <p + class={`font-sans font-[600] tracking-wide text-layer-1-glyph-shade ${basis.back?.disabled ? `` : `group-active:text-layer-1-glyph/40`} transition-all`} + > + {basis.back?.label || `${$t(`common.back`)}`} + </p> + </button> + {:else} + <div + class={`flex flex-row h-4 w-full justify-start items-center`} + > + <Fill /> + </div> + {/if} + </div> + {/if} +</div> diff --git a/apps-lib/src/lib/components/envelope_lower.svelte b/apps-lib/src/lib/components/envelope_lower.svelte @@ -6,50 +6,87 @@ export let basis: { visible: boolean; close: CallbackPromise; + label_close?: string | true; }; - $: basis = basis; $: if (basis.visible) { app_tilt.set(true); } + + const handle_close = async (): Promise<void> => { + try { + app_tilt.set(false); + await basis.close(); + } catch (e) { + console.log(`(error) handle_close `, e); + } + }; </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 h-[calc(100vh-12%)] w-full justify-start items-start bg-layer-1-surface rounded-t-2xl overflow-y-scroll scroll-hide`} + class={`z-20 absolute bottom-0 left-0 flex flex-col h-[100vh] w-full justify-start items-start`} > + <button + class={`flex flex-row h-[12%] w-full justify-center items-center text-white`} + on:click={async () => { + await handle_close(); + }} + > + <Fill /> + </button> <div - class={`sticky top-0 left-0 grid grid-cols-12 flex flex-row h-12 w-full px-4 pb-2 justify-center items-center bg-layer-1-surface/60 backdrop-blur-md`} + class={`flex flex-col h-[calc(100vh-12%)] w-full justify-start justify-start items-start bg-layer-1-surface rounded-t-2xl`} > <div - class={`col-span-4 flex flex-row h-full justify-start items-end`} + class={`sticky top-0 left-0 grid grid-cols-12 flex flex-row h-12 w-full px-4 pb-2 justify-center items-center bg-layer-1-surface/60 backdrop-blur-md`} > + <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 + : `${$t(`common.cancel`)}`} + </p> + </button> + {:else} + <Fill /> + {/if} + </div> <button - class={`flex flex-row justify-center items-center`} + class={`col-span-4 flex flex-row h-full pt-3 justify-center items-start`} on:click={async () => { - app_tilt.set(false); - await basis.close(); + await handle_close(); }} > - <p class={`font-sans font-[500] text-layer-1-glyph-hl`}> - {`${$t(`common.cancel`)}`} - </p> + <div + class={`flex flex-row justify-start items-center h-1 w-10 rounded-full bg-layer-2-surface-edge`} + /> </button> + <div + class={`col-span-4 flex flex-row justify-start items-center`} + > + <Fill /> + </div> </div> <div - class={`col-span-4 flex flex-row h-full pt-3 justify-center items-start`} + class={`flex flex-col w-full justify-start items-center overflow-y-scroll overflow-x-hidden scroll-hide`} > - <div - class={`flex flex-row justify-start items-center h-1 w-10 rounded-full bg-layer-2-surface-edge`} - /> - </div> - <div class={`col-span-4 flex flex-row justify-start items-center`}> - <Fill /> + <slot /> </div> </div> - <slot /> </div> {/if} diff --git a/apps-lib/src/lib/el/css_static.svelte b/apps-lib/src/lib/el/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_w active:bg-layer-0-surface_w group-active:bg-layer-0-surface_w focus:bg-layer-0-surface_w group-focus:bg-layer-0-surface_w border-layer-0-surface_w active:border-layer-0-surface_w group-active:border-layer-0-surface_w focus:border-layer-0-surface_w group-focus:border-layer-0-surface_w 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_d active:text-layer-1-glyph_d group-active:text-layer-1-glyph_d focus:text-layer-1-glyph_d group-focus:text-layer-1-glyph_d 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> -\ No newline at end of file +<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_w active:bg-layer-0-surface_w group-active:bg-layer-0-surface_w focus:bg-layer-0-surface_w group-focus:bg-layer-0-surface_w border-layer-0-surface_w active:border-layer-0-surface_w group-active:border-layer-0-surface_w focus:border-layer-0-surface_w group-focus:border-layer-0-surface_w 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_d active:text-layer-1-glyph_d group-active:text-layer-1-glyph_d focus:text-layer-1-glyph_d group-focus:text-layer-1-glyph_d 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_d active:text-layer-2-glyph_d group-active:text-layer-2-glyph_d focus:text-layer-2-glyph_d group-focus:text-layer-2-glyph_d 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> +\ No newline at end of file diff --git a/apps-lib/src/lib/el/image_blob.svelte b/apps-lib/src/lib/el/image_blob.svelte @@ -0,0 +1,42 @@ +<script lang="ts"> + import { onDestroy, onMount } from "svelte"; + + export let basis: { + 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 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/index.ts b/apps-lib/src/lib/index.ts @@ -13,6 +13,7 @@ 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"; @@ -49,20 +50,22 @@ export { default as AppControls } from "./components/app_controls.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 ButtonCarouselPair } from "./components/button_carousel_pair.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 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 TrellisOffset } from "./components/trellis_offset.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 LoadingView } from "./components/loading_view.svelte"; export { default as NavOption } from "./components/nav_option.svelte"; export { default as TrellisRowLabel } from "./components/trellis_row_label.svelte"; diff --git a/apps-lib/src/lib/locales/en/common.json b/apps-lib/src/lib/locales/en/common.json @@ -8,6 +8,7 @@ "add_new_location": "Add new location", "agree": "Agree", "all_accounts": "All accounts", + "at": "At", "authenticated": "Authenticated", "available_balance": "Available balance", "back": "Back", diff --git a/apps-lib/src/lib/locales/en/icu.json b/apps-lib/src/lib/locales/en/icu.json @@ -6,9 +6,9 @@ "*_details": "{value} details", "*_failure": "{value} failure", "*_list": "{value} list", - "*_price": "{value} price", "*_month": "{value} month", "*_name": "{value} name", + "*_price": "{value} price", "*_summary": "{value} summary", "*_the": "{value} the", "*_title": "{value} title", diff --git a/apps-lib/src/lib/locales/en/trade.json b/apps-lib/src/lib/locales/en/trade.json @@ -14,13 +14,13 @@ "cacao": { "name": "Cacao", "process": { - "raw": "Raw", - "fermented": "Fermented", - "dried": "Dried", - "roasted": "Roasted", - "cocoa_powder": "Cocoa Powder", + "chocolate": "Chocolate", "cocoa_butter": "Cocoa Butter", - "chocolate": "Chocolate" + "cocoa_powder": "Cocoa Powder", + "dried": "Dried", + "fermented": "Fermented", + "raw": "Raw", + "roasted": "Roasted" } }, "coffee": { @@ -39,11 +39,11 @@ "maca": { "name": "Maca", "process": { - "raw": "Raw", + "capsules": "Capsules", "gelatinized": "Gelatinized", "powdered": "Powdered", - "roasted": "Roasted", - "capsules": "Capsules" + "raw": "Raw", + "roasted": "Roasted" } } } diff --git a/apps-lib/src/lib/utils/time.ts b/apps-lib/src/lib/utils/time.ts @@ -5,6 +5,7 @@ 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 }; @@ -15,7 +16,7 @@ export function time_fmt_epoch_s(epoch_s: number | undefined, fmt_key: keyof typ return time; }; -export function time_iso(iso: string, fmt_key: keyof typeof time_fmt = `default`): string { +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]); @@ -23,7 +24,7 @@ export function time_iso(iso: string, fmt_key: keyof typeof time_fmt = `default` }; -export function time_iso_fmt(iso: string, fmt_str: string): string { +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);