diff options
author | Sebastian <sebasjm@gmail.com> | 2024-03-07 09:34:06 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2024-03-07 09:34:28 -0300 |
commit | 2b76e32d5714fc410085b5a5ab5c1f4333190fe6 (patch) | |
tree | f890abb9b01c240561d29d489b345b0350b60e7a /packages/web-util/src | |
parent | b059cf4b16663ef2db70a2c2d7af0a6ba5ce2688 (diff) | |
download | wallet-core-2b76e32d5714fc410085b5a5ab5c1f4333190fe6.tar.xz |
time component
Diffstat (limited to 'packages/web-util/src')
-rw-r--r-- | packages/web-util/src/components/Attention.tsx | 6 | ||||
-rw-r--r-- | packages/web-util/src/components/GlobalNotificationBanner.tsx | 27 | ||||
-rw-r--r-- | packages/web-util/src/components/NotificationBanner.tsx (renamed from packages/web-util/src/components/LocalNotificationBanner.tsx) | 0 | ||||
-rw-r--r-- | packages/web-util/src/components/ToastBanner.tsx | 44 | ||||
-rw-r--r-- | packages/web-util/src/components/index.ts | 4 | ||||
-rw-r--r-- | packages/web-util/src/hooks/useNotifications.ts | 30 |
6 files changed, 65 insertions, 46 deletions
diff --git a/packages/web-util/src/components/Attention.tsx b/packages/web-util/src/components/Attention.tsx index 50378e85a..4172c0c9b 100644 --- a/packages/web-util/src/components/Attention.tsx +++ b/packages/web-util/src/components/Attention.tsx @@ -9,10 +9,11 @@ interface Props { timeout?: Duration, } export function Attention({ type = "info", title, children, onClose, timeout = Duration.getForever() }: Props): VNode { + return <div class={`group attention-${type} mt-2 shadow-lg`}> - <style>{` + {timeout.d_ms === "forever" ? undefined : <style>{` .progress { - animation: notificationTimeoutBar 3s ease-in-out; + animation: notificationTimeoutBar ${Math.round(timeout.d_ms / 1000)}s ease-in-out; animation-fill-mode:both; } @@ -21,6 +22,7 @@ export function Attention({ type = "info", title, children, onClose, timeout = D 100% { width: 100%; } } `}</style> + } <div data-timed={timeout.d_ms !== "forever"} class="rounded-md data-[timed=true]:rounded-b-none group-[.attention-info]:bg-blue-50 group-[.attention-low]:bg-gray-100 group-[.attention-warning]:bg-yellow-50 group-[.attention-danger]:bg-red-50 group-[.attention-success]:bg-green-50 p-4 shadow"> <div class="flex"> diff --git a/packages/web-util/src/components/GlobalNotificationBanner.tsx b/packages/web-util/src/components/GlobalNotificationBanner.tsx deleted file mode 100644 index b0a06f7e1..000000000 --- a/packages/web-util/src/components/GlobalNotificationBanner.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { Fragment, VNode, h } from "preact" -import { Attention, GLOBAL_NOTIFICATION_TIMEOUT, useNotifications } from "../index.browser.js" - -export function GlobalNotificationsBanner(): VNode { - const notifs = useNotifications() - if (notifs.length === 0) return <Fragment /> - return <Fragment> { - notifs.map(n => { - switch (n.message.type) { - case "error": - return <Attention type="danger" title={n.message.title} onClose={() => { - n.remove() - }} timeout={GLOBAL_NOTIFICATION_TIMEOUT}> - {n.message.description && - <div class="mt-2 text-sm text-red-700"> - {n.message.description} - </div> - } - </Attention> - case "info": - return <Attention type="success" title={n.message.title} onClose={() => { - n.remove(); - }} timeout={GLOBAL_NOTIFICATION_TIMEOUT} /> - } - })} - </Fragment> -} diff --git a/packages/web-util/src/components/LocalNotificationBanner.tsx b/packages/web-util/src/components/NotificationBanner.tsx index 62733ab3c..62733ab3c 100644 --- a/packages/web-util/src/components/LocalNotificationBanner.tsx +++ b/packages/web-util/src/components/NotificationBanner.tsx diff --git a/packages/web-util/src/components/ToastBanner.tsx b/packages/web-util/src/components/ToastBanner.tsx new file mode 100644 index 000000000..2424b17ff --- /dev/null +++ b/packages/web-util/src/components/ToastBanner.tsx @@ -0,0 +1,44 @@ +import { Fragment, VNode, h } from "preact" +import { Attention, GLOBAL_NOTIFICATION_TIMEOUT as GLOBAL_TOAST_TIMEOUT, useNotifications } from "../index.browser.js" + +/** + * Toasts should be considered when displaying these types of information to the user: + * + * Low attention messages that do not require user action + * Singular status updates + * Confirmations + * Information that does not need to be followed up + * + * Do not use toasts if the information contains the following: + * + * High attention and crtitical information + * Time-sensitive information + * Requires user action or input + * Batch updates + * + * @returns + */ +export function ToastBanner(): VNode { + const notifs = useNotifications() + if (notifs.length === 0) return <Fragment /> + return <Fragment> { + notifs.map(n => { + switch (n.message.type) { + case "error": + return <Attention type="danger" title={n.message.title} onClose={() => { + n.remove() + }} timeout={GLOBAL_TOAST_TIMEOUT}> + {n.message.description && + <div class="mt-2 text-sm text-red-700"> + {n.message.description} + </div> + } + </Attention> + case "info": + return <Attention type="success" title={n.message.title} onClose={() => { + n.remove(); + }} timeout={GLOBAL_TOAST_TIMEOUT} /> + } + })} + </Fragment> +} diff --git a/packages/web-util/src/components/index.ts b/packages/web-util/src/components/index.ts index 4ef840c7d..d7ea41874 100644 --- a/packages/web-util/src/components/index.ts +++ b/packages/web-util/src/components/index.ts @@ -8,5 +8,5 @@ export * from "./Header.js"; export * from "./Footer.js"; export * from "./Button.js"; export * from "./ShowInputErrorLabel.js"; -export * from "./LocalNotificationBanner.js"; -export * from "./GlobalNotificationBanner.js"; +export * from "./NotificationBanner.js"; +export * from "./ToastBanner.js"; diff --git a/packages/web-util/src/hooks/useNotifications.ts b/packages/web-util/src/hooks/useNotifications.ts index d8a927461..000abbc94 100644 --- a/packages/web-util/src/hooks/useNotifications.ts +++ b/packages/web-util/src/hooks/useNotifications.ts @@ -32,7 +32,7 @@ const storage = memoryMap<Map<string, NotificationMessage>>(); const NOTIFICATION_KEY = "notification"; export const GLOBAL_NOTIFICATION_TIMEOUT = Duration.fromSpec({ - minutes: 2, + seconds: 5, }); function removeFromStorage(n: NotificationMessage) { @@ -164,11 +164,11 @@ export function useLocalNotification(): [ const notif = !value ? undefined : { - message: value, - remove: () => { - setter(undefined); - }, - }; + message: value, + remove: () => { + setter(undefined); + }, + }; async function errorHandling(cb: (notify: typeof errorMap) => Promise<void>) { try { @@ -194,8 +194,8 @@ type HandlerMaker = <T extends OperationResult<A, B>, A, B>( onOperationSuccess: | ((result: T extends OperationOk<any> ? T : never) => void) | (( - result: T extends OperationOk<any> ? T : never, - ) => TranslatedString | undefined), + result: T extends OperationOk<any> ? T : never, + ) => TranslatedString | undefined), onOperationFail: ( d: T extends OperationFail<any> ? T : never, ) => TranslatedString, @@ -211,19 +211,19 @@ export function useLocalNotificationHandler(): [ const notif = !value ? undefined : { - message: value, - remove: () => { - setter(undefined); - }, - }; + message: value, + remove: () => { + setter(undefined); + }, + }; function makeHandler<T extends OperationResult<A, B>, A, B>( onClick: () => Promise<T | undefined>, onOperationSuccess: | ((result: T extends OperationOk<any> ? T : never) => void) | (( - result: T extends OperationOk<any> ? T : never, - ) => TranslatedString | undefined), + result: T extends OperationOk<any> ? T : never, + ) => TranslatedString | undefined), onOperationFail: ( d: T extends OperationFail<any> ? T : never, ) => TranslatedString, |