web_lib

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

commit 534e077cabd5e5001b66137530309911dfab2d45
parent 0cecf8e736bd95e5e5b0ee42fdbbcc4ad528e5c3
Author: triesap <137732411+triesap@users.noreply.github.com>
Date:   Sat,  7 Sep 2024 08:59:29 +0000

apps-lib: add envelope titled component, edit envelope, edit time utils, edit client utils, edit types

Diffstat:
Mapps-lib/src/lib/components/envelope.svelte | 14+++++++-------
Mapps-lib/src/lib/components/envelope_titled.svelte | 66++++++++++++++++++++++++++++++++++++++++++++----------------------
Mapps-lib/src/lib/index.ts | 1+
Mapps-lib/src/lib/types/client.ts | 20+++++++++++++++++---
Mapps-lib/src/lib/types/components.ts | 20+++++++++++---------
Mapps-lib/src/lib/types/ui.ts | 4++++
Mapps-lib/src/lib/utils/client.ts | 4++--
Mapps-lib/src/lib/utils/time.ts | 15++++++++++-----
8 files changed, 96 insertions(+), 48 deletions(-)

diff --git a/apps-lib/src/lib/components/envelope.svelte b/apps-lib/src/lib/components/envelope.svelte @@ -13,10 +13,8 @@ export let basis: IEnvelopeBasis; $: basis = basis; - $: layer = parse_layer(basis?.layer); - //${is_transparent ? `bg-transparent` : `bg-layer-${layer}-surface opacity-[95%] backdrop-blur-sm`} - //$: is_transparent = basis.transparent ? basis.transparent : false; + $: layer = parse_layer(basis.layer, 1); let envelope_toggle = writable<boolean>(false); let envelope_visible = false; @@ -62,11 +60,13 @@ basis={basis.titled} callback_close={basis.close} {layer} - /> + > + {#if $$slots.default} + <slot /> + {/if} + </EnvelopeTitled> {:else if $$slots.el} - <div class={`flex flex-row h-full w-full`}> - <slot name="el" /> - </div> + <slot name="el" /> {/if} </div> {/if} diff --git a/apps-lib/src/lib/components/envelope_titled.svelte b/apps-lib/src/lib/components/envelope_titled.svelte @@ -2,26 +2,31 @@ import { type CallbackPromise, fmt_cl, + Glyph, type IEnvelopeTitledBasis, t, } from "$lib"; + import Fill from "$lib/ui/fill.svelte"; import type { ThemeLayer } from "@radroots/theme"; export let basis: IEnvelopeTitledBasis; export let layer: ThemeLayer; export let callback_close: CallbackPromise; - $: classes_action = basis.callback_valid - ? `text-layer-${layer}-glyph-hl group-active:opacity-60` - : `text-layer-${layer}-glyph-shade opacity-40`; - $: classes_title = + $: classes_base = basis.hide_border === true || typeof basis.hide_border !== `boolean` ? `` : `border-b-line border-layer-${layer}-surface-edge`; + $: classes_submit = + typeof basis.submit?.valid === `boolean` && !basis.submit?.valid + ? `text-layer-${layer}-glyph-shade opacity-40` + : `text-layer-${layer}-glyph-hl group-active:opacity-60`; </script> -<div class={`flex flex-col h-[700px] w-full bg-layer-1-surface rounded-t-xl`}> - <div class={`${classes_title} grid grid-cols-12 h-envTop w-full px-4`}> +<div + class={`flex flex-col h-[700px] w-full bg-layer-${layer + 1}-surface rounded-t-3xl`} +> + <div class={`${classes_base} grid grid-cols-12 h-envTop w-full px-4`}> <div class={`col-span-3 flex flex-row h-full justify-start items-center`} > @@ -30,36 +35,53 @@ on:click|preventDefault={async () => await callback_close()} > <p - class={`glyph font-sans text-envelopeTitlePrevious text-layer-${layer}-glyph-hl group-active:opacity-40 transition-all`} + class={`${fmt_cl(basis.previous?.label?.classes)} font-sans text-envelopeTitlePrevious text-layer-${layer}-glyph-hl group-active:opacity-40 transition-all`} > - {basis.previous || `${$t(`common.cancel`)}`} + {basis.previous?.label?.value || `${$t(`common.cancel`)}`} </p> </button> </div> <div class={`col-span-6 flex flex-row h-full justify-center items-center`} > - {#if basis.title} + {#if basis.heading?.label?.value} <p - class={`${fmt_cl(basis.title.classes)} glyph font-sans text-envelopeTitle`} + class={`${fmt_cl(basis.heading?.label?.classes)} font-sans text-envelopeTitle text-layer-${layer + 1}-glyph`} > - {basis.title.value} + {basis.heading?.label?.value || ``} </p> + {:else} + <Fill /> {/if} </div> <div class={`col-span-3 flex flex-row h-full justify-end items-center`}> - <button - class={`group`} - on:click|preventDefault={async () => { - if (basis.callback_valid) await basis.callback(); - }} - > - <p - class={`glyph font-sans text-envelopeTitleAction ${classes_action} transition-all`} + {#if basis.submit} + <button + class={`group`} + on:click|preventDefault={async () => { + if ( + typeof basis.submit?.valid === `boolean` && + !basis.submit?.valid + ) + return; + await basis.submit?.callback(); + }} > - {basis.action || `${$t(`common.add`)}`} - </p> - </button> + {#if `glyph` in basis.submit} + <Glyph basis={basis.submit?.glyph} /> + {:else if `label` in basis.submit} + <p + class={`font-sans text-envelopeTitleAction ${classes_submit} transition-all`} + > + {basis.submit?.label.value || `${$t(`common.add`)}`} + </p> + {:else} + <Fill /> + {/if} + </button> + {:else} + <Fill /> + {/if} </div> </div> <div class={`flex flex-col w-full overflow-y-scroll`}> diff --git a/apps-lib/src/lib/index.ts b/apps-lib/src/lib/index.ts @@ -1,5 +1,6 @@ export * from "./locales/i18n" export { default as Envelope } from "./components/envelope.svelte" +export { default as EnvelopeTitled } from "./components/envelope_titled.svelte" export { default as InputForm } from "./components/input_form.svelte" export { default as LoadingView } from "./components/loading_view.svelte" export { default as Tabs } from "./components/tabs.svelte" diff --git a/apps-lib/src/lib/types/client.ts b/apps-lib/src/lib/types/client.ts @@ -72,13 +72,27 @@ export type ILyOpt = { layer?: ThemeLayer; }; +export type IGl = { + glyph: IGlyph; +} + export type IGlOpt = { glyph?: IGlyph; } -/*export type IGlyphOptFields = IGlyphFields & { - glyph?: IGlyphFields; -};*/ +export type ILabelFieldsOpt = { + label: { + value?: string; + classes?: string; + }; +}; + +export type ILabelOptFieldsOpt = { + label?: { + value?: string; + classes?: string; + }; +}; export type IGlyphFields = { value: string; 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, ICb, IClOpt, IGlyphFields, ILy, ILyOpt } from "./client"; +import type { CallbackPromise, CallbackPromiseGeneric, ICb, IClOpt, IGl, ILabelFieldsOpt, ILabelOptFieldsOpt, ILy, ILyOpt } from "./client"; import type { GlyphKey, GlyphWeight } from "./ui"; export type ITabsBasisList = { @@ -39,15 +39,17 @@ export type IEnvelopeBasis = ILyOpt & transparent?: boolean; }; -export type IEnvelopeKind = { - titled: IEnvelopeTitledBasis; -}; +export type IEnvelopeKind = ( + { + titled: IEnvelopeTitledBasis; + }); -export type IEnvelopeTitledBasis = ICb & { - callback_valid?: boolean; - previous?: string; - title: IGlyphFields; - action?: string; +export type IEnvelopeTitledBasis = { hide_border?: boolean; + previous?: ILabelOptFieldsOpt; + heading?: ILabelOptFieldsOpt; + submit?: ICb & (ILabelFieldsOpt | IGl) & { + valid?: boolean; + } }; diff --git a/apps-lib/src/lib/types/ui.ts b/apps-lib/src/lib/types/ui.ts @@ -2,6 +2,10 @@ import type { ThemeLayer } from "@radroots/theme"; import type { GeometryCardinalDirection, GeometryGlyphDimension, ICbOpt } from "./client"; export type GlyphKey = | + `caret-circle-down` | + `caret-circle-up` | + `shopping-bag-open` | + `coffee-bean` | `compass` | `map-pin-simple` | `handbag-simple` | diff --git a/apps-lib/src/lib/utils/client.ts b/apps-lib/src/lib/utils/client.ts @@ -22,14 +22,14 @@ export function get_label_classes(layer: ThemeLayer, label_kind: LabelFieldKind return `text-layer-${layer}-glyph${label_kind ? `-${label_kind}` : ``} ${hide_active ? `` : `group-active:text-layer-${layer}-glyph${label_kind ? `-${label_kind}_a` : `_a`}`}` }; -export function parse_layer(layer?: number): ThemeLayer { +export function parse_layer(layer?: number, layer_default?: ThemeLayer): ThemeLayer { switch (layer) { case 0: case 1: case 2: return layer; default: - return 0; + return layer_default ? layer_default : 0; }; }; diff --git a/apps-lib/src/lib/utils/time.ts b/apps-lib/src/lib/utils/time.ts @@ -1,15 +1,20 @@ -import { DateTime } from "luxon"; +import { DateTime, type DateTimeFormatOptions } from "luxon"; -export function time_fmt_nostr_event(locale: string, epoch_s?: number): string { +const time_fmt: Record<string, DateTimeFormatOptions> = { + default: DateTime.DATE_SHORT, + abbrev: DateTime.DATE_MED +}; + +export function time_fmt_epoch_s(locale: string, epoch_s: number | undefined, fmt_key: keyof typeof time_fmt = `default`): string { const dt = DateTime.fromSeconds(epoch_s); if (!dt.isValid) return ``; - const time = dt.setLocale(locale).toLocaleString(DateTime.DATETIME_MED) + const time = dt.setLocale(locale).toLocaleString(time_fmt[fmt_key]); return time; }; -export function time_fmt_db_iso(locale: string, iso?: string): string { +export function time_fmt_iso(locale: string, iso: string, fmt_key: keyof typeof time_fmt = `default`): string { const dt = DateTime.fromISO(iso); if (!dt.isValid) return ``; - const time = dt.setLocale(locale).toLocaleString(DateTime.DATETIME_MED) + const time = dt.setLocale(locale).toLocaleString(time_fmt[fmt_key]); return time; }; \ No newline at end of file