Buckets:
| import { createEffect, createMemo, createSignal, onCleanup, type ValidComponent } from "solid-js" | |
| import { Dynamic } from "solid-js/web" | |
| export const TextShimmer = <T extends ValidComponent = "span">(props: { | |
| text: string | |
| class?: string | |
| as?: T | |
| active?: boolean | |
| offset?: number | |
| }) => { | |
| const text = createMemo(() => props.text ?? "") | |
| const active = createMemo(() => props.active ?? true) | |
| const offset = createMemo(() => props.offset ?? 0) | |
| const [run, setRun] = createSignal(active()) | |
| const swap = 220 | |
| let timer: ReturnType<typeof setTimeout> | undefined | |
| createEffect(() => { | |
| if (timer) { | |
| clearTimeout(timer) | |
| timer = undefined | |
| } | |
| if (active()) { | |
| setRun(true) | |
| return | |
| } | |
| timer = setTimeout(() => { | |
| timer = undefined | |
| setRun(false) | |
| }, swap) | |
| }) | |
| onCleanup(() => { | |
| if (!timer) return | |
| clearTimeout(timer) | |
| }) | |
| return ( | |
| <Dynamic | |
| component={props.as ?? "span"} | |
| data-component="text-shimmer" | |
| data-active={active() ? "true" : "false"} | |
| class={props.class} | |
| aria-label={text()} | |
| style={{ | |
| "--text-shimmer-swap": `${swap}ms`, | |
| "--text-shimmer-index": `${offset()}`, | |
| }} | |
| > | |
| <span data-slot="text-shimmer-char"> | |
| <span data-slot="text-shimmer-char-base" aria-hidden="true"> | |
| {text()} | |
| </span> | |
| <span data-slot="text-shimmer-char-shimmer" data-run={run() ? "true" : "false"} aria-hidden="true"> | |
| {text()} | |
| </span> | |
| </span> | |
| </Dynamic> | |
| ) | |
| } | |
Xet Storage Details
- Size:
- 1.54 kB
- Xet hash:
- ff8fd9a8e36ff841efa717c138aca0eec06e5a85fc536c0a2038fada2174dff7
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.