@gabvdl/ui 0.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +95 -0
- package/dist/components/button/button.d.ts +39 -0
- package/dist/components/button/button.d.ts.map +1 -0
- package/dist/components/button/button.js +72 -0
- package/dist/components/button/button.js.map +1 -0
- package/dist/components/button/index.d.ts +5 -0
- package/dist/components/button/index.d.ts.map +1 -0
- package/dist/components/button/tooltip.d.ts +31 -0
- package/dist/components/button/tooltip.d.ts.map +1 -0
- package/dist/components/button/tooltip.js +83 -0
- package/dist/components/button/tooltip.js.map +1 -0
- package/dist/components/changelog/changelog.d.ts +52 -0
- package/dist/components/changelog/changelog.d.ts.map +1 -0
- package/dist/components/changelog/changelog.js +164 -0
- package/dist/components/changelog/changelog.js.map +1 -0
- package/dist/components/changelog/index.d.ts +3 -0
- package/dist/components/changelog/index.d.ts.map +1 -0
- package/dist/components/copy-button/copy-button.d.ts +16 -0
- package/dist/components/copy-button/copy-button.d.ts.map +1 -0
- package/dist/components/copy-button/copy-button.js +40 -0
- package/dist/components/copy-button/copy-button.js.map +1 -0
- package/dist/components/copy-button/index.d.ts +3 -0
- package/dist/components/copy-button/index.d.ts.map +1 -0
- package/dist/components/drop-zone/drop-zone.d.ts +20 -0
- package/dist/components/drop-zone/drop-zone.d.ts.map +1 -0
- package/dist/components/drop-zone/drop-zone.js +54 -0
- package/dist/components/drop-zone/drop-zone.js.map +1 -0
- package/dist/components/drop-zone/index.d.ts +5 -0
- package/dist/components/drop-zone/index.d.ts.map +1 -0
- package/dist/components/drop-zone/use-file-drop.d.ts +45 -0
- package/dist/components/drop-zone/use-file-drop.d.ts.map +1 -0
- package/dist/components/drop-zone/use-file-drop.js +97 -0
- package/dist/components/drop-zone/use-file-drop.js.map +1 -0
- package/dist/components/element-picker/element-picker-field.d.ts +30 -0
- package/dist/components/element-picker/element-picker-field.d.ts.map +1 -0
- package/dist/components/element-picker/element-picker-field.js +273 -0
- package/dist/components/element-picker/element-picker-field.js.map +1 -0
- package/dist/components/element-picker/element-picker.d.ts +45 -0
- package/dist/components/element-picker/element-picker.d.ts.map +1 -0
- package/dist/components/element-picker/element-picker.js +179 -0
- package/dist/components/element-picker/element-picker.js.map +1 -0
- package/dist/components/element-picker/element-preview.d.ts +23 -0
- package/dist/components/element-picker/element-preview.d.ts.map +1 -0
- package/dist/components/element-picker/element-preview.js +72 -0
- package/dist/components/element-picker/element-preview.js.map +1 -0
- package/dist/components/element-picker/index.d.ts +12 -0
- package/dist/components/element-picker/index.d.ts.map +1 -0
- package/dist/components/element-picker/parse.d.ts +32 -0
- package/dist/components/element-picker/parse.d.ts.map +1 -0
- package/dist/components/element-picker/parse.js +230 -0
- package/dist/components/element-picker/parse.js.map +1 -0
- package/dist/components/element-picker/types.d.ts +72 -0
- package/dist/components/element-picker/types.d.ts.map +1 -0
- package/dist/components/element-picker/use-element-picker.d.ts +56 -0
- package/dist/components/element-picker/use-element-picker.d.ts.map +1 -0
- package/dist/components/element-picker/use-element-picker.js +201 -0
- package/dist/components/element-picker/use-element-picker.js.map +1 -0
- package/dist/components/empty-state/empty-state.d.ts +16 -0
- package/dist/components/empty-state/empty-state.d.ts.map +1 -0
- package/dist/components/empty-state/empty-state.js +41 -0
- package/dist/components/empty-state/empty-state.js.map +1 -0
- package/dist/components/empty-state/index.d.ts +3 -0
- package/dist/components/empty-state/index.d.ts.map +1 -0
- package/dist/components/floating-panel/dock-context.d.ts +66 -0
- package/dist/components/floating-panel/dock-context.d.ts.map +1 -0
- package/dist/components/floating-panel/dock-context.js +96 -0
- package/dist/components/floating-panel/dock-context.js.map +1 -0
- package/dist/components/floating-panel/dock.d.ts +26 -0
- package/dist/components/floating-panel/dock.d.ts.map +1 -0
- package/dist/components/floating-panel/dock.js +46 -0
- package/dist/components/floating-panel/dock.js.map +1 -0
- package/dist/components/floating-panel/floating-panel.d.ts +69 -0
- package/dist/components/floating-panel/floating-panel.d.ts.map +1 -0
- package/dist/components/floating-panel/floating-panel.js +285 -0
- package/dist/components/floating-panel/floating-panel.js.map +1 -0
- package/dist/components/floating-panel/index.d.ts +7 -0
- package/dist/components/floating-panel/index.d.ts.map +1 -0
- package/dist/components/fuzzy-list/fuzzy-list.d.ts +96 -0
- package/dist/components/fuzzy-list/fuzzy-list.d.ts.map +1 -0
- package/dist/components/fuzzy-list/fuzzy-list.js +127 -0
- package/dist/components/fuzzy-list/fuzzy-list.js.map +1 -0
- package/dist/components/fuzzy-list/index.d.ts +4 -0
- package/dist/components/fuzzy-list/index.d.ts.map +1 -0
- package/dist/components/global-search/global-search.d.ts +78 -0
- package/dist/components/global-search/global-search.d.ts.map +1 -0
- package/dist/components/global-search/global-search.js +181 -0
- package/dist/components/global-search/global-search.js.map +1 -0
- package/dist/components/global-search/hotkey.d.ts +23 -0
- package/dist/components/global-search/hotkey.d.ts.map +1 -0
- package/dist/components/global-search/hotkey.js +41 -0
- package/dist/components/global-search/hotkey.js.map +1 -0
- package/dist/components/global-search/index.d.ts +5 -0
- package/dist/components/global-search/index.d.ts.map +1 -0
- package/dist/components/iframe-preview/iframe-preview.d.ts +64 -0
- package/dist/components/iframe-preview/iframe-preview.d.ts.map +1 -0
- package/dist/components/iframe-preview/iframe-preview.js +257 -0
- package/dist/components/iframe-preview/iframe-preview.js.map +1 -0
- package/dist/components/iframe-preview/index.d.ts +3 -0
- package/dist/components/iframe-preview/index.d.ts.map +1 -0
- package/dist/components/image-viewer/image-viewer.d.ts +30 -0
- package/dist/components/image-viewer/image-viewer.d.ts.map +1 -0
- package/dist/components/image-viewer/image-viewer.js +226 -0
- package/dist/components/image-viewer/image-viewer.js.map +1 -0
- package/dist/components/image-viewer/index.d.ts +4 -0
- package/dist/components/image-viewer/index.d.ts.map +1 -0
- package/dist/components/image-viewer/progressive-image.d.ts +20 -0
- package/dist/components/image-viewer/progressive-image.d.ts.map +1 -0
- package/dist/components/image-viewer/progressive-image.js +62 -0
- package/dist/components/image-viewer/progressive-image.js.map +1 -0
- package/dist/components/image-viewer/viewable-image.d.ts +17 -0
- package/dist/components/image-viewer/viewable-image.d.ts.map +1 -0
- package/dist/components/image-viewer/viewable-image.js +38 -0
- package/dist/components/image-viewer/viewable-image.js.map +1 -0
- package/dist/components/input/index.d.ts +3 -0
- package/dist/components/input/index.d.ts.map +1 -0
- package/dist/components/input/input.d.ts +15 -0
- package/dist/components/input/input.d.ts.map +1 -0
- package/dist/components/input/input.js +56 -0
- package/dist/components/input/input.js.map +1 -0
- package/dist/components/modal/index.d.ts +5 -0
- package/dist/components/modal/index.d.ts.map +1 -0
- package/dist/components/modal/modal-context.d.ts +37 -0
- package/dist/components/modal/modal-context.d.ts.map +1 -0
- package/dist/components/modal/modal-context.js +81 -0
- package/dist/components/modal/modal-context.js.map +1 -0
- package/dist/components/modal/modal.d.ts +28 -0
- package/dist/components/modal/modal.d.ts.map +1 -0
- package/dist/components/modal/modal.js +94 -0
- package/dist/components/modal/modal.js.map +1 -0
- package/dist/components/nav-2d/index.d.ts +3 -0
- package/dist/components/nav-2d/index.d.ts.map +1 -0
- package/dist/components/nav-2d/nav-2d.d.ts +59 -0
- package/dist/components/nav-2d/nav-2d.d.ts.map +1 -0
- package/dist/components/nav-2d/nav-2d.js +290 -0
- package/dist/components/nav-2d/nav-2d.js.map +1 -0
- package/dist/components/phone-preview/index.d.ts +3 -0
- package/dist/components/phone-preview/index.d.ts.map +1 -0
- package/dist/components/phone-preview/phone-preview.d.ts +45 -0
- package/dist/components/phone-preview/phone-preview.d.ts.map +1 -0
- package/dist/components/phone-preview/phone-preview.js +117 -0
- package/dist/components/phone-preview/phone-preview.js.map +1 -0
- package/dist/components/progressive-bash/index.d.ts +7 -0
- package/dist/components/progressive-bash/index.d.ts.map +1 -0
- package/dist/components/progressive-bash/parse.d.ts +88 -0
- package/dist/components/progressive-bash/parse.d.ts.map +1 -0
- package/dist/components/progressive-bash/parse.js +120 -0
- package/dist/components/progressive-bash/parse.js.map +1 -0
- package/dist/components/progressive-bash/playback.d.ts +50 -0
- package/dist/components/progressive-bash/playback.d.ts.map +1 -0
- package/dist/components/progressive-bash/playback.js +19 -0
- package/dist/components/progressive-bash/playback.js.map +1 -0
- package/dist/components/progressive-bash/progressive-bash.d.ts +97 -0
- package/dist/components/progressive-bash/progressive-bash.d.ts.map +1 -0
- package/dist/components/progressive-bash/progressive-bash.js +377 -0
- package/dist/components/progressive-bash/progressive-bash.js.map +1 -0
- package/dist/components/progressive-list/index.d.ts +3 -0
- package/dist/components/progressive-list/index.d.ts.map +1 -0
- package/dist/components/progressive-list/progressive-list.d.ts +55 -0
- package/dist/components/progressive-list/progressive-list.d.ts.map +1 -0
- package/dist/components/progressive-list/progressive-list.js +83 -0
- package/dist/components/progressive-list/progressive-list.js.map +1 -0
- package/dist/components/progressive-table/index.d.ts +3 -0
- package/dist/components/progressive-table/index.d.ts.map +1 -0
- package/dist/components/progressive-table/progressive-table.d.ts +58 -0
- package/dist/components/progressive-table/progressive-table.d.ts.map +1 -0
- package/dist/components/progressive-table/progressive-table.js +86 -0
- package/dist/components/progressive-table/progressive-table.js.map +1 -0
- package/dist/components/progressive-text/index.d.ts +3 -0
- package/dist/components/progressive-text/index.d.ts.map +1 -0
- package/dist/components/progressive-text/progressive-text.d.ts +54 -0
- package/dist/components/progressive-text/progressive-text.d.ts.map +1 -0
- package/dist/components/progressive-text/progressive-text.js +97 -0
- package/dist/components/progressive-text/progressive-text.js.map +1 -0
- package/dist/components/progressive-timeline/index.d.ts +3 -0
- package/dist/components/progressive-timeline/index.d.ts.map +1 -0
- package/dist/components/progressive-timeline/progressive-timeline.d.ts +46 -0
- package/dist/components/progressive-timeline/progressive-timeline.d.ts.map +1 -0
- package/dist/components/progressive-timeline/progressive-timeline.js +62 -0
- package/dist/components/progressive-timeline/progressive-timeline.js.map +1 -0
- package/dist/components/relative-time/index.d.ts +3 -0
- package/dist/components/relative-time/index.d.ts.map +1 -0
- package/dist/components/relative-time/relative-time.d.ts +14 -0
- package/dist/components/relative-time/relative-time.d.ts.map +1 -0
- package/dist/components/relative-time/relative-time.js +15 -0
- package/dist/components/relative-time/relative-time.js.map +1 -0
- package/dist/components/resizable-layout/index.d.ts +3 -0
- package/dist/components/resizable-layout/index.d.ts.map +1 -0
- package/dist/components/resizable-layout/resizable-layout.d.ts +113 -0
- package/dist/components/resizable-layout/resizable-layout.d.ts.map +1 -0
- package/dist/components/resizable-layout/resizable-layout.js +398 -0
- package/dist/components/resizable-layout/resizable-layout.js.map +1 -0
- package/dist/components/rich-input/compose.d.ts +13 -0
- package/dist/components/rich-input/compose.d.ts.map +1 -0
- package/dist/components/rich-input/compose.js +28 -0
- package/dist/components/rich-input/compose.js.map +1 -0
- package/dist/components/rich-input/index.d.ts +5 -0
- package/dist/components/rich-input/index.d.ts.map +1 -0
- package/dist/components/rich-input/parts.d.ts +53 -0
- package/dist/components/rich-input/parts.d.ts.map +1 -0
- package/dist/components/rich-input/parts.js +285 -0
- package/dist/components/rich-input/parts.js.map +1 -0
- package/dist/components/rich-input/rich-input.d.ts +64 -0
- package/dist/components/rich-input/rich-input.d.ts.map +1 -0
- package/dist/components/rich-input/rich-input.js +351 -0
- package/dist/components/rich-input/rich-input.js.map +1 -0
- package/dist/components/rich-input/types.d.ts +92 -0
- package/dist/components/rich-input/types.d.ts.map +1 -0
- package/dist/components/rich-input/use-draft.d.ts +9 -0
- package/dist/components/rich-input/use-draft.d.ts.map +1 -0
- package/dist/components/rich-input/use-draft.js +47 -0
- package/dist/components/rich-input/use-draft.js.map +1 -0
- package/dist/components/rich-input/use-file-upload.d.ts +18 -0
- package/dist/components/rich-input/use-file-upload.d.ts.map +1 -0
- package/dist/components/rich-input/use-file-upload.js +88 -0
- package/dist/components/rich-input/use-file-upload.js.map +1 -0
- package/dist/components/rich-input/use-guidelines.d.ts +16 -0
- package/dist/components/rich-input/use-guidelines.d.ts.map +1 -0
- package/dist/components/rich-input/use-guidelines.js +85 -0
- package/dist/components/rich-input/use-guidelines.js.map +1 -0
- package/dist/components/rich-input/use-input-history.d.ts +22 -0
- package/dist/components/rich-input/use-input-history.d.ts.map +1 -0
- package/dist/components/rich-input/use-input-history.js +61 -0
- package/dist/components/rich-input/use-input-history.js.map +1 -0
- package/dist/components/rich-input/use-mention.d.ts +24 -0
- package/dist/components/rich-input/use-mention.d.ts.map +1 -0
- package/dist/components/rich-input/use-mention.js +54 -0
- package/dist/components/rich-input/use-mention.js.map +1 -0
- package/dist/components/search-input/index.d.ts +3 -0
- package/dist/components/search-input/index.d.ts.map +1 -0
- package/dist/components/search-input/search-input.d.ts +14 -0
- package/dist/components/search-input/search-input.d.ts.map +1 -0
- package/dist/components/search-input/search-input.js +63 -0
- package/dist/components/search-input/search-input.js.map +1 -0
- package/dist/components/skeleton/index.d.ts +3 -0
- package/dist/components/skeleton/index.d.ts.map +1 -0
- package/dist/components/skeleton/skeleton.d.ts +19 -0
- package/dist/components/skeleton/skeleton.d.ts.map +1 -0
- package/dist/components/skeleton/skeleton.js +29 -0
- package/dist/components/skeleton/skeleton.js.map +1 -0
- package/dist/components/spinner/index.d.ts +3 -0
- package/dist/components/spinner/index.d.ts.map +1 -0
- package/dist/components/spinner/spinner.d.ts +11 -0
- package/dist/components/spinner/spinner.d.ts.map +1 -0
- package/dist/components/spinner/spinner.js +32 -0
- package/dist/components/spinner/spinner.js.map +1 -0
- package/dist/components/status-badge/index.d.ts +3 -0
- package/dist/components/status-badge/index.d.ts.map +1 -0
- package/dist/components/status-badge/status-badge.d.ts +31 -0
- package/dist/components/status-badge/status-badge.d.ts.map +1 -0
- package/dist/components/status-badge/status-badge.js +53 -0
- package/dist/components/status-badge/status-badge.js.map +1 -0
- package/dist/components/theme/index.d.ts +5 -0
- package/dist/components/theme/index.d.ts.map +1 -0
- package/dist/components/theme/theme-toggle.d.ts +11 -0
- package/dist/components/theme/theme-toggle.d.ts.map +1 -0
- package/dist/components/theme/theme-toggle.js +57 -0
- package/dist/components/theme/theme-toggle.js.map +1 -0
- package/dist/components/theme/theme.d.ts +29 -0
- package/dist/components/theme/theme.d.ts.map +1 -0
- package/dist/components/theme/theme.js +70 -0
- package/dist/components/theme/theme.js.map +1 -0
- package/dist/components/toast/index.d.ts +3 -0
- package/dist/components/toast/index.d.ts.map +1 -0
- package/dist/components/toast/toast.d.ts +64 -0
- package/dist/components/toast/toast.d.ts.map +1 -0
- package/dist/components/toast/toast.js +155 -0
- package/dist/components/toast/toast.js.map +1 -0
- package/dist/components/virtual-list/index.d.ts +3 -0
- package/dist/components/virtual-list/index.d.ts.map +1 -0
- package/dist/components/virtual-list/virtual-list.d.ts +71 -0
- package/dist/components/virtual-list/virtual-list.d.ts.map +1 -0
- package/dist/components/virtual-list/virtual-list.js +65 -0
- package/dist/components/virtual-list/virtual-list.js.map +1 -0
- package/dist/hooks/index.d.ts +12 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/use-copy-to-clipboard.d.ts +26 -0
- package/dist/hooks/use-copy-to-clipboard.d.ts.map +1 -0
- package/dist/hooks/use-copy-to-clipboard.js +36 -0
- package/dist/hooks/use-copy-to-clipboard.js.map +1 -0
- package/dist/hooks/use-debounced-value.d.ts +23 -0
- package/dist/hooks/use-debounced-value.d.ts.map +1 -0
- package/dist/hooks/use-debounced-value.js +19 -0
- package/dist/hooks/use-debounced-value.js.map +1 -0
- package/dist/hooks/use-intersection.d.ts +25 -0
- package/dist/hooks/use-intersection.d.ts.map +1 -0
- package/dist/hooks/use-intersection.js +38 -0
- package/dist/hooks/use-intersection.js.map +1 -0
- package/dist/hooks/use-local-storage.d.ts +12 -0
- package/dist/hooks/use-local-storage.d.ts.map +1 -0
- package/dist/hooks/use-local-storage.js +43 -0
- package/dist/hooks/use-local-storage.js.map +1 -0
- package/dist/hooks/use-long-press.d.ts +37 -0
- package/dist/hooks/use-long-press.d.ts.map +1 -0
- package/dist/hooks/use-long-press.js +39 -0
- package/dist/hooks/use-long-press.js.map +1 -0
- package/dist/hooks/use-media-query.d.ts +17 -0
- package/dist/hooks/use-media-query.d.ts.map +1 -0
- package/dist/hooks/use-media-query.js +37 -0
- package/dist/hooks/use-media-query.js.map +1 -0
- package/dist/hooks/use-overlay.d.ts +20 -0
- package/dist/hooks/use-overlay.d.ts.map +1 -0
- package/dist/hooks/use-overlay.js +42 -0
- package/dist/hooks/use-overlay.js.map +1 -0
- package/dist/image-viewer.css +152 -0
- package/dist/index.d.ts +67 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +161 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/format.d.ts +19 -0
- package/dist/lib/format.d.ts.map +1 -0
- package/dist/lib/format.js +62 -0
- package/dist/lib/format.js.map +1 -0
- package/dist/lib/highlight.d.ts +15 -0
- package/dist/lib/highlight.d.ts.map +1 -0
- package/dist/lib/highlight.js +39 -0
- package/dist/lib/highlight.js.map +1 -0
- package/dist/lib/search.d.ts +40 -0
- package/dist/lib/search.d.ts.map +1 -0
- package/dist/lib/search.js +91 -0
- package/dist/lib/search.js.map +1 -0
- package/dist/lib/utils.d.ts +4 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +9 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/overlay.css +78 -0
- package/dist/styles.css +6 -0
- package/dist/theme.css +81 -0
- package/dist/tooltip.css +53 -0
- package/dist/virtual-list.css +29 -0
- package/package.json +77 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export interface ProgressiveTableCellContext {
|
|
3
|
+
/** Row index within `rows` (the header row is not counted). */
|
|
4
|
+
row: number;
|
|
5
|
+
/** Column index. */
|
|
6
|
+
col: number;
|
|
7
|
+
/** True for a header cell (then `row` is -1). */
|
|
8
|
+
header: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface ProgressiveTableProps {
|
|
11
|
+
/** Header cells — rendered in a single `<thead>` row. */
|
|
12
|
+
headers: readonly ReactNode[];
|
|
13
|
+
/** Body rows; each is an array of cells aligned to `headers`. */
|
|
14
|
+
rows: readonly (readonly ReactNode[])[];
|
|
15
|
+
/** Body rows revealed per second, after the header. @default 6 */
|
|
16
|
+
speed?: number;
|
|
17
|
+
/** Seconds to wait before the header appears. @default 0 */
|
|
18
|
+
delay?: number;
|
|
19
|
+
/** Render the whole table at once, with no animation. */
|
|
20
|
+
instant?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* How many leading body rows to show instantly (with the header), no
|
|
23
|
+
* animation. @default rows.length — an already-known table appears whole and
|
|
24
|
+
* nothing animates. Pass `0` to reveal header + every row from scratch.
|
|
25
|
+
*/
|
|
26
|
+
initialReveal?: number;
|
|
27
|
+
/** Optional `<caption>`. */
|
|
28
|
+
caption?: ReactNode;
|
|
29
|
+
/** Optional per-cell renderer (defaults to rendering the cell node as-is). */
|
|
30
|
+
renderCell?: (cell: ReactNode, ctx: ProgressiveTableCellContext) => ReactNode;
|
|
31
|
+
/** Classes on the scroll wrapper `<div>`. @default 'overflow-x-auto' */
|
|
32
|
+
wrapperClassName?: string;
|
|
33
|
+
/** Classes on the `<table>`. */
|
|
34
|
+
className?: string;
|
|
35
|
+
theadClassName?: string;
|
|
36
|
+
tbodyClassName?: string;
|
|
37
|
+
/** Classes on every body `<tr>`. */
|
|
38
|
+
rowClassName?: string;
|
|
39
|
+
/** Classes on the header `<tr>`. */
|
|
40
|
+
headRowClassName?: string;
|
|
41
|
+
/** Classes on every `<td>`. */
|
|
42
|
+
cellClassName?: string;
|
|
43
|
+
/** Classes on every `<th>`. */
|
|
44
|
+
headCellClassName?: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Reveals a table header-first, then its body rows one at a time — the table
|
|
48
|
+
* analogue of {@link ProgressiveText} (typewriter) and {@link ProgressiveList}
|
|
49
|
+
* (staggered feed). It participates in the same timeline: inside a
|
|
50
|
+
* {@link ProgressiveList} it waits for its slot to become active, reports how
|
|
51
|
+
* long the whole reveal takes, and hands off once the last row is in.
|
|
52
|
+
*
|
|
53
|
+
* Rows present when the table is "already known" are shown instantly (see
|
|
54
|
+
* `initialReveal`); pass `initialReveal={0}` to animate the entire table.
|
|
55
|
+
* Respects `prefers-reduced-motion` and `instant` (renders everything at once).
|
|
56
|
+
*/
|
|
57
|
+
export declare function ProgressiveTable({ headers, rows, speed, delay, instant, initialReveal, caption, renderCell, wrapperClassName, className, theadClassName, tbodyClassName, rowClassName, headRowClassName, cellClassName, headCellClassName, }: ProgressiveTableProps): import("react").JSX.Element;
|
|
58
|
+
//# sourceMappingURL=progressive-table.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progressive-table.d.ts","sourceRoot":"","sources":["../../../src/components/progressive-table/progressive-table.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAKpE,MAAM,WAAW,2BAA2B;IAC1C,+DAA+D;IAC/D,GAAG,EAAE,MAAM,CAAC;IACZ,oBAAoB;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,iDAAiD;IACjD,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,qBAAqB;IACpC,yDAAyD;IACzD,OAAO,EAAE,SAAS,SAAS,EAAE,CAAC;IAC9B,iEAAiE;IACjE,IAAI,EAAE,SAAS,CAAC,SAAS,SAAS,EAAE,CAAC,EAAE,CAAC;IACxC,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,4BAA4B;IAC5B,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,8EAA8E;IAC9E,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,2BAA2B,KAAK,SAAS,CAAC;IAC9E,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gCAAgC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oCAAoC;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oCAAoC;IACpC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,+BAA+B;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,+BAA+B;IAC/B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAaD;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,OAAO,EACP,IAAI,EACJ,KAAS,EACT,KAAS,EACT,OAAe,EACf,aAAa,EACb,OAAO,EACP,UAAU,EACV,gBAAoC,EACpC,SAAS,EACT,cAAc,EACd,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,iBAAiB,GAClB,EAAE,qBAAqB,+BA4FvB"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { jsx as i, jsxs as B } from "react/jsx-runtime";
|
|
2
|
+
import { useRef as A, useState as R, useEffect as u } from "react";
|
|
3
|
+
import { cn as D } from "../../lib/utils.js";
|
|
4
|
+
import { useProgressiveSlot as G } from "../progressive-timeline/progressive-timeline.js";
|
|
5
|
+
const I = 300;
|
|
6
|
+
function J() {
|
|
7
|
+
return typeof window < "u" && typeof window.matchMedia == "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
8
|
+
}
|
|
9
|
+
function U({
|
|
10
|
+
headers: c,
|
|
11
|
+
rows: e,
|
|
12
|
+
speed: s = 6,
|
|
13
|
+
delay: l = 0,
|
|
14
|
+
instant: v = !1,
|
|
15
|
+
initialReveal: N,
|
|
16
|
+
caption: w,
|
|
17
|
+
renderCell: g,
|
|
18
|
+
wrapperClassName: F = "overflow-x-auto",
|
|
19
|
+
className: P,
|
|
20
|
+
theadClassName: k,
|
|
21
|
+
tbodyClassName: q,
|
|
22
|
+
rowClassName: C,
|
|
23
|
+
headRowClassName: H,
|
|
24
|
+
cellClassName: _,
|
|
25
|
+
headCellClassName: j
|
|
26
|
+
}) {
|
|
27
|
+
const r = v || J(), M = A(-1);
|
|
28
|
+
M.current < 0 && (M.current = r ? e.length : Math.min(N ?? e.length, e.length));
|
|
29
|
+
const h = M.current, m = !r && h < e.length, x = G(), o = x.active, p = A(x);
|
|
30
|
+
p.current = x;
|
|
31
|
+
const [a, T] = R(!m), [d, b] = R(h);
|
|
32
|
+
u(() => {
|
|
33
|
+
r && (T(!0), b(e.length), p.current.finish());
|
|
34
|
+
}, [r, e.length]), u(() => {
|
|
35
|
+
if (r || !o) return;
|
|
36
|
+
const n = 1e3 / Math.max(1e-3, s), t = Math.max(0, e.length - h), f = l * 1e3 + I + t * n;
|
|
37
|
+
p.current.report(f);
|
|
38
|
+
}, [o, r, s, l, e.length, h]), u(() => {
|
|
39
|
+
if (!m || a || !o) return;
|
|
40
|
+
const n = window.setTimeout(() => T(!0), l * 1e3);
|
|
41
|
+
return () => window.clearTimeout(n);
|
|
42
|
+
}, [m, a, o, l]), u(() => {
|
|
43
|
+
if (r || !o || !a || d >= e.length) return;
|
|
44
|
+
const n = 1e3 / Math.max(1e-3, s), t = window.setTimeout(() => b((f) => Math.min(f + 1, e.length)), n);
|
|
45
|
+
return () => window.clearTimeout(t);
|
|
46
|
+
}, [r, o, a, d, e.length, s]), u(() => {
|
|
47
|
+
!r && o && a && d >= e.length && p.current.finish();
|
|
48
|
+
}, [r, o, a, d, e.length]);
|
|
49
|
+
const S = (n, t) => g ? g(n, t) : n;
|
|
50
|
+
return /* @__PURE__ */ i("div", { className: F, children: /* @__PURE__ */ B("table", { className: P, children: [
|
|
51
|
+
w != null && /* @__PURE__ */ i("caption", { children: w }),
|
|
52
|
+
/* @__PURE__ */ i("thead", { className: k, children: /* @__PURE__ */ i(E, { animate: m, shown: a, className: H, children: c.map((n, t) => /* @__PURE__ */ i("th", { className: j, children: S(n, { row: -1, col: t, header: !0 }) }, t)) }) }),
|
|
53
|
+
/* @__PURE__ */ i("tbody", { className: q, children: e.map((n, t) => {
|
|
54
|
+
if (t >= d) return null;
|
|
55
|
+
const f = t >= h;
|
|
56
|
+
return /* @__PURE__ */ i(E, { animate: m && f, shown: !0, className: C, children: n.map((z, y) => /* @__PURE__ */ i("td", { className: _, children: S(z, { row: t, col: y, header: !1 }) }, y)) }, t);
|
|
57
|
+
}) })
|
|
58
|
+
] }) });
|
|
59
|
+
}
|
|
60
|
+
function E({
|
|
61
|
+
animate: c,
|
|
62
|
+
shown: e,
|
|
63
|
+
className: s,
|
|
64
|
+
children: l
|
|
65
|
+
}) {
|
|
66
|
+
const [v, N] = R(!c);
|
|
67
|
+
return u(() => {
|
|
68
|
+
if (!c) return;
|
|
69
|
+
const g = requestAnimationFrame(() => N(!0));
|
|
70
|
+
return () => cancelAnimationFrame(g);
|
|
71
|
+
}, [c]), /* @__PURE__ */ i(
|
|
72
|
+
"tr",
|
|
73
|
+
{
|
|
74
|
+
className: D(
|
|
75
|
+
c && "transition-all duration-300 ease-out",
|
|
76
|
+
c && ((c ? v && e : !0) ? "translate-y-0 opacity-100" : "translate-y-1 opacity-0"),
|
|
77
|
+
s
|
|
78
|
+
),
|
|
79
|
+
children: l
|
|
80
|
+
}
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
export {
|
|
84
|
+
U as ProgressiveTable
|
|
85
|
+
};
|
|
86
|
+
//# sourceMappingURL=progressive-table.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progressive-table.js","sources":["../../../src/components/progressive-table/progressive-table.tsx"],"sourcesContent":["import { useEffect, useRef, useState, type ReactNode } from 'react';\n\nimport { cn } from '../../lib/utils';\nimport { useProgressiveSlot } from '../progressive-timeline';\n\nexport interface ProgressiveTableCellContext {\n /** Row index within `rows` (the header row is not counted). */\n row: number;\n /** Column index. */\n col: number;\n /** True for a header cell (then `row` is -1). */\n header: boolean;\n}\n\nexport interface ProgressiveTableProps {\n /** Header cells — rendered in a single `<thead>` row. */\n headers: readonly ReactNode[];\n /** Body rows; each is an array of cells aligned to `headers`. */\n rows: readonly (readonly ReactNode[])[];\n /** Body rows revealed per second, after the header. @default 6 */\n speed?: number;\n /** Seconds to wait before the header appears. @default 0 */\n delay?: number;\n /** Render the whole table at once, with no animation. */\n instant?: boolean;\n /**\n * How many leading body rows to show instantly (with the header), no\n * animation. @default rows.length — an already-known table appears whole and\n * nothing animates. Pass `0` to reveal header + every row from scratch.\n */\n initialReveal?: number;\n /** Optional `<caption>`. */\n caption?: ReactNode;\n /** Optional per-cell renderer (defaults to rendering the cell node as-is). */\n renderCell?: (cell: ReactNode, ctx: ProgressiveTableCellContext) => ReactNode;\n /** Classes on the scroll wrapper `<div>`. @default 'overflow-x-auto' */\n wrapperClassName?: string;\n /** Classes on the `<table>`. */\n className?: string;\n theadClassName?: string;\n tbodyClassName?: string;\n /** Classes on every body `<tr>`. */\n rowClassName?: string;\n /** Classes on the header `<tr>`. */\n headRowClassName?: string;\n /** Classes on every `<td>`. */\n cellClassName?: string;\n /** Classes on every `<th>`. */\n headCellClassName?: string;\n}\n\n/** Duration of a single row's fade+slide entrance (must match the CSS below). */\nconst ENTRANCE_MS = 300;\n\nfunction reducedMotion(): boolean {\n return (\n typeof window !== 'undefined' &&\n typeof window.matchMedia === 'function' &&\n window.matchMedia('(prefers-reduced-motion: reduce)').matches\n );\n}\n\n/**\n * Reveals a table header-first, then its body rows one at a time — the table\n * analogue of {@link ProgressiveText} (typewriter) and {@link ProgressiveList}\n * (staggered feed). It participates in the same timeline: inside a\n * {@link ProgressiveList} it waits for its slot to become active, reports how\n * long the whole reveal takes, and hands off once the last row is in.\n *\n * Rows present when the table is \"already known\" are shown instantly (see\n * `initialReveal`); pass `initialReveal={0}` to animate the entire table.\n * Respects `prefers-reduced-motion` and `instant` (renders everything at once).\n */\nexport function ProgressiveTable({\n headers,\n rows,\n speed = 6,\n delay = 0,\n instant = false,\n initialReveal,\n caption,\n renderCell,\n wrapperClassName = 'overflow-x-auto',\n className,\n theadClassName,\n tbodyClassName,\n rowClassName,\n headRowClassName,\n cellClassName,\n headCellClassName,\n}: ProgressiveTableProps) {\n const skip = instant || reducedMotion();\n\n // Fixed at mount: how many body rows were \"already there\" (shown instantly).\n const initialRef = useRef<number>(-1);\n if (initialRef.current < 0) {\n initialRef.current = skip ? rows.length : Math.min(initialReveal ?? rows.length, rows.length);\n }\n const initialCount = initialRef.current;\n const animate = !skip && initialCount < rows.length;\n\n // Timeline slot (a no-op when standalone): hold the reveal until it's our turn.\n const slot = useProgressiveSlot();\n const active = slot.active;\n const slotRef = useRef(slot);\n slotRef.current = slot;\n\n const [headerShown, setHeaderShown] = useState(!animate);\n const [revealed, setRevealed] = useState(initialCount);\n\n // Instant / reduced-motion: everything at once, and hand the timeline off now.\n useEffect(() => {\n if (!skip) return;\n setHeaderShown(true);\n setRevealed(rows.length);\n slotRef.current.finish();\n }, [skip, rows.length]);\n\n // Tell the enclosing list how long we'll animate, so the *next* item waits for\n // the whole table. Only once it's our slot's turn.\n useEffect(() => {\n if (skip || !active) return;\n const interval = 1000 / Math.max(0.001, speed);\n const n = Math.max(0, rows.length - initialCount);\n const durationMs = delay * 1000 + ENTRANCE_MS + n * interval;\n slotRef.current.report(durationMs);\n }, [active, skip, speed, delay, rows.length, initialCount]);\n\n // Reveal the header once it's our turn (after the lead-in delay).\n useEffect(() => {\n if (!animate || headerShown || !active) return;\n const t = window.setTimeout(() => setHeaderShown(true), delay * 1000);\n return () => window.clearTimeout(t);\n }, [animate, headerShown, active, delay]);\n\n // Then reveal body rows one per interval.\n useEffect(() => {\n if (skip || !active || !headerShown || revealed >= rows.length) return;\n const interval = 1000 / Math.max(0.001, speed);\n const t = window.setTimeout(() => setRevealed((r) => Math.min(r + 1, rows.length)), interval);\n return () => window.clearTimeout(t);\n }, [skip, active, headerShown, revealed, rows.length, speed]);\n\n // Hand the timeline off the moment the last row lands.\n useEffect(() => {\n if (!skip && active && headerShown && revealed >= rows.length) slotRef.current.finish();\n }, [skip, active, headerShown, revealed, rows.length]);\n\n const cell = (node: ReactNode, ctx: ProgressiveTableCellContext) =>\n renderCell ? renderCell(node, ctx) : node;\n\n return (\n <div className={wrapperClassName}>\n <table className={className}>\n {caption != null && <caption>{caption}</caption>}\n <thead className={theadClassName}>\n <AnimatedRow animate={animate} shown={headerShown} className={headRowClassName}>\n {headers.map((h, j) => (\n <th key={j} className={headCellClassName}>\n {cell(h, { row: -1, col: j, header: true })}\n </th>\n ))}\n </AnimatedRow>\n </thead>\n <tbody className={tbodyClassName}>\n {rows.map((row, i) => {\n if (i >= revealed) return null;\n const isNew = i >= initialCount;\n return (\n <AnimatedRow key={i} animate={animate && isNew} shown className={rowClassName}>\n {row.map((c, j) => (\n <td key={j} className={cellClassName}>\n {cell(c, { row: i, col: j, header: false })}\n </td>\n ))}\n </AnimatedRow>\n );\n })}\n </tbody>\n </table>\n </div>\n );\n}\n\n/**\n * A `<tr>` that fades + slides in on mount when `animate` — the reveal classes\n * live on the row itself (a table row can't be wrapped in a `<div>`). `shown`\n * lets a caller (the header) drive the target state externally.\n */\nfunction AnimatedRow({\n animate,\n shown,\n className,\n children,\n}: {\n animate: boolean;\n shown: boolean;\n className?: string;\n children: ReactNode;\n}) {\n // Mount hidden, then flip on the next frame so the transition runs.\n const [entered, setEntered] = useState(!animate);\n useEffect(() => {\n if (!animate) return;\n const id = requestAnimationFrame(() => setEntered(true));\n return () => cancelAnimationFrame(id);\n }, [animate]);\n\n const visible = animate ? entered && shown : true;\n return (\n <tr\n className={cn(\n animate && 'transition-all duration-300 ease-out',\n animate && (visible ? 'translate-y-0 opacity-100' : 'translate-y-1 opacity-0'),\n className,\n )}\n >\n {children}\n </tr>\n );\n}\n"],"names":["ENTRANCE_MS","reducedMotion","ProgressiveTable","headers","rows","speed","delay","instant","initialReveal","caption","renderCell","wrapperClassName","className","theadClassName","tbodyClassName","rowClassName","headRowClassName","cellClassName","headCellClassName","skip","initialRef","useRef","initialCount","animate","slot","useProgressiveSlot","active","slotRef","headerShown","setHeaderShown","useState","revealed","setRevealed","useEffect","interval","n","durationMs","t","r","cell","node","ctx","jsxs","jsx","AnimatedRow","h","j","row","i","isNew","c","shown","children","entered","setEntered","id","cn"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/progressive-text/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { ElementType, ReactNode } from 'react';
|
|
2
|
+
export interface ProgressiveTextMeta {
|
|
3
|
+
/** The visible text has fully caught up to `text`. */
|
|
4
|
+
done: boolean;
|
|
5
|
+
/** Characters are currently being removed (the target diverged from what's shown). */
|
|
6
|
+
deleting: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface ProgressiveTextProps {
|
|
9
|
+
/** The full target string to reveal. */
|
|
10
|
+
text: string;
|
|
11
|
+
/** Typing rate in characters per second (constant). @default 40 */
|
|
12
|
+
speed?: number;
|
|
13
|
+
/**
|
|
14
|
+
* Backspacing rate, in characters per second, used when `text` changes to a
|
|
15
|
+
* value that diverges from what's already shown (the component deletes back to
|
|
16
|
+
* the common prefix, then types the rest). @default `speed * 2`
|
|
17
|
+
*/
|
|
18
|
+
deleteSpeed?: number;
|
|
19
|
+
/** Seconds to wait before the first character is revealed. @default 0 */
|
|
20
|
+
delay?: number;
|
|
21
|
+
/** Render the full text at once with no animation (e.g. pre-existing content). */
|
|
22
|
+
instant?: boolean;
|
|
23
|
+
/** Show a blinking block caret while animating (default renderer only). */
|
|
24
|
+
caret?: boolean;
|
|
25
|
+
/** Wrapper element type. Use `'div'` when `children` returns block content. @default 'span' */
|
|
26
|
+
as?: ElementType;
|
|
27
|
+
className?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Custom renderer for the currently-revealed substring — pass this to wrap the
|
|
30
|
+
* partial text (e.g. a Markdown renderer or a styled caret). When omitted the
|
|
31
|
+
* raw string is rendered.
|
|
32
|
+
*/
|
|
33
|
+
children?: (visible: string, meta: ProgressiveTextMeta) => ReactNode;
|
|
34
|
+
/** Fired once the visible text catches up to `text`. */
|
|
35
|
+
onDone?: () => void;
|
|
36
|
+
/** Fired on every revealed/removed character with the new visible string. */
|
|
37
|
+
onUpdate?: (visible: string) => void;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Reveals `text` one character at a time at a constant rate — a typewriter.
|
|
41
|
+
*
|
|
42
|
+
* The animation is driven by the *difference* between what's shown and the
|
|
43
|
+
* current `text`, so it composes with streaming and live edits:
|
|
44
|
+
* - text grows (a message streams in) → it types the appended characters;
|
|
45
|
+
* - text changes to a divergent value (an aggregated title updates) → it deletes
|
|
46
|
+
* from the end back to the common prefix, then types the new tail.
|
|
47
|
+
*
|
|
48
|
+
* `speed`/`deleteSpeed`/`delay` are the tunables. `instant` (or the user's
|
|
49
|
+
* `prefers-reduced-motion`) renders the full string immediately. Content that was
|
|
50
|
+
* already present when the component mounted should pass `instant` so history
|
|
51
|
+
* isn't re-typed; only freshly-arrived text needs to animate.
|
|
52
|
+
*/
|
|
53
|
+
export declare function ProgressiveText({ text, speed, deleteSpeed, delay, instant, caret, as, className, children, onDone, onUpdate, }: ProgressiveTextProps): import("react").JSX.Element;
|
|
54
|
+
//# sourceMappingURL=progressive-text.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progressive-text.d.ts","sourceRoot":"","sources":["../../../src/components/progressive-text/progressive-text.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,WAAW,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAKtF,MAAM,WAAW,mBAAmB;IAClC,sDAAsD;IACtD,IAAI,EAAE,OAAO,CAAC;IACd,sFAAsF;IACtF,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kFAAkF;IAClF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2EAA2E;IAC3E,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,+FAA+F;IAC/F,EAAE,CAAC,EAAE,WAAW,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,mBAAmB,KAAK,SAAS,CAAC;IACrE,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAkBD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,KAAU,EACV,WAAW,EACX,KAAS,EACT,OAAe,EACf,KAAa,EACb,EAAE,EACF,SAAS,EACT,QAAQ,EACR,MAAM,EACN,QAAQ,GACT,EAAE,oBAAoB,+BAuItB"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { jsxs as U, jsx as X } from "react/jsx-runtime";
|
|
2
|
+
import { useState as Y, useRef as t, useEffect as D } from "react";
|
|
3
|
+
import { cn as Z } from "../../lib/utils.js";
|
|
4
|
+
import { useProgressiveSlot as _ } from "../progressive-timeline/progressive-timeline.js";
|
|
5
|
+
function G(e, c) {
|
|
6
|
+
const l = Math.min(e.length, c.length);
|
|
7
|
+
let r = 0;
|
|
8
|
+
for (; r < l && e.charCodeAt(r) === c.charCodeAt(r); ) r++;
|
|
9
|
+
return r;
|
|
10
|
+
}
|
|
11
|
+
function $() {
|
|
12
|
+
return typeof window < "u" && typeof window.matchMedia == "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
13
|
+
}
|
|
14
|
+
function ue({
|
|
15
|
+
text: e,
|
|
16
|
+
speed: c = 40,
|
|
17
|
+
deleteSpeed: l,
|
|
18
|
+
delay: r = 0,
|
|
19
|
+
instant: H = !1,
|
|
20
|
+
caret: J = !1,
|
|
21
|
+
as: K,
|
|
22
|
+
className: O,
|
|
23
|
+
children: g,
|
|
24
|
+
onDone: q,
|
|
25
|
+
onUpdate: P
|
|
26
|
+
}) {
|
|
27
|
+
const s = H || $(), [u, j] = Y(() => s ? e : ""), R = _(), x = R.active, v = t(R);
|
|
28
|
+
v.current = R;
|
|
29
|
+
const m = t(e);
|
|
30
|
+
m.current = e;
|
|
31
|
+
const n = t(u);
|
|
32
|
+
n.current = u;
|
|
33
|
+
const d = t({ speed: c, deleteSpeed: l, delay: r, skip: s });
|
|
34
|
+
d.current = { speed: c, deleteSpeed: l, delay: r, skip: s };
|
|
35
|
+
const M = t({ onDone: q, onUpdate: P });
|
|
36
|
+
M.current = { onDone: q, onUpdate: P };
|
|
37
|
+
const a = t(0), h = t(!1), k = t(!1), y = t(() => {
|
|
38
|
+
});
|
|
39
|
+
D(() => {
|
|
40
|
+
let i = 0, o = 0, w = 0;
|
|
41
|
+
const p = (A) => {
|
|
42
|
+
var E, N, V, z;
|
|
43
|
+
if (i === 0) {
|
|
44
|
+
i = A, a.current = requestAnimationFrame(p);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const I = A - i;
|
|
48
|
+
if (i = A, !k.current) {
|
|
49
|
+
if (w -= I, w > 0) {
|
|
50
|
+
a.current = requestAnimationFrame(p);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
k.current = !0;
|
|
54
|
+
}
|
|
55
|
+
o += I;
|
|
56
|
+
const { speed: L, deleteSpeed: Q } = d.current, S = 1e3 / Math.max(1, L), T = 1e3 / Math.max(1, Q ?? L * 2);
|
|
57
|
+
let W = !1;
|
|
58
|
+
for (let B = 0; B < 2e3; B++) {
|
|
59
|
+
const f = n.current, b = m.current;
|
|
60
|
+
if (f === b) break;
|
|
61
|
+
const F = f.length > G(f, b);
|
|
62
|
+
if (o < (F ? T : S)) break;
|
|
63
|
+
o -= F ? T : S, n.current = F ? f.slice(0, -1) : b.slice(0, f.length + 1), W = !0;
|
|
64
|
+
}
|
|
65
|
+
if (W && (j(n.current), (N = (E = M.current).onUpdate) == null || N.call(E, n.current)), n.current === m.current) {
|
|
66
|
+
h.current = !1, (z = (V = M.current).onDone) == null || z.call(V);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
a.current = requestAnimationFrame(p);
|
|
70
|
+
};
|
|
71
|
+
return y.current = () => {
|
|
72
|
+
d.current.skip || h.current || n.current !== m.current && (h.current = !0, i = 0, o = 0, w = k.current ? 0 : d.current.delay * 1e3, a.current = requestAnimationFrame(p));
|
|
73
|
+
}, () => {
|
|
74
|
+
cancelAnimationFrame(a.current), h.current = !1;
|
|
75
|
+
};
|
|
76
|
+
}, []), D(() => {
|
|
77
|
+
if (s) {
|
|
78
|
+
n.current = e, j(e), v.current.finish();
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (!x) return;
|
|
82
|
+
const i = 1e3 / Math.max(1, c), o = Math.max(0, r) * 1e3 + e.length * i;
|
|
83
|
+
v.current.report(o), y.current();
|
|
84
|
+
}, [e, s, x, c, r]);
|
|
85
|
+
const C = {
|
|
86
|
+
done: u === e,
|
|
87
|
+
deleting: u.length > G(u, e)
|
|
88
|
+
};
|
|
89
|
+
return /* @__PURE__ */ U(K ?? "span", { className: O, children: [
|
|
90
|
+
g ? g(u, C) : u,
|
|
91
|
+
J && !g && !C.done && /* @__PURE__ */ X("span", { "aria-hidden": !0, className: Z("ml-px inline-block animate-pulse"), children: "▍" })
|
|
92
|
+
] });
|
|
93
|
+
}
|
|
94
|
+
export {
|
|
95
|
+
ue as ProgressiveText
|
|
96
|
+
};
|
|
97
|
+
//# sourceMappingURL=progressive-text.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progressive-text.js","sources":["../../../src/components/progressive-text/progressive-text.tsx"],"sourcesContent":["import { useEffect, useRef, useState, type ElementType, type ReactNode } from 'react';\n\nimport { cn } from '../../lib/utils';\nimport { useProgressiveSlot } from '../progressive-timeline';\n\nexport interface ProgressiveTextMeta {\n /** The visible text has fully caught up to `text`. */\n done: boolean;\n /** Characters are currently being removed (the target diverged from what's shown). */\n deleting: boolean;\n}\n\nexport interface ProgressiveTextProps {\n /** The full target string to reveal. */\n text: string;\n /** Typing rate in characters per second (constant). @default 40 */\n speed?: number;\n /**\n * Backspacing rate, in characters per second, used when `text` changes to a\n * value that diverges from what's already shown (the component deletes back to\n * the common prefix, then types the rest). @default `speed * 2`\n */\n deleteSpeed?: number;\n /** Seconds to wait before the first character is revealed. @default 0 */\n delay?: number;\n /** Render the full text at once with no animation (e.g. pre-existing content). */\n instant?: boolean;\n /** Show a blinking block caret while animating (default renderer only). */\n caret?: boolean;\n /** Wrapper element type. Use `'div'` when `children` returns block content. @default 'span' */\n as?: ElementType;\n className?: string;\n /**\n * Custom renderer for the currently-revealed substring — pass this to wrap the\n * partial text (e.g. a Markdown renderer or a styled caret). When omitted the\n * raw string is rendered.\n */\n children?: (visible: string, meta: ProgressiveTextMeta) => ReactNode;\n /** Fired once the visible text catches up to `text`. */\n onDone?: () => void;\n /** Fired on every revealed/removed character with the new visible string. */\n onUpdate?: (visible: string) => void;\n}\n\n/** Length of the shared leading run of two strings. */\nfunction commonPrefixLen(a: string, b: string): number {\n const n = Math.min(a.length, b.length);\n let i = 0;\n while (i < n && a.charCodeAt(i) === b.charCodeAt(i)) i++;\n return i;\n}\n\nfunction reducedMotion(): boolean {\n return (\n typeof window !== 'undefined' &&\n typeof window.matchMedia === 'function' &&\n window.matchMedia('(prefers-reduced-motion: reduce)').matches\n );\n}\n\n/**\n * Reveals `text` one character at a time at a constant rate — a typewriter.\n *\n * The animation is driven by the *difference* between what's shown and the\n * current `text`, so it composes with streaming and live edits:\n * - text grows (a message streams in) → it types the appended characters;\n * - text changes to a divergent value (an aggregated title updates) → it deletes\n * from the end back to the common prefix, then types the new tail.\n *\n * `speed`/`deleteSpeed`/`delay` are the tunables. `instant` (or the user's\n * `prefers-reduced-motion`) renders the full string immediately. Content that was\n * already present when the component mounted should pass `instant` so history\n * isn't re-typed; only freshly-arrived text needs to animate.\n */\nexport function ProgressiveText({\n text,\n speed = 40,\n deleteSpeed,\n delay = 0,\n instant = false,\n caret = false,\n as,\n className,\n children,\n onDone,\n onUpdate,\n}: ProgressiveTextProps) {\n const skip = instant || reducedMotion();\n const [visible, setVisible] = useState(() => (skip ? text : ''));\n\n // Timeline slot (a no-op when not inside a ProgressiveList): hold the reveal\n // until it's this slot's turn, and report how long the reveal takes so the\n // next list element is delayed by exactly this inner animation.\n const slot = useProgressiveSlot();\n const active = slot.active;\n const slotRef = useRef(slot);\n slotRef.current = slot;\n\n // Latest values read by the rAF loop, so prop changes never restart it.\n const targetRef = useRef(text);\n targetRef.current = text;\n const visibleRef = useRef(visible);\n visibleRef.current = visible;\n const cfgRef = useRef({ speed, deleteSpeed, delay, skip });\n cfgRef.current = { speed, deleteSpeed, delay, skip };\n const cbRef = useRef({ onDone, onUpdate });\n cbRef.current = { onDone, onUpdate };\n\n const rafRef = useRef(0);\n const runningRef = useRef(false);\n const startedRef = useRef(false); // the one-time initial delay has elapsed\n const kickRef = useRef<() => void>(() => {});\n\n // The persistent animation loop — created once, reads everything via refs and\n // is cancelled only on unmount, so a growing `text` never resets its progress.\n useEffect(() => {\n let lastTs = 0;\n let acc = 0;\n let delayLeft = 0;\n\n const frame = (ts: number) => {\n if (lastTs === 0) {\n lastTs = ts;\n rafRef.current = requestAnimationFrame(frame);\n return;\n }\n const dt = ts - lastTs;\n lastTs = ts;\n\n // Burn the one-time initial delay before the first character.\n if (!startedRef.current) {\n delayLeft -= dt;\n if (delayLeft > 0) {\n rafRef.current = requestAnimationFrame(frame);\n return;\n }\n startedRef.current = true;\n }\n\n acc += dt;\n const { speed: sp, deleteSpeed: dsp } = cfgRef.current;\n const typeIv = 1000 / Math.max(1, sp);\n const delIv = 1000 / Math.max(1, dsp ?? sp * 2);\n\n let changed = false;\n // Emit as many characters as the elapsed time allows (frame-rate independent).\n for (let guard = 0; guard < 2000; guard++) {\n const cur = visibleRef.current;\n const tgt = targetRef.current;\n if (cur === tgt) break;\n const deleting = cur.length > commonPrefixLen(cur, tgt);\n if (acc < (deleting ? delIv : typeIv)) break;\n acc -= deleting ? delIv : typeIv;\n visibleRef.current = deleting ? cur.slice(0, -1) : tgt.slice(0, cur.length + 1);\n changed = true;\n }\n\n if (changed) {\n setVisible(visibleRef.current);\n cbRef.current.onUpdate?.(visibleRef.current);\n }\n\n if (visibleRef.current === targetRef.current) {\n runningRef.current = false;\n cbRef.current.onDone?.();\n return; // idle — the next text change re-kicks the loop\n }\n rafRef.current = requestAnimationFrame(frame);\n };\n\n kickRef.current = () => {\n if (cfgRef.current.skip || runningRef.current) return;\n if (visibleRef.current === targetRef.current) return;\n runningRef.current = true;\n lastTs = 0;\n acc = 0;\n delayLeft = startedRef.current ? 0 : cfgRef.current.delay * 1000;\n rafRef.current = requestAnimationFrame(frame);\n };\n\n return () => {\n cancelAnimationFrame(rafRef.current);\n runningRef.current = false;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // React to text / skip / activation: jump when instant, else — once it's this\n // slot's turn — report the reveal duration and (re)start the loop.\n useEffect(() => {\n if (skip) {\n visibleRef.current = text;\n setVisible(text);\n slotRef.current.finish(); // instant content hands the timeline off at once\n return;\n }\n if (!active) return; // wait until this slot is the head of the timeline\n // Constant rate ⇒ the reveal takes delay + (length / speed). Reporting it\n // lets ProgressiveList delay the next item until this text finishes typing.\n const interval = 1000 / Math.max(1, speed);\n const durationMs = Math.max(0, delay) * 1000 + text.length * interval;\n slotRef.current.report(durationMs);\n kickRef.current();\n }, [text, skip, active, speed, delay]);\n\n const meta: ProgressiveTextMeta = {\n done: visible === text,\n deleting: visible.length > commonPrefixLen(visible, text),\n };\n\n const Wrapper = (as ?? 'span') as ElementType;\n return (\n <Wrapper className={className}>\n {children ? children(visible, meta) : visible}\n {caret && !children && !meta.done && (\n <span aria-hidden className={cn('ml-px inline-block animate-pulse')}>\n ▍\n </span>\n )}\n </Wrapper>\n );\n}\n"],"names":["commonPrefixLen","a","b","n","i","reducedMotion","ProgressiveText","text","speed","deleteSpeed","delay","instant","caret","as","className","children","onDone","onUpdate","skip","visible","setVisible","useState","slot","useProgressiveSlot","active","slotRef","useRef","targetRef","visibleRef","cfgRef","cbRef","rafRef","runningRef","startedRef","kickRef","useEffect","lastTs","acc","delayLeft","frame","ts","dt","sp","dsp","typeIv","delIv","changed","guard","cur","tgt","deleting","_b","_a","_d","_c","interval","durationMs","meta","jsxs","jsx","cn"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/progressive-timeline/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACrF,YAAY,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export interface ProgressiveSlotValue {
|
|
3
|
+
/**
|
|
4
|
+
* True when this slot is the current head of the timeline — the moment its
|
|
5
|
+
* children are meant to animate. Outside a {@link ProgressiveList} this is
|
|
6
|
+
* always `true`, so a progressive element just animates on its own.
|
|
7
|
+
*/
|
|
8
|
+
active: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* A participating child announces that — once active — it will animate for
|
|
11
|
+
* `durationMs`. The timeline waits (at least) that long before revealing the
|
|
12
|
+
* next slot: this is how a list element's appearance is delayed by the inner
|
|
13
|
+
* animation of the one before it. Calling it again raises the wait to the
|
|
14
|
+
* longest reported duration (e.g. as streamed text grows). Returns a `done`
|
|
15
|
+
* callback that advances the timeline immediately — call it the instant the
|
|
16
|
+
* child actually finishes, if you want to hand off early.
|
|
17
|
+
*/
|
|
18
|
+
report: (durationMs: number) => () => void;
|
|
19
|
+
/** Advance the timeline for this slot right now (e.g. instant / static content). */
|
|
20
|
+
finish: () => void;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Read the enclosing {@link ProgressiveList} timeline slot. Any component can
|
|
24
|
+
* consume this to participate in the sequence:
|
|
25
|
+
* - hold its animation until it's this slot's turn (`active`);
|
|
26
|
+
* - tell the timeline how long it will animate (`report`) — so the *next* list
|
|
27
|
+
* element is delayed until this one's inner animation completes — or that it's
|
|
28
|
+
* done (`finish` / the `done` returned by `report`).
|
|
29
|
+
*
|
|
30
|
+
* Outside a ProgressiveList it returns an always-active no-op, so progressive
|
|
31
|
+
* components keep working standalone.
|
|
32
|
+
*/
|
|
33
|
+
export declare function useProgressiveSlot(): ProgressiveSlotValue;
|
|
34
|
+
/**
|
|
35
|
+
* One slot on a {@link ProgressiveList}'s timeline. Provides the slot context to
|
|
36
|
+
* its subtree and, while `active`, decides when to hand off to the next slot:
|
|
37
|
+
* after the longest duration its children reported, or — if nothing reported —
|
|
38
|
+
* after `fallbackMs`; whichever child calls its `done` early wins.
|
|
39
|
+
*/
|
|
40
|
+
export declare function ProgressiveTimelineSlot({ active, fallbackMs, onComplete, children, }: {
|
|
41
|
+
active: boolean;
|
|
42
|
+
fallbackMs: number;
|
|
43
|
+
onComplete: () => void;
|
|
44
|
+
children: ReactNode;
|
|
45
|
+
}): import("react").JSX.Element;
|
|
46
|
+
//# sourceMappingURL=progressive-timeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progressive-timeline.d.ts","sourceRoot":"","sources":["../../../src/components/progressive-timeline/progressive-timeline.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAyD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAQ9F,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,MAAM,EAAE,OAAO,CAAC;IAChB;;;;;;;;OAQG;IACH,MAAM,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,IAAI,CAAC;IAC3C,oFAAoF;IACpF,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAUD;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,IAAI,oBAAoB,CAEzD;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,MAAM,EACN,UAAU,EACV,UAAU,EACV,QAAQ,GACT,EAAE;IACD,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,QAAQ,EAAE,SAAS,CAAC;CACrB,+BAmEA"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { jsx as w } from "react/jsx-runtime";
|
|
2
|
+
import { useRef as i, useMemo as d, useEffect as A, useContext as T, createContext as y } from "react";
|
|
3
|
+
function u() {
|
|
4
|
+
return typeof performance < "u" && typeof performance.now == "function" ? performance.now() : Date.now();
|
|
5
|
+
}
|
|
6
|
+
const D = {
|
|
7
|
+
active: !0,
|
|
8
|
+
report: () => () => {
|
|
9
|
+
},
|
|
10
|
+
finish: () => {
|
|
11
|
+
}
|
|
12
|
+
}, x = y(D);
|
|
13
|
+
function C() {
|
|
14
|
+
return T(x);
|
|
15
|
+
}
|
|
16
|
+
function O({
|
|
17
|
+
active: r,
|
|
18
|
+
fallbackMs: s,
|
|
19
|
+
onComplete: a,
|
|
20
|
+
children: v
|
|
21
|
+
}) {
|
|
22
|
+
const n = i({ activatedAt: 0, anyReport: !1, maxDuration: 0, completed: !1, timer: 0 });
|
|
23
|
+
r && n.current.activatedAt === 0 && (n.current.activatedAt = u());
|
|
24
|
+
const m = i(r);
|
|
25
|
+
m.current = r;
|
|
26
|
+
const f = i(s);
|
|
27
|
+
f.current = s;
|
|
28
|
+
const p = i(a);
|
|
29
|
+
p.current = a;
|
|
30
|
+
const o = d(() => {
|
|
31
|
+
const e = () => {
|
|
32
|
+
const t = n.current;
|
|
33
|
+
t.completed || (t.completed = !0, t.timer && (clearTimeout(t.timer), t.timer = 0), p.current());
|
|
34
|
+
}, l = () => {
|
|
35
|
+
const t = n.current;
|
|
36
|
+
if (t.completed || !m.current) return;
|
|
37
|
+
t.timer && clearTimeout(t.timer);
|
|
38
|
+
const c = t.anyReport ? t.maxDuration : f.current, h = u() - t.activatedAt;
|
|
39
|
+
t.timer = window.setTimeout(e, Math.max(0, c - h));
|
|
40
|
+
};
|
|
41
|
+
return { complete: e, schedule: l, report: (t) => {
|
|
42
|
+
const c = n.current;
|
|
43
|
+
return c.anyReport = !0, c.maxDuration = Math.max(c.maxDuration, t), l(), e;
|
|
44
|
+
} };
|
|
45
|
+
}, []), R = d(
|
|
46
|
+
() => ({ active: r, report: o.report, finish: o.complete }),
|
|
47
|
+
[r, o]
|
|
48
|
+
);
|
|
49
|
+
return A(() => {
|
|
50
|
+
if (!r) return;
|
|
51
|
+
const e = n.current;
|
|
52
|
+
if (!e.completed)
|
|
53
|
+
return e.activatedAt === 0 && (e.activatedAt = u()), o.schedule(), () => {
|
|
54
|
+
e.timer && (clearTimeout(e.timer), e.timer = 0);
|
|
55
|
+
};
|
|
56
|
+
}, [r, o]), /* @__PURE__ */ w(x.Provider, { value: R, children: v });
|
|
57
|
+
}
|
|
58
|
+
export {
|
|
59
|
+
O as ProgressiveTimelineSlot,
|
|
60
|
+
C as useProgressiveSlot
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=progressive-timeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progressive-timeline.js","sources":["../../../src/components/progressive-timeline/progressive-timeline.tsx"],"sourcesContent":["import { createContext, useContext, useEffect, useMemo, useRef, type ReactNode } from 'react';\n\nfunction now(): number {\n return typeof performance !== 'undefined' && typeof performance.now === 'function'\n ? performance.now()\n : Date.now();\n}\n\nexport interface ProgressiveSlotValue {\n /**\n * True when this slot is the current head of the timeline — the moment its\n * children are meant to animate. Outside a {@link ProgressiveList} this is\n * always `true`, so a progressive element just animates on its own.\n */\n active: boolean;\n /**\n * A participating child announces that — once active — it will animate for\n * `durationMs`. The timeline waits (at least) that long before revealing the\n * next slot: this is how a list element's appearance is delayed by the inner\n * animation of the one before it. Calling it again raises the wait to the\n * longest reported duration (e.g. as streamed text grows). Returns a `done`\n * callback that advances the timeline immediately — call it the instant the\n * child actually finishes, if you want to hand off early.\n */\n report: (durationMs: number) => () => void;\n /** Advance the timeline for this slot right now (e.g. instant / static content). */\n finish: () => void;\n}\n\nconst NOOP_SLOT: ProgressiveSlotValue = {\n active: true,\n report: () => () => {},\n finish: () => {},\n};\n\nconst ProgressiveSlotContext = createContext<ProgressiveSlotValue>(NOOP_SLOT);\n\n/**\n * Read the enclosing {@link ProgressiveList} timeline slot. Any component can\n * consume this to participate in the sequence:\n * - hold its animation until it's this slot's turn (`active`);\n * - tell the timeline how long it will animate (`report`) — so the *next* list\n * element is delayed until this one's inner animation completes — or that it's\n * done (`finish` / the `done` returned by `report`).\n *\n * Outside a ProgressiveList it returns an always-active no-op, so progressive\n * components keep working standalone.\n */\nexport function useProgressiveSlot(): ProgressiveSlotValue {\n return useContext(ProgressiveSlotContext);\n}\n\n/**\n * One slot on a {@link ProgressiveList}'s timeline. Provides the slot context to\n * its subtree and, while `active`, decides when to hand off to the next slot:\n * after the longest duration its children reported, or — if nothing reported —\n * after `fallbackMs`; whichever child calls its `done` early wins.\n */\nexport function ProgressiveTimelineSlot({\n active,\n fallbackMs,\n onComplete,\n children,\n}: {\n active: boolean;\n fallbackMs: number;\n onComplete: () => void;\n children: ReactNode;\n}) {\n const st = useRef({ activatedAt: 0, anyReport: false, maxDuration: 0, completed: false, timer: 0 });\n\n // A slot is mounted exactly when it becomes the head, so its first render is\n // the activation instant. Stamp it during render so a child's report() — which\n // runs in a child effect, before this component's own effects — sees a valid\n // clock to measure elapsed time against.\n if (active && st.current.activatedAt === 0) st.current.activatedAt = now();\n\n // Latest props read by the (stable) api closures without rebuilding them.\n const activeRef = useRef(active);\n activeRef.current = active;\n const fallbackRef = useRef(fallbackMs);\n fallbackRef.current = fallbackMs;\n const onCompleteRef = useRef(onComplete);\n onCompleteRef.current = onComplete;\n\n const api = useMemo(() => {\n const complete = () => {\n const s = st.current;\n if (s.completed) return;\n s.completed = true;\n if (s.timer) {\n clearTimeout(s.timer);\n s.timer = 0;\n }\n onCompleteRef.current();\n };\n const schedule = () => {\n const s = st.current;\n if (s.completed || !activeRef.current) return;\n if (s.timer) clearTimeout(s.timer);\n const target = s.anyReport ? s.maxDuration : fallbackRef.current;\n const elapsed = now() - s.activatedAt;\n s.timer = window.setTimeout(complete, Math.max(0, target - elapsed));\n };\n const report = (durationMs: number) => {\n const s = st.current;\n s.anyReport = true;\n s.maxDuration = Math.max(s.maxDuration, durationMs);\n schedule();\n return complete;\n };\n return { complete, schedule, report };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const value = useMemo<ProgressiveSlotValue>(\n () => ({ active, report: api.report, finish: api.complete }),\n [active, api],\n );\n\n useEffect(() => {\n if (!active) return;\n const s = st.current;\n if (s.completed) return;\n if (s.activatedAt === 0) s.activatedAt = now();\n api.schedule(); // fallback / duration timer (reschedules over any earlier child report)\n return () => {\n if (s.timer) {\n clearTimeout(s.timer);\n s.timer = 0;\n }\n };\n }, [active, api]);\n\n return <ProgressiveSlotContext.Provider value={value}>{children}</ProgressiveSlotContext.Provider>;\n}\n"],"names":["now","NOOP_SLOT","ProgressiveSlotContext","createContext","useProgressiveSlot","useContext","ProgressiveTimelineSlot","active","fallbackMs","onComplete","children","st","useRef","activeRef","fallbackRef","onCompleteRef","api","useMemo","complete","s","schedule","target","elapsed","durationMs","value","useEffect","jsx"],"mappings":";;AAEA,SAASA,IAAc;AACrB,SAAO,OAAO,cAAgB,OAAe,OAAO,YAAY,OAAQ,aACpE,YAAY,QACZ,KAAK,IAAA;AACX;AAuBA,MAAMC,IAAkC;AAAA,EACtC,QAAQ;AAAA,EACR,QAAQ,MAAM,MAAM;AAAA,EAAC;AAAA,EACrB,QAAQ,MAAM;AAAA,EAAC;AACjB,GAEMC,IAAyBC,EAAoCF,CAAS;AAarE,SAASG,IAA2C;AACzD,SAAOC,EAAWH,CAAsB;AAC1C;AAQO,SAASI,EAAwB;AAAA,EACtC,QAAAC;AAAA,EACA,YAAAC;AAAA,EACA,YAAAC;AAAA,EACA,UAAAC;AACF,GAKG;AACD,QAAMC,IAAKC,EAAO,EAAE,aAAa,GAAG,WAAW,IAAO,aAAa,GAAG,WAAW,IAAO,OAAO,GAAG;AAMlG,EAAIL,KAAUI,EAAG,QAAQ,gBAAgB,MAAGA,EAAG,QAAQ,cAAcX,EAAA;AAGrE,QAAMa,IAAYD,EAAOL,CAAM;AAC/B,EAAAM,EAAU,UAAUN;AACpB,QAAMO,IAAcF,EAAOJ,CAAU;AACrC,EAAAM,EAAY,UAAUN;AACtB,QAAMO,IAAgBH,EAAOH,CAAU;AACvC,EAAAM,EAAc,UAAUN;AAExB,QAAMO,IAAMC,EAAQ,MAAM;AACxB,UAAMC,IAAW,MAAM;AACrB,YAAMC,IAAIR,EAAG;AACb,MAAIQ,EAAE,cACNA,EAAE,YAAY,IACVA,EAAE,UACJ,aAAaA,EAAE,KAAK,GACpBA,EAAE,QAAQ,IAEZJ,EAAc,QAAA;AAAA,IAChB,GACMK,IAAW,MAAM;AACrB,YAAMD,IAAIR,EAAG;AACb,UAAIQ,EAAE,aAAa,CAACN,EAAU,QAAS;AACvC,MAAIM,EAAE,SAAO,aAAaA,EAAE,KAAK;AACjC,YAAME,IAASF,EAAE,YAAYA,EAAE,cAAcL,EAAY,SACnDQ,IAAUtB,MAAQmB,EAAE;AAC1B,MAAAA,EAAE,QAAQ,OAAO,WAAWD,GAAU,KAAK,IAAI,GAAGG,IAASC,CAAO,CAAC;AAAA,IACrE;AAQA,WAAO,EAAE,UAAAJ,GAAU,UAAAE,GAAU,QAPd,CAACG,MAAuB;AACrC,YAAMJ,IAAIR,EAAG;AACb,aAAAQ,EAAE,YAAY,IACdA,EAAE,cAAc,KAAK,IAAIA,EAAE,aAAaI,CAAU,GAClDH,EAAA,GACOF;AAAA,IACT,EAC6B;AAAA,EAE/B,GAAG,CAAA,CAAE,GAECM,IAAQP;AAAA,IACZ,OAAO,EAAE,QAAAV,GAAQ,QAAQS,EAAI,QAAQ,QAAQA,EAAI;IACjD,CAACT,GAAQS,CAAG;AAAA,EAAA;AAGd,SAAAS,EAAU,MAAM;AACd,QAAI,CAAClB,EAAQ;AACb,UAAMY,IAAIR,EAAG;AACb,QAAI,CAAAQ,EAAE;AACN,aAAIA,EAAE,gBAAgB,MAAGA,EAAE,cAAcnB,EAAA,IACzCgB,EAAI,SAAA,GACG,MAAM;AACX,QAAIG,EAAE,UACJ,aAAaA,EAAE,KAAK,GACpBA,EAAE,QAAQ;AAAA,MAEd;AAAA,EACF,GAAG,CAACZ,GAAQS,CAAG,CAAC,GAET,gBAAAU,EAACxB,EAAuB,UAAvB,EAAgC,OAAAsB,GAAe,UAAAd,EAAA,CAAS;AAClE;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/relative-time/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { TimeInput } from '../../lib/format';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
export interface RelativeTimeProps extends React.TimeHTMLAttributes<HTMLTimeElement> {
|
|
4
|
+
date: TimeInput;
|
|
5
|
+
/** Re-render cadence, ms. `0` freezes it. */
|
|
6
|
+
every?: number;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* `<time>` that says "4m ago" and keeps saying the right thing — it ticks, so a
|
|
10
|
+
* dashboard left open overnight doesn't still claim the job ran "just now".
|
|
11
|
+
* Hovering shows the absolute timestamp.
|
|
12
|
+
*/
|
|
13
|
+
export declare function RelativeTime({ date, every, ...props }: RelativeTimeProps): React.JSX.Element;
|
|
14
|
+
//# sourceMappingURL=relative-time.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relative-time.d.ts","sourceRoot":"","sources":["../../../src/components/relative-time/relative-time.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAwB,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAExE,MAAM,WAAW,iBAAkB,SAAQ,KAAK,CAAC,kBAAkB,CAAC,eAAe,CAAC;IAClF,IAAI,EAAE,SAAS,CAAC;IAChB,6CAA6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,EAAE,IAAI,EAAE,KAAc,EAAE,GAAG,KAAK,EAAE,EAAE,iBAAiB,qBAcjF"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { jsx as o } from "react/jsx-runtime";
|
|
2
|
+
import * as i from "react";
|
|
3
|
+
import { relTime as c, fmtDateTime as f } from "../../lib/format.js";
|
|
4
|
+
function u({ date: r, every: t = 3e4, ...m }) {
|
|
5
|
+
const [, n] = i.useReducer((e) => e + 1, 0);
|
|
6
|
+
return i.useEffect(() => {
|
|
7
|
+
if (!t) return;
|
|
8
|
+
const e = setInterval(n, t);
|
|
9
|
+
return () => clearInterval(e);
|
|
10
|
+
}, [t]), /* @__PURE__ */ o("time", { title: f(r), ...m, children: c(r) });
|
|
11
|
+
}
|
|
12
|
+
export {
|
|
13
|
+
u as RelativeTime
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=relative-time.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relative-time.js","sources":["../../../src/components/relative-time/relative-time.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { fmtDateTime, relTime, type TimeInput } from '../../lib/format';\n\nexport interface RelativeTimeProps extends React.TimeHTMLAttributes<HTMLTimeElement> {\n date: TimeInput;\n /** Re-render cadence, ms. `0` freezes it. */\n every?: number;\n}\n\n/**\n * `<time>` that says \"4m ago\" and keeps saying the right thing — it ticks, so a\n * dashboard left open overnight doesn't still claim the job ran \"just now\".\n * Hovering shows the absolute timestamp.\n */\nexport function RelativeTime({ date, every = 30_000, ...props }: RelativeTimeProps) {\n const [, tick] = React.useReducer((n: number) => n + 1, 0);\n\n React.useEffect(() => {\n if (!every) return;\n const id = setInterval(tick, every);\n return () => clearInterval(id);\n }, [every]);\n\n return (\n <time title={fmtDateTime(date)} {...props}>\n {relTime(date)}\n </time>\n );\n}\n"],"names":["RelativeTime","date","every","props","tick","React","n","id","jsx","fmtDateTime","relTime"],"mappings":";;;AAeO,SAASA,EAAa,EAAE,MAAAC,GAAM,OAAAC,IAAQ,KAAQ,GAAGC,KAA4B;AAClF,QAAM,CAAA,EAAGC,CAAI,IAAIC,EAAM,WAAW,CAACC,MAAcA,IAAI,GAAG,CAAC;AAEzD,SAAAD,EAAM,UAAU,MAAM;AACpB,QAAI,CAACH,EAAO;AACZ,UAAMK,IAAK,YAAYH,GAAMF,CAAK;AAClC,WAAO,MAAM,cAAcK,CAAE;AAAA,EAC/B,GAAG,CAACL,CAAK,CAAC,GAGR,gBAAAM,EAAC,QAAA,EAAK,OAAOC,EAAYR,CAAI,GAAI,GAAGE,GACjC,UAAAO,EAAQT,CAAI,EAAA,CACf;AAEJ;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/resizable-layout/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,YAAY,EACV,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,EACrB,UAAU,EACV,UAAU,GACX,MAAM,oBAAoB,CAAC"}
|