@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,11 @@
|
|
|
1
|
+
export interface SpinnerProps {
|
|
2
|
+
size?: 'sm' | 'md' | 'lg';
|
|
3
|
+
/** Text under the spinner (also its accessible name). */
|
|
4
|
+
label?: string;
|
|
5
|
+
/** Centre it in a tall block — the "page is loading" shape. */
|
|
6
|
+
center?: boolean;
|
|
7
|
+
className?: string;
|
|
8
|
+
}
|
|
9
|
+
/** The `Loader2 animate-spin` block that every project hand-rolls. */
|
|
10
|
+
export declare function Spinner({ size, label, center, className }: SpinnerProps): import("react").JSX.Element;
|
|
11
|
+
//# sourceMappingURL=spinner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spinner.d.ts","sourceRoot":"","sources":["../../../src/components/spinner/spinner.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID,sEAAsE;AACtE,wBAAgB,OAAO,CAAC,EAAE,IAAW,EAAE,KAAK,EAAE,MAAc,EAAE,SAAS,EAAE,EAAE,YAAY,+BAuBtF"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { jsx as i, jsxs as m } from "react/jsx-runtime";
|
|
2
|
+
import { Loader2 as a } from "lucide-react";
|
|
3
|
+
import { cn as o } from "../../lib/utils.js";
|
|
4
|
+
const d = { sm: "size-4", md: "size-6", lg: "size-9" };
|
|
5
|
+
function c({ size: n = "md", label: e, center: r = !1, className: s }) {
|
|
6
|
+
const t = /* @__PURE__ */ i(
|
|
7
|
+
a,
|
|
8
|
+
{
|
|
9
|
+
className: o("animate-spin text-muted-foreground", d[n], !r && s),
|
|
10
|
+
role: "status",
|
|
11
|
+
"aria-label": e ?? "Loading"
|
|
12
|
+
}
|
|
13
|
+
);
|
|
14
|
+
return !r && !e ? t : /* @__PURE__ */ m(
|
|
15
|
+
"div",
|
|
16
|
+
{
|
|
17
|
+
className: o(
|
|
18
|
+
"flex flex-col items-center justify-center gap-3",
|
|
19
|
+
r && "py-16",
|
|
20
|
+
r && s
|
|
21
|
+
),
|
|
22
|
+
children: [
|
|
23
|
+
t,
|
|
24
|
+
e && /* @__PURE__ */ i("p", { className: "text-sm text-muted-foreground", children: e })
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
export {
|
|
30
|
+
c as Spinner
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=spinner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spinner.js","sources":["../../../src/components/spinner/spinner.tsx"],"sourcesContent":["import { Loader2 } from 'lucide-react';\n\nimport { cn } from '../../lib/utils';\n\nexport interface SpinnerProps {\n size?: 'sm' | 'md' | 'lg';\n /** Text under the spinner (also its accessible name). */\n label?: string;\n /** Centre it in a tall block — the \"page is loading\" shape. */\n center?: boolean;\n className?: string;\n}\n\nconst SIZES = { sm: 'size-4', md: 'size-6', lg: 'size-9' } as const;\n\n/** The `Loader2 animate-spin` block that every project hand-rolls. */\nexport function Spinner({ size = 'md', label, center = false, className }: SpinnerProps) {\n const spinner = (\n <Loader2\n className={cn('animate-spin text-muted-foreground', SIZES[size], !center && className)}\n role=\"status\"\n aria-label={label ?? 'Loading'}\n />\n );\n\n if (!center && !label) return spinner;\n\n return (\n <div\n className={cn(\n 'flex flex-col items-center justify-center gap-3',\n center && 'py-16',\n center && className,\n )}\n >\n {spinner}\n {label && <p className=\"text-sm text-muted-foreground\">{label}</p>}\n </div>\n );\n}\n"],"names":["SIZES","Spinner","size","label","center","className","spinner","jsx","Loader2","cn","jsxs"],"mappings":";;;AAaA,MAAMA,IAAQ,EAAE,IAAI,UAAU,IAAI,UAAU,IAAI,SAAA;AAGzC,SAASC,EAAQ,EAAE,MAAAC,IAAO,MAAM,OAAAC,GAAO,QAAAC,IAAS,IAAO,WAAAC,KAA2B;AACvF,QAAMC,IACJ,gBAAAC;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,WAAWC,EAAG,sCAAsCT,EAAME,CAAI,GAAG,CAACE,KAAUC,CAAS;AAAA,MACrF,MAAK;AAAA,MACL,cAAYF,KAAS;AAAA,IAAA;AAAA,EAAA;AAIzB,SAAI,CAACC,KAAU,CAACD,IAAcG,IAG5B,gBAAAI;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWD;AAAA,QACT;AAAA,QACAL,KAAU;AAAA,QACVA,KAAUC;AAAA,MAAA;AAAA,MAGX,UAAA;AAAA,QAAAC;AAAA,QACAH,KAAS,gBAAAI,EAAC,KAAA,EAAE,WAAU,iCAAiC,UAAAJ,EAAA,CAAM;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGpE;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/status-badge/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAChE,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { LucideIcon } from 'lucide-react';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
export type Tone = 'neutral' | 'sky' | 'emerald' | 'amber' | 'rose' | 'violet';
|
|
4
|
+
export interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
5
|
+
tone?: Tone;
|
|
6
|
+
/** A leading dot instead of an icon — for tag/priority chips. */
|
|
7
|
+
dot?: boolean;
|
|
8
|
+
}
|
|
9
|
+
/** A small pill. The base every status/tag chip in the lab is built from. */
|
|
10
|
+
export declare function Badge({ tone, dot, className, children, ...props }: BadgeProps): React.JSX.Element;
|
|
11
|
+
export interface StatusMeta {
|
|
12
|
+
label: string;
|
|
13
|
+
tone: Tone;
|
|
14
|
+
Icon?: LucideIcon;
|
|
15
|
+
/** Spin the icon — for anything in flight. */
|
|
16
|
+
spin?: boolean;
|
|
17
|
+
}
|
|
18
|
+
/** The job lifecycle every queue in the lab speaks. Extend it via `meta`. */
|
|
19
|
+
export declare const JOB_STATUS: Record<string, StatusMeta>;
|
|
20
|
+
export interface StatusBadgeProps extends Omit<BadgeProps, 'tone' | 'children'> {
|
|
21
|
+
status: string;
|
|
22
|
+
/** Override or extend the default map (merged over `JOB_STATUS`). */
|
|
23
|
+
meta?: Record<string, StatusMeta>;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* A status pill driven by a `status → {label, tone, icon}` map, so the same
|
|
27
|
+
* string renders the same colour in every service.
|
|
28
|
+
* Unknown statuses degrade to a neutral pill of the raw string, never a crash.
|
|
29
|
+
*/
|
|
30
|
+
export declare function StatusBadge({ status, meta, className, ...props }: StatusBadgeProps): React.JSX.Element;
|
|
31
|
+
//# sourceMappingURL=status-badge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status-badge.d.ts","sourceRoot":"","sources":["../../../src/components/status-badge/status-badge.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAOL,KAAK,UAAU,EAChB,MAAM,cAAc,CAAC;AAItB,MAAM,MAAM,IAAI,GAAG,SAAS,GAAG,KAAK,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;AAe/E,MAAM,WAAW,UAAW,SAAQ,KAAK,CAAC,cAAc,CAAC,eAAe,CAAC;IACvE,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,iEAAiE;IACjE,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,6EAA6E;AAC7E,wBAAgB,KAAK,CAAC,EAAE,IAAgB,EAAE,GAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,UAAU,qBAcjG;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,IAAI,CAAC;IACX,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,8CAA8C;IAC9C,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,6EAA6E;AAC7E,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAUjD,CAAC;AAEF,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,CAAC;IAC7E,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CACnC;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,gBAAgB,qBASlF"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { jsxs as c, jsx as i } from "react/jsx-runtime";
|
|
2
|
+
import "react";
|
|
3
|
+
import { CircleDashed as m, Ban as u, TriangleAlert as a, Check as d, Loader2 as x, Clock as s } from "lucide-react";
|
|
4
|
+
import { cn as b } from "../../lib/utils.js";
|
|
5
|
+
const g = {
|
|
6
|
+
neutral: "bg-muted text-muted-foreground border-border",
|
|
7
|
+
sky: "bg-sky-500/12 text-sky-600 border-sky-500/25 dark:text-sky-400",
|
|
8
|
+
emerald: "bg-emerald-500/12 text-emerald-600 border-emerald-500/25 dark:text-emerald-400",
|
|
9
|
+
amber: "bg-amber-500/12 text-amber-600 border-amber-500/25 dark:text-amber-400",
|
|
10
|
+
rose: "bg-rose-500/12 text-rose-600 border-rose-500/25 dark:text-rose-400",
|
|
11
|
+
violet: "bg-violet-500/12 text-violet-600 border-violet-500/25 dark:text-violet-400"
|
|
12
|
+
};
|
|
13
|
+
function p({ tone: r = "neutral", dot: n = !1, className: t, children: o, ...e }) {
|
|
14
|
+
return /* @__PURE__ */ c(
|
|
15
|
+
"span",
|
|
16
|
+
{
|
|
17
|
+
className: b(
|
|
18
|
+
"inline-flex items-center gap-1.5 rounded-full border px-2 py-0.5 text-xs font-medium whitespace-nowrap [&_svg]:size-3",
|
|
19
|
+
g[r],
|
|
20
|
+
t
|
|
21
|
+
),
|
|
22
|
+
...e,
|
|
23
|
+
children: [
|
|
24
|
+
n && /* @__PURE__ */ i("span", { className: "size-1.5 rounded-full bg-current" }),
|
|
25
|
+
o
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
const k = {
|
|
31
|
+
queued: { label: "Queued", tone: "neutral", Icon: s },
|
|
32
|
+
pending: { label: "Pending", tone: "neutral", Icon: s },
|
|
33
|
+
running: { label: "Running", tone: "sky", Icon: x, spin: !0 },
|
|
34
|
+
done: { label: "Done", tone: "emerald", Icon: d },
|
|
35
|
+
succeeded: { label: "Succeeded", tone: "emerald", Icon: d },
|
|
36
|
+
error: { label: "Error", tone: "rose", Icon: a },
|
|
37
|
+
failed: { label: "Failed", tone: "rose", Icon: a },
|
|
38
|
+
cancelled: { label: "Cancelled", tone: "amber", Icon: u },
|
|
39
|
+
archived: { label: "Archived", tone: "violet", Icon: m }
|
|
40
|
+
};
|
|
41
|
+
function h({ status: r, meta: n, className: t, ...o }) {
|
|
42
|
+
const e = { ...k, ...n }[r] ?? { label: r, tone: "neutral" }, { Icon: l } = e;
|
|
43
|
+
return /* @__PURE__ */ c(p, { tone: e.tone, className: t, ...o, children: [
|
|
44
|
+
l && /* @__PURE__ */ i(l, { className: b(e.spin && "animate-spin") }),
|
|
45
|
+
e.label
|
|
46
|
+
] });
|
|
47
|
+
}
|
|
48
|
+
export {
|
|
49
|
+
p as Badge,
|
|
50
|
+
k as JOB_STATUS,
|
|
51
|
+
h as StatusBadge
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=status-badge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status-badge.js","sources":["../../../src/components/status-badge/status-badge.tsx"],"sourcesContent":["import * as React from 'react';\nimport {\n Ban,\n Check,\n CircleDashed,\n Clock,\n Loader2,\n TriangleAlert,\n type LucideIcon,\n} from 'lucide-react';\n\nimport { cn } from '../../lib/utils';\n\nexport type Tone = 'neutral' | 'sky' | 'emerald' | 'amber' | 'rose' | 'violet';\n\n/*\n * Tones are written out in full — Tailwind scans source text, so a template\n * literal like `bg-${tone}-500/12` would compile to nothing.\n */\nconst TONES: Record<Tone, string> = {\n neutral: 'bg-muted text-muted-foreground border-border',\n sky: 'bg-sky-500/12 text-sky-600 border-sky-500/25 dark:text-sky-400',\n emerald: 'bg-emerald-500/12 text-emerald-600 border-emerald-500/25 dark:text-emerald-400',\n amber: 'bg-amber-500/12 text-amber-600 border-amber-500/25 dark:text-amber-400',\n rose: 'bg-rose-500/12 text-rose-600 border-rose-500/25 dark:text-rose-400',\n violet: 'bg-violet-500/12 text-violet-600 border-violet-500/25 dark:text-violet-400',\n};\n\nexport interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {\n tone?: Tone;\n /** A leading dot instead of an icon — for tag/priority chips. */\n dot?: boolean;\n}\n\n/** A small pill. The base every status/tag chip in the lab is built from. */\nexport function Badge({ tone = 'neutral', dot = false, className, children, ...props }: BadgeProps) {\n return (\n <span\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-full border px-2 py-0.5 text-xs font-medium whitespace-nowrap [&_svg]:size-3',\n TONES[tone],\n className,\n )}\n {...props}\n >\n {dot && <span className=\"size-1.5 rounded-full bg-current\" />}\n {children}\n </span>\n );\n}\n\nexport interface StatusMeta {\n label: string;\n tone: Tone;\n Icon?: LucideIcon;\n /** Spin the icon — for anything in flight. */\n spin?: boolean;\n}\n\n/** The job lifecycle every queue in the lab speaks. Extend it via `meta`. */\nexport const JOB_STATUS: Record<string, StatusMeta> = {\n queued: { label: 'Queued', tone: 'neutral', Icon: Clock },\n pending: { label: 'Pending', tone: 'neutral', Icon: Clock },\n running: { label: 'Running', tone: 'sky', Icon: Loader2, spin: true },\n done: { label: 'Done', tone: 'emerald', Icon: Check },\n succeeded: { label: 'Succeeded', tone: 'emerald', Icon: Check },\n error: { label: 'Error', tone: 'rose', Icon: TriangleAlert },\n failed: { label: 'Failed', tone: 'rose', Icon: TriangleAlert },\n cancelled: { label: 'Cancelled', tone: 'amber', Icon: Ban },\n archived: { label: 'Archived', tone: 'violet', Icon: CircleDashed },\n};\n\nexport interface StatusBadgeProps extends Omit<BadgeProps, 'tone' | 'children'> {\n status: string;\n /** Override or extend the default map (merged over `JOB_STATUS`). */\n meta?: Record<string, StatusMeta>;\n}\n\n/**\n * A status pill driven by a `status → {label, tone, icon}` map, so the same\n * string renders the same colour in every service.\n * Unknown statuses degrade to a neutral pill of the raw string, never a crash.\n */\nexport function StatusBadge({ status, meta, className, ...props }: StatusBadgeProps) {\n const entry: StatusMeta = { ...JOB_STATUS, ...meta }[status] ?? { label: status, tone: 'neutral' };\n const { Icon } = entry;\n return (\n <Badge tone={entry.tone} className={className} {...props}>\n {Icon && <Icon className={cn(entry.spin && 'animate-spin')} />}\n {entry.label}\n </Badge>\n );\n}\n"],"names":["TONES","Badge","tone","dot","className","children","props","jsxs","cn","jsx","JOB_STATUS","Clock","Loader2","Check","TriangleAlert","Ban","CircleDashed","StatusBadge","status","meta","entry","Icon"],"mappings":";;;;AAmBA,MAAMA,IAA8B;AAAA,EAClC,SAAS;AAAA,EACT,KAAK;AAAA,EACL,SAAS;AAAA,EACT,OAAO;AAAA,EACP,MAAM;AAAA,EACN,QAAQ;AACV;AASO,SAASC,EAAM,EAAE,MAAAC,IAAO,WAAW,KAAAC,IAAM,IAAO,WAAAC,GAAW,UAAAC,GAAU,GAAGC,KAAqB;AAClG,SACE,gBAAAC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWC;AAAA,QACT;AAAA,QACAR,EAAME,CAAI;AAAA,QACVE;AAAA,MAAA;AAAA,MAED,GAAGE;AAAA,MAEH,UAAA;AAAA,QAAAH,KAAO,gBAAAM,EAAC,QAAA,EAAK,WAAU,mCAAA,CAAmC;AAAA,QAC1DJ;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGP;AAWO,MAAMK,IAAyC;AAAA,EACpD,QAAQ,EAAE,OAAO,UAAU,MAAM,WAAW,MAAMC,EAAA;AAAA,EAClD,SAAS,EAAE,OAAO,WAAW,MAAM,WAAW,MAAMA,EAAA;AAAA,EACpD,SAAS,EAAE,OAAO,WAAW,MAAM,OAAO,MAAMC,GAAS,MAAM,GAAA;AAAA,EAC/D,MAAM,EAAE,OAAO,QAAQ,MAAM,WAAW,MAAMC,EAAA;AAAA,EAC9C,WAAW,EAAE,OAAO,aAAa,MAAM,WAAW,MAAMA,EAAA;AAAA,EACxD,OAAO,EAAE,OAAO,SAAS,MAAM,QAAQ,MAAMC,EAAA;AAAA,EAC7C,QAAQ,EAAE,OAAO,UAAU,MAAM,QAAQ,MAAMA,EAAA;AAAA,EAC/C,WAAW,EAAE,OAAO,aAAa,MAAM,SAAS,MAAMC,EAAA;AAAA,EACtD,UAAU,EAAE,OAAO,YAAY,MAAM,UAAU,MAAMC,EAAA;AACvD;AAaO,SAASC,EAAY,EAAE,QAAAC,GAAQ,MAAAC,GAAM,WAAAf,GAAW,GAAGE,KAA2B;AACnF,QAAMc,IAAoB,EAAE,GAAGV,GAAY,GAAGS,EAAA,EAAOD,CAAM,KAAK,EAAE,OAAOA,GAAQ,MAAM,UAAA,GACjF,EAAE,MAAAG,MAASD;AACjB,2BACGnB,GAAA,EAAM,MAAMmB,EAAM,MAAM,WAAAhB,GAAuB,GAAGE,GAChD,UAAA;AAAA,IAAAe,uBAASA,GAAA,EAAK,WAAWb,EAAGY,EAAM,QAAQ,cAAc,GAAG;AAAA,IAC3DA,EAAM;AAAA,EAAA,GACT;AAEJ;"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { ThemeProvider, resolveTheme, setTheme, toggleTheme, useTheme } from './theme';
|
|
2
|
+
export type { ThemeMode, UseThemeResult } from './theme';
|
|
3
|
+
export { ThemeToggle } from './theme-toggle';
|
|
4
|
+
export type { ThemeToggleProps } from './theme-toggle';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/theme/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACvF,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface ThemeToggleProps {
|
|
2
|
+
/**
|
|
3
|
+
* `icon` — one button, light ⇄ dark.
|
|
4
|
+
* `segmented` — light / system / dark, so "follow the OS" stays reachable.
|
|
5
|
+
*/
|
|
6
|
+
variant?: 'icon' | 'segmented';
|
|
7
|
+
className?: string;
|
|
8
|
+
}
|
|
9
|
+
/** The Sun/Moon button, wired to `useTheme` and persisted. */
|
|
10
|
+
export declare function ThemeToggle({ variant, className }: ThemeToggleProps): import("react").JSX.Element;
|
|
11
|
+
//# sourceMappingURL=theme-toggle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-toggle.d.ts","sourceRoot":"","sources":["../../../src/components/theme/theme-toggle.tsx"],"names":[],"mappings":"AAKA,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,8DAA8D;AAC9D,wBAAgB,WAAW,CAAC,EAAE,OAAgB,EAAE,SAAS,EAAE,EAAE,gBAAgB,+BAkD5E"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { jsx as e } from "react/jsx-runtime";
|
|
2
|
+
import { Sun as a, Monitor as h, Moon as l } from "lucide-react";
|
|
3
|
+
import { cn as o } from "../../lib/utils.js";
|
|
4
|
+
import { useTheme as f } from "./theme.js";
|
|
5
|
+
function y({ variant: m = "icon", className: i }) {
|
|
6
|
+
const { theme: n, isDark: r, setTheme: d, toggle: c } = f();
|
|
7
|
+
if (m === "segmented") {
|
|
8
|
+
const u = [
|
|
9
|
+
["light", a, "Light"],
|
|
10
|
+
["system", h, "System"],
|
|
11
|
+
["dark", l, "Dark"]
|
|
12
|
+
];
|
|
13
|
+
return /* @__PURE__ */ e(
|
|
14
|
+
"div",
|
|
15
|
+
{
|
|
16
|
+
role: "radiogroup",
|
|
17
|
+
"aria-label": "Theme",
|
|
18
|
+
className: o("inline-flex items-center gap-0.5 rounded-lg border border-border p-0.5", i),
|
|
19
|
+
children: u.map(([t, g, s]) => /* @__PURE__ */ e(
|
|
20
|
+
"button",
|
|
21
|
+
{
|
|
22
|
+
type: "button",
|
|
23
|
+
role: "radio",
|
|
24
|
+
"aria-checked": n === t,
|
|
25
|
+
"aria-label": s,
|
|
26
|
+
title: s,
|
|
27
|
+
onClick: () => d(t),
|
|
28
|
+
className: o(
|
|
29
|
+
"rounded-md p-1.5 text-muted-foreground transition-colors hover:text-foreground",
|
|
30
|
+
n === t && "bg-muted text-foreground"
|
|
31
|
+
),
|
|
32
|
+
children: /* @__PURE__ */ e(g, { className: "size-4" })
|
|
33
|
+
},
|
|
34
|
+
t
|
|
35
|
+
))
|
|
36
|
+
}
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
return /* @__PURE__ */ e(
|
|
40
|
+
"button",
|
|
41
|
+
{
|
|
42
|
+
type: "button",
|
|
43
|
+
onClick: c,
|
|
44
|
+
"aria-label": r ? "Switch to light theme" : "Switch to dark theme",
|
|
45
|
+
title: r ? "Light" : "Dark",
|
|
46
|
+
className: o(
|
|
47
|
+
"inline-flex size-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
|
|
48
|
+
i
|
|
49
|
+
),
|
|
50
|
+
children: r ? /* @__PURE__ */ e(l, { className: "size-4" }) : /* @__PURE__ */ e(a, { className: "size-4" })
|
|
51
|
+
}
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
export {
|
|
55
|
+
y as ThemeToggle
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=theme-toggle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-toggle.js","sources":["../../../src/components/theme/theme-toggle.tsx"],"sourcesContent":["import { Monitor, Moon, Sun } from 'lucide-react';\n\nimport { cn } from '../../lib/utils';\nimport { useTheme, type ThemeMode } from './theme';\n\nexport interface ThemeToggleProps {\n /**\n * `icon` — one button, light ⇄ dark.\n * `segmented` — light / system / dark, so \"follow the OS\" stays reachable.\n */\n variant?: 'icon' | 'segmented';\n className?: string;\n}\n\n/** The Sun/Moon button, wired to `useTheme` and persisted. */\nexport function ThemeToggle({ variant = 'icon', className }: ThemeToggleProps) {\n const { theme, isDark, setTheme, toggle } = useTheme();\n\n if (variant === 'segmented') {\n const modes: [ThemeMode, typeof Sun, string][] = [\n ['light', Sun, 'Light'],\n ['system', Monitor, 'System'],\n ['dark', Moon, 'Dark'],\n ];\n return (\n <div\n role=\"radiogroup\"\n aria-label=\"Theme\"\n className={cn('inline-flex items-center gap-0.5 rounded-lg border border-border p-0.5', className)}\n >\n {modes.map(([mode, Icon, label]) => (\n <button\n key={mode}\n type=\"button\"\n role=\"radio\"\n aria-checked={theme === mode}\n aria-label={label}\n title={label}\n onClick={() => setTheme(mode)}\n className={cn(\n 'rounded-md p-1.5 text-muted-foreground transition-colors hover:text-foreground',\n theme === mode && 'bg-muted text-foreground',\n )}\n >\n <Icon className=\"size-4\" />\n </button>\n ))}\n </div>\n );\n }\n\n return (\n <button\n type=\"button\"\n onClick={toggle}\n aria-label={isDark ? 'Switch to light theme' : 'Switch to dark theme'}\n title={isDark ? 'Light' : 'Dark'}\n className={cn(\n 'inline-flex size-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:bg-muted hover:text-foreground',\n className,\n )}\n >\n {isDark ? <Moon className=\"size-4\" /> : <Sun className=\"size-4\" />}\n </button>\n );\n}\n"],"names":["ThemeToggle","variant","className","theme","isDark","setTheme","toggle","useTheme","modes","Sun","Monitor","Moon","jsx","cn","mode","Icon","label"],"mappings":";;;;AAeO,SAASA,EAAY,EAAE,SAAAC,IAAU,QAAQ,WAAAC,KAA+B;AAC7E,QAAM,EAAE,OAAAC,GAAO,QAAAC,GAAQ,UAAAC,GAAU,QAAAC,EAAA,IAAWC,EAAA;AAE5C,MAAIN,MAAY,aAAa;AAC3B,UAAMO,IAA2C;AAAA,MAC/C,CAAC,SAASC,GAAK,OAAO;AAAA,MACtB,CAAC,UAAUC,GAAS,QAAQ;AAAA,MAC5B,CAAC,QAAQC,GAAM,MAAM;AAAA,IAAA;AAEvB,WACE,gBAAAC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,cAAW;AAAA,QACX,WAAWC,EAAG,0EAA0EX,CAAS;AAAA,QAEhG,YAAM,IAAI,CAAC,CAACY,GAAMC,GAAMC,CAAK,MAC5B,gBAAAJ;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC,MAAK;AAAA,YACL,MAAK;AAAA,YACL,gBAAcT,MAAUW;AAAA,YACxB,cAAYE;AAAA,YACZ,OAAOA;AAAA,YACP,SAAS,MAAMX,EAASS,CAAI;AAAA,YAC5B,WAAWD;AAAA,cACT;AAAA,cACAV,MAAUW,KAAQ;AAAA,YAAA;AAAA,YAGpB,UAAA,gBAAAF,EAACG,GAAA,EAAK,WAAU,SAAA,CAAS;AAAA,UAAA;AAAA,UAZpBD;AAAA,QAAA,CAcR;AAAA,MAAA;AAAA,IAAA;AAAA,EAGP;AAEA,SACE,gBAAAF;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,SAASN;AAAA,MACT,cAAYF,IAAS,0BAA0B;AAAA,MAC/C,OAAOA,IAAS,UAAU;AAAA,MAC1B,WAAWS;AAAA,QACT;AAAA,QACAX;AAAA,MAAA;AAAA,MAGD,UAAAE,sBAAUO,GAAA,EAAK,WAAU,UAAS,IAAK,gBAAAC,EAACH,GAAA,EAAI,WAAU,SAAA,CAAS;AAAA,IAAA;AAAA,EAAA;AAGtE;"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export type ThemeMode = 'light' | 'dark' | 'system';
|
|
3
|
+
/** Set the theme from anywhere — a settings page, a keyboard shortcut, a test. */
|
|
4
|
+
export declare function setTheme(next: ThemeMode): void;
|
|
5
|
+
/** Light ⇄ dark. From `system`, flips to the opposite of what is showing. */
|
|
6
|
+
export declare function toggleTheme(): void;
|
|
7
|
+
/** What is actually on screen right now (`system` resolved against the OS). */
|
|
8
|
+
export declare function resolveTheme(): 'light' | 'dark';
|
|
9
|
+
export interface UseThemeResult {
|
|
10
|
+
/** The chosen mode, including `system`. */
|
|
11
|
+
theme: ThemeMode;
|
|
12
|
+
/** The mode in effect — `system` already resolved. */
|
|
13
|
+
resolved: 'light' | 'dark';
|
|
14
|
+
isDark: boolean;
|
|
15
|
+
setTheme: (mode: ThemeMode) => void;
|
|
16
|
+
toggle: () => void;
|
|
17
|
+
}
|
|
18
|
+
/** The dark-mode hook. No provider required. */
|
|
19
|
+
export declare function useTheme(): UseThemeResult;
|
|
20
|
+
/**
|
|
21
|
+
* Optional — only to override the defaults (`localStorage['ui-theme']`,
|
|
22
|
+
* defaulting to the OS preference). Configure before the first paint.
|
|
23
|
+
*/
|
|
24
|
+
export declare function ThemeProvider({ children, storageKey: key, defaultTheme, }: {
|
|
25
|
+
children?: React.ReactNode;
|
|
26
|
+
storageKey?: string;
|
|
27
|
+
defaultTheme?: ThemeMode;
|
|
28
|
+
}): React.JSX.Element;
|
|
29
|
+
//# sourceMappingURL=theme.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../../src/components/theme/theme.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;AAuDpD,kFAAkF;AAClF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,SAAS,QASvC;AAED,6EAA6E;AAC7E,wBAAgB,WAAW,SAE1B;AAED,+EAA+E;AAC/E,wBAAgB,YAAY,IAAI,OAAO,GAAG,MAAM,CAG/C;AAQD,MAAM,WAAW,cAAc;IAC7B,2CAA2C;IAC3C,KAAK,EAAE,SAAS,CAAC;IACjB,sDAAsD;IACtD,QAAQ,EAAE,OAAO,GAAG,MAAM,CAAC;IAC3B,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;IACpC,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,gDAAgD;AAChD,wBAAgB,QAAQ,IAAI,cAAc,CAQzC;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,UAAU,EAAE,GAAgB,EAC5B,YAAuB,GACxB,EAAE;IACD,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,SAAS,CAAC;CAC1B,qBAQA"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { jsx as f, Fragment as h } from "react/jsx-runtime";
|
|
2
|
+
import * as g from "react";
|
|
3
|
+
let s = "ui-theme", o = "system", n = null;
|
|
4
|
+
const c = /* @__PURE__ */ new Set();
|
|
5
|
+
function i() {
|
|
6
|
+
return typeof window < "u" && window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
7
|
+
}
|
|
8
|
+
function a() {
|
|
9
|
+
if (n) return n;
|
|
10
|
+
if (typeof window > "u") return o;
|
|
11
|
+
const e = window.localStorage.getItem(s);
|
|
12
|
+
return n = e === "light" || e === "dark" || e === "system" ? e : o, d(), y(), n;
|
|
13
|
+
}
|
|
14
|
+
function d() {
|
|
15
|
+
if (typeof document > "u" || !n) return;
|
|
16
|
+
const e = n === "dark" || n === "system" && i(), t = document.documentElement;
|
|
17
|
+
t.classList.toggle("dark", e), t.style.colorScheme = e ? "dark" : "light";
|
|
18
|
+
const r = document.querySelector('meta[name="theme-color"]');
|
|
19
|
+
if (r) {
|
|
20
|
+
const m = getComputedStyle(t).getPropertyValue("--background").trim();
|
|
21
|
+
m && (r.content = m);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
let u = !1;
|
|
25
|
+
function y() {
|
|
26
|
+
u || typeof window > "u" || (u = !0, window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", () => {
|
|
27
|
+
n === "system" && (d(), c.forEach((e) => e()));
|
|
28
|
+
}));
|
|
29
|
+
}
|
|
30
|
+
function l(e) {
|
|
31
|
+
n = e;
|
|
32
|
+
try {
|
|
33
|
+
window.localStorage.setItem(s, e);
|
|
34
|
+
} catch {
|
|
35
|
+
}
|
|
36
|
+
d(), c.forEach((t) => t());
|
|
37
|
+
}
|
|
38
|
+
function w() {
|
|
39
|
+
l(k() === "dark" ? "light" : "dark");
|
|
40
|
+
}
|
|
41
|
+
function k() {
|
|
42
|
+
const e = a();
|
|
43
|
+
return e === "system" ? i() ? "dark" : "light" : e;
|
|
44
|
+
}
|
|
45
|
+
function p(e) {
|
|
46
|
+
return a(), c.add(e), () => c.delete(e);
|
|
47
|
+
}
|
|
48
|
+
function S() {
|
|
49
|
+
const e = g.useSyncExternalStore(
|
|
50
|
+
p,
|
|
51
|
+
() => a(),
|
|
52
|
+
() => o
|
|
53
|
+
), t = e === "system" ? i() ? "dark" : "light" : e;
|
|
54
|
+
return { theme: e, resolved: t, isDark: t === "dark", setTheme: l, toggle: w };
|
|
55
|
+
}
|
|
56
|
+
function E({
|
|
57
|
+
children: e,
|
|
58
|
+
storageKey: t = "ui-theme",
|
|
59
|
+
defaultTheme: r = "system"
|
|
60
|
+
}) {
|
|
61
|
+
return (t !== s || r !== o) && (s = t, o = r, n = null), S(), /* @__PURE__ */ f(h, { children: e });
|
|
62
|
+
}
|
|
63
|
+
export {
|
|
64
|
+
E as ThemeProvider,
|
|
65
|
+
k as resolveTheme,
|
|
66
|
+
l as setTheme,
|
|
67
|
+
w as toggleTheme,
|
|
68
|
+
S as useTheme
|
|
69
|
+
};
|
|
70
|
+
//# sourceMappingURL=theme.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.js","sources":["../../../src/components/theme/theme.tsx"],"sourcesContent":["import * as React from 'react';\n\nexport type ThemeMode = 'light' | 'dark' | 'system';\n\n/*\n * A module-level store rather than a context, because the theme is one global\n * fact: `useTheme()` works anywhere with no provider, and `<ThemeProvider>` is\n * only needed to change the storage key or the default. Every subscriber shares\n * one `matchMedia` listener via `useSyncExternalStore`.\n */\n\nlet storageKey = 'ui-theme';\nlet fallback: ThemeMode = 'system';\nlet mode: ThemeMode | null = null;\nconst listeners = new Set<() => void>();\n\nfunction systemDark(): boolean {\n return typeof window !== 'undefined' && window.matchMedia('(prefers-color-scheme: dark)').matches;\n}\n\nfunction init(): ThemeMode {\n if (mode) return mode;\n if (typeof window === 'undefined') return fallback;\n const stored = window.localStorage.getItem(storageKey) as ThemeMode | null;\n mode = stored === 'light' || stored === 'dark' || stored === 'system' ? stored : fallback;\n apply();\n watchSystem();\n return mode;\n}\n\nfunction apply() {\n if (typeof document === 'undefined' || !mode) return;\n const dark = mode === 'dark' || (mode === 'system' && systemDark());\n const root = document.documentElement;\n root.classList.toggle('dark', dark);\n root.style.colorScheme = dark ? 'dark' : 'light';\n // Keep the mobile browser chrome in step with the page, or a dark page keeps\n // a white notch bar.\n const meta = document.querySelector<HTMLMetaElement>('meta[name=\"theme-color\"]');\n if (meta) {\n const bg = getComputedStyle(root).getPropertyValue('--background').trim();\n if (bg) meta.content = bg;\n }\n}\n\nlet watching = false;\nfunction watchSystem() {\n if (watching || typeof window === 'undefined') return;\n watching = true;\n window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {\n if (mode === 'system') {\n apply();\n listeners.forEach((l) => l());\n }\n });\n}\n\n/** Set the theme from anywhere — a settings page, a keyboard shortcut, a test. */\nexport function setTheme(next: ThemeMode) {\n mode = next;\n try {\n window.localStorage.setItem(storageKey, next);\n } catch {\n /* private mode — the theme still applies for this session */\n }\n apply();\n listeners.forEach((l) => l());\n}\n\n/** Light ⇄ dark. From `system`, flips to the opposite of what is showing. */\nexport function toggleTheme() {\n setTheme(resolveTheme() === 'dark' ? 'light' : 'dark');\n}\n\n/** What is actually on screen right now (`system` resolved against the OS). */\nexport function resolveTheme(): 'light' | 'dark' {\n const m = init();\n return m === 'system' ? (systemDark() ? 'dark' : 'light') : m;\n}\n\nfunction subscribe(l: () => void) {\n init();\n listeners.add(l);\n return () => listeners.delete(l);\n}\n\nexport interface UseThemeResult {\n /** The chosen mode, including `system`. */\n theme: ThemeMode;\n /** The mode in effect — `system` already resolved. */\n resolved: 'light' | 'dark';\n isDark: boolean;\n setTheme: (mode: ThemeMode) => void;\n toggle: () => void;\n}\n\n/** The dark-mode hook. No provider required. */\nexport function useTheme(): UseThemeResult {\n const theme = React.useSyncExternalStore(\n subscribe,\n () => init(),\n () => fallback,\n );\n const resolved = theme === 'system' ? (systemDark() ? 'dark' : 'light') : theme;\n return { theme, resolved, isDark: resolved === 'dark', setTheme, toggle: toggleTheme };\n}\n\n/**\n * Optional — only to override the defaults (`localStorage['ui-theme']`,\n * defaulting to the OS preference). Configure before the first paint.\n */\nexport function ThemeProvider({\n children,\n storageKey: key = 'ui-theme',\n defaultTheme = 'system',\n}: {\n children?: React.ReactNode;\n storageKey?: string;\n defaultTheme?: ThemeMode;\n}) {\n if (key !== storageKey || defaultTheme !== fallback) {\n storageKey = key;\n fallback = defaultTheme;\n mode = null; // re-read under the new key\n }\n useTheme(); // mount the subscription so the class lands before paint\n return <>{children}</>;\n}\n"],"names":["storageKey","fallback","mode","listeners","systemDark","init","stored","apply","watchSystem","dark","root","meta","bg","watching","l","setTheme","next","toggleTheme","resolveTheme","m","subscribe","useTheme","theme","React","resolved","ThemeProvider","children","key","defaultTheme"],"mappings":";;AAWA,IAAIA,IAAa,YACbC,IAAsB,UACtBC,IAAyB;AAC7B,MAAMC,wBAAgB,IAAA;AAEtB,SAASC,IAAsB;AAC7B,SAAO,OAAO,SAAW,OAAe,OAAO,WAAW,8BAA8B,EAAE;AAC5F;AAEA,SAASC,IAAkB;AACzB,MAAIH,EAAM,QAAOA;AACjB,MAAI,OAAO,SAAW,IAAa,QAAOD;AAC1C,QAAMK,IAAS,OAAO,aAAa,QAAQN,CAAU;AACrD,SAAAE,IAAOI,MAAW,WAAWA,MAAW,UAAUA,MAAW,WAAWA,IAASL,GACjFM,EAAA,GACAC,EAAA,GACON;AACT;AAEA,SAASK,IAAQ;AACf,MAAI,OAAO,WAAa,OAAe,CAACL,EAAM;AAC9C,QAAMO,IAAOP,MAAS,UAAWA,MAAS,YAAYE,EAAA,GAChDM,IAAO,SAAS;AACtB,EAAAA,EAAK,UAAU,OAAO,QAAQD,CAAI,GAClCC,EAAK,MAAM,cAAcD,IAAO,SAAS;AAGzC,QAAME,IAAO,SAAS,cAA+B,0BAA0B;AAC/E,MAAIA,GAAM;AACR,UAAMC,IAAK,iBAAiBF,CAAI,EAAE,iBAAiB,cAAc,EAAE,KAAA;AACnE,IAAIE,QAAS,UAAUA;AAAA,EACzB;AACF;AAEA,IAAIC,IAAW;AACf,SAASL,IAAc;AACrB,EAAIK,KAAY,OAAO,SAAW,QAClCA,IAAW,IACX,OAAO,WAAW,8BAA8B,EAAE,iBAAiB,UAAU,MAAM;AACjF,IAAIX,MAAS,aACXK,EAAA,GACAJ,EAAU,QAAQ,CAACW,MAAMA,EAAA,CAAG;AAAA,EAEhC,CAAC;AACH;AAGO,SAASC,EAASC,GAAiB;AACxC,EAAAd,IAAOc;AACP,MAAI;AACF,WAAO,aAAa,QAAQhB,GAAYgB,CAAI;AAAA,EAC9C,QAAQ;AAAA,EAER;AACA,EAAAT,EAAA,GACAJ,EAAU,QAAQ,CAACW,MAAMA,EAAA,CAAG;AAC9B;AAGO,SAASG,IAAc;AAC5B,EAAAF,EAASG,EAAA,MAAmB,SAAS,UAAU,MAAM;AACvD;AAGO,SAASA,IAAiC;AAC/C,QAAMC,IAAId,EAAA;AACV,SAAOc,MAAM,WAAYf,EAAA,IAAe,SAAS,UAAWe;AAC9D;AAEA,SAASC,EAAUN,GAAe;AAChC,SAAAT,EAAA,GACAF,EAAU,IAAIW,CAAC,GACR,MAAMX,EAAU,OAAOW,CAAC;AACjC;AAaO,SAASO,IAA2B;AACzC,QAAMC,IAAQC,EAAM;AAAA,IAClBH;AAAA,IACA,MAAMf,EAAA;AAAA,IACN,MAAMJ;AAAA,EAAA,GAEFuB,IAAWF,MAAU,WAAYlB,EAAA,IAAe,SAAS,UAAWkB;AAC1E,SAAO,EAAE,OAAAA,GAAO,UAAAE,GAAU,QAAQA,MAAa,QAAQ,UAAAT,GAAU,QAAQE,EAAA;AAC3E;AAMO,SAASQ,EAAc;AAAA,EAC5B,UAAAC;AAAA,EACA,YAAYC,IAAM;AAAA,EAClB,cAAAC,IAAe;AACjB,GAIG;AACD,UAAID,MAAQ3B,KAAc4B,MAAiB3B,OACzCD,IAAa2B,GACb1B,IAAW2B,GACX1B,IAAO,OAETmB,EAAA,0BACU,UAAAK,GAAS;AACrB;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/toast/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC3D,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export type ToastType = 'success' | 'error' | 'warning' | 'info' | 'loading';
|
|
3
|
+
export type ToastPosition = 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';
|
|
4
|
+
export interface ToastAction {
|
|
5
|
+
label: string;
|
|
6
|
+
onClick?: () => void;
|
|
7
|
+
/** Renders the action as a link instead of a button. */
|
|
8
|
+
href?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface ToastOptions {
|
|
11
|
+
/** Bold first line above the message. */
|
|
12
|
+
title?: string;
|
|
13
|
+
type?: ToastType;
|
|
14
|
+
/** ms before it self-dismisses. `0` (or a `loading` toast) pins it open. */
|
|
15
|
+
duration?: number;
|
|
16
|
+
action?: ToastAction;
|
|
17
|
+
}
|
|
18
|
+
export interface Toast extends ToastOptions {
|
|
19
|
+
id: string;
|
|
20
|
+
message: React.ReactNode;
|
|
21
|
+
type: ToastType;
|
|
22
|
+
}
|
|
23
|
+
/** Callable: `toast('Saved')`, plus one shorthand per type. */
|
|
24
|
+
export interface ToastFn {
|
|
25
|
+
(message: React.ReactNode, options?: ToastOptions): string;
|
|
26
|
+
success: (message: React.ReactNode, options?: ToastOptions) => string;
|
|
27
|
+
error: (message: React.ReactNode, options?: ToastOptions) => string;
|
|
28
|
+
warning: (message: React.ReactNode, options?: ToastOptions) => string;
|
|
29
|
+
info: (message: React.ReactNode, options?: ToastOptions) => string;
|
|
30
|
+
/** Pinned open with a spinner — settle it with `toast.update(id, …)`. */
|
|
31
|
+
loading: (message: React.ReactNode, options?: ToastOptions) => string;
|
|
32
|
+
/** Turn a pending toast into its outcome, in place. */
|
|
33
|
+
update: (id: string, message: React.ReactNode, options?: ToastOptions) => void;
|
|
34
|
+
dismiss: (id?: string) => void;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* The toast queue.
|
|
38
|
+
*
|
|
39
|
+
* ```tsx
|
|
40
|
+
* <ToastProvider> <App /> </ToastProvider>
|
|
41
|
+
*
|
|
42
|
+
* const toast = useToast()
|
|
43
|
+
* toast.success('Deployed', { action: { label: 'Open', href: url } })
|
|
44
|
+
* const id = toast.loading('Uploading…')
|
|
45
|
+
* toast.update(id, 'Uploaded', { type: 'success' })
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export declare function ToastProvider({ children, position, duration, max, }: {
|
|
49
|
+
children: React.ReactNode;
|
|
50
|
+
position?: ToastPosition;
|
|
51
|
+
/** Default lifetime. Errors get 1.75× this, since they carry more to read. */
|
|
52
|
+
duration?: number;
|
|
53
|
+
/** Oldest toasts beyond this are dropped, so a burst can't cover the page. */
|
|
54
|
+
max?: number;
|
|
55
|
+
}): React.JSX.Element;
|
|
56
|
+
/** The toast function. Throws outside a `<ToastProvider>` — a silent no-op toast is worse. */
|
|
57
|
+
export declare function useToast(): ToastFn;
|
|
58
|
+
/** The rendered stack. `ToastProvider` mounts one; you rarely need it directly. */
|
|
59
|
+
export declare function Toaster({ toasts, position, onDismiss, }: {
|
|
60
|
+
toasts: Toast[];
|
|
61
|
+
position?: ToastPosition;
|
|
62
|
+
onDismiss: (id: string) => void;
|
|
63
|
+
}): React.ReactPortal | null;
|
|
64
|
+
//# sourceMappingURL=toast.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toast.d.ts","sourceRoot":"","sources":["../../../src/components/toast/toast.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC;AAE7E,MAAM,MAAM,aAAa,GACrB,UAAU,GACV,YAAY,GACZ,WAAW,GACX,aAAa,GACb,eAAe,GACf,cAAc,CAAC;AAEnB,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,wDAAwD;IACxD,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,yCAAyC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,KAAM,SAAQ,YAAY;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,+DAA+D;AAC/D,MAAM,WAAW,OAAO;IACtB,CAAC,OAAO,EAAE,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,MAAM,CAAC;IAC3D,OAAO,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,YAAY,KAAK,MAAM,CAAC;IACtE,KAAK,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,YAAY,KAAK,MAAM,CAAC;IACpE,OAAO,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,YAAY,KAAK,MAAM,CAAC;IACtE,IAAI,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,YAAY,KAAK,MAAM,CAAC;IACnE,yEAAyE;IACzE,OAAO,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,YAAY,KAAK,MAAM,CAAC;IACtE,uDAAuD;IACvD,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,YAAY,KAAK,IAAI,CAAC;IAC/E,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAID;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,QAAyB,EACzB,QAAe,EACf,GAAO,GACR,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,qBA0EA;AAED,8FAA8F;AAC9F,wBAAgB,QAAQ,IAAI,OAAO,CAIlC;AAmBD,mFAAmF;AACnF,wBAAgB,OAAO,CAAC,EACtB,MAAM,EACN,QAAyB,EACzB,SAAS,GACV,EAAE;IACD,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC,4BAoEA"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { jsxs as v, jsx as i } from "react/jsx-runtime";
|
|
2
|
+
import * as n from "react";
|
|
3
|
+
import { createPortal as k } from "react-dom";
|
|
4
|
+
import { Loader2 as N, Info as E, AlertTriangle as I, XCircle as P, CheckCircle2 as M, X as z } from "lucide-react";
|
|
5
|
+
import { cn as y } from "../../lib/utils.js";
|
|
6
|
+
const w = n.createContext(null);
|
|
7
|
+
function S({
|
|
8
|
+
children: u,
|
|
9
|
+
position: x = "bottom-right",
|
|
10
|
+
duration: d = 4e3,
|
|
11
|
+
max: p = 4
|
|
12
|
+
}) {
|
|
13
|
+
const [r, m] = n.useState([]), s = n.useRef(/* @__PURE__ */ new Map()), f = n.useRef(0), a = n.useCallback((e) => {
|
|
14
|
+
if (e == null) {
|
|
15
|
+
s.current.forEach(clearTimeout), s.current.clear(), m([]);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
clearTimeout(s.current.get(e)), s.current.delete(e), m((t) => t.filter((o) => o.id !== e));
|
|
19
|
+
}, []), g = n.useCallback(
|
|
20
|
+
(e) => {
|
|
21
|
+
clearTimeout(s.current.get(e.id));
|
|
22
|
+
const t = e.duration ?? (e.type === "loading" ? 0 : e.type === "error" ? d * 1.75 : d);
|
|
23
|
+
t > 0 && s.current.set(e.id, setTimeout(() => a(e.id), t));
|
|
24
|
+
},
|
|
25
|
+
[a, d]
|
|
26
|
+
), c = n.useCallback(
|
|
27
|
+
(e, { type: t = "info", ...o } = {}) => {
|
|
28
|
+
const b = `t${f.current += 1}`, l = { id: b, message: e, type: t, ...o };
|
|
29
|
+
return m((h) => [...h, l].slice(-p)), g(l), b;
|
|
30
|
+
},
|
|
31
|
+
[g, p]
|
|
32
|
+
), T = n.useCallback(
|
|
33
|
+
(e, t, o = {}) => {
|
|
34
|
+
m(
|
|
35
|
+
(b) => b.map((l) => {
|
|
36
|
+
if (l.id !== e) return l;
|
|
37
|
+
const h = { ...l, message: t, ...o, type: o.type ?? l.type };
|
|
38
|
+
return g(h), h;
|
|
39
|
+
})
|
|
40
|
+
);
|
|
41
|
+
},
|
|
42
|
+
[g]
|
|
43
|
+
), C = n.useMemo(() => {
|
|
44
|
+
const e = ((t, o) => c(t, o));
|
|
45
|
+
return e.success = (t, o) => c(t, { ...o, type: "success" }), e.error = (t, o) => c(t, { ...o, type: "error" }), e.warning = (t, o) => c(t, { ...o, type: "warning" }), e.info = (t, o) => c(t, { ...o, type: "info" }), e.loading = (t, o) => c(t, { ...o, type: "loading" }), e.update = T, e.dismiss = a, e;
|
|
46
|
+
}, [c, T, a]);
|
|
47
|
+
return n.useEffect(() => {
|
|
48
|
+
const e = s.current;
|
|
49
|
+
return () => e.forEach(clearTimeout);
|
|
50
|
+
}, []), /* @__PURE__ */ v(w.Provider, { value: C, children: [
|
|
51
|
+
u,
|
|
52
|
+
/* @__PURE__ */ i(j, { toasts: r, position: x, onDismiss: a })
|
|
53
|
+
] });
|
|
54
|
+
}
|
|
55
|
+
function W() {
|
|
56
|
+
const u = n.useContext(w);
|
|
57
|
+
if (!u) throw new Error("useToast must be used inside a <ToastProvider>");
|
|
58
|
+
return u;
|
|
59
|
+
}
|
|
60
|
+
const A = {
|
|
61
|
+
success: { Icon: M, tone: "text-emerald-500" },
|
|
62
|
+
error: { Icon: P, tone: "text-destructive" },
|
|
63
|
+
warning: { Icon: I, tone: "text-amber-500" },
|
|
64
|
+
info: { Icon: E, tone: "text-sky-500" },
|
|
65
|
+
loading: { Icon: N, tone: "text-muted-foreground" }
|
|
66
|
+
}, R = {
|
|
67
|
+
"top-left": "top-0 left-0 items-start",
|
|
68
|
+
"top-center": "top-0 left-1/2 -translate-x-1/2 items-center",
|
|
69
|
+
"top-right": "top-0 right-0 items-end",
|
|
70
|
+
"bottom-left": "bottom-0 left-0 items-start",
|
|
71
|
+
"bottom-center": "bottom-0 left-1/2 -translate-x-1/2 items-center",
|
|
72
|
+
"bottom-right": "bottom-0 right-0 items-end"
|
|
73
|
+
};
|
|
74
|
+
function j({
|
|
75
|
+
toasts: u,
|
|
76
|
+
position: x = "bottom-right",
|
|
77
|
+
onDismiss: d
|
|
78
|
+
}) {
|
|
79
|
+
if (typeof document > "u") return null;
|
|
80
|
+
const p = x.startsWith("top");
|
|
81
|
+
return k(
|
|
82
|
+
/* @__PURE__ */ i(
|
|
83
|
+
"div",
|
|
84
|
+
{
|
|
85
|
+
className: y(
|
|
86
|
+
"pointer-events-none fixed z-[100] flex w-full max-w-sm flex-col gap-2 p-4",
|
|
87
|
+
p ? "flex-col" : "flex-col-reverse",
|
|
88
|
+
R[x]
|
|
89
|
+
),
|
|
90
|
+
role: "region",
|
|
91
|
+
"aria-label": "Notifications",
|
|
92
|
+
children: u.map((r) => {
|
|
93
|
+
const { Icon: m, tone: s } = A[r.type];
|
|
94
|
+
return /* @__PURE__ */ v(
|
|
95
|
+
"div",
|
|
96
|
+
{
|
|
97
|
+
role: r.type === "error" ? "alert" : "status",
|
|
98
|
+
"aria-live": r.type === "error" ? "assertive" : "polite",
|
|
99
|
+
className: y(
|
|
100
|
+
"ds-toast pointer-events-auto flex w-full items-start gap-3 rounded-xl border border-border bg-popover p-3 pr-2 text-popover-foreground shadow-lg",
|
|
101
|
+
p ? "ds-toast--top" : "ds-toast--bottom"
|
|
102
|
+
),
|
|
103
|
+
children: [
|
|
104
|
+
/* @__PURE__ */ i(m, { className: y("mt-0.5 size-4 shrink-0", s, r.type === "loading" && "animate-spin") }),
|
|
105
|
+
/* @__PURE__ */ v("div", { className: "min-w-0 flex-1", children: [
|
|
106
|
+
r.title && /* @__PURE__ */ i("p", { className: "text-sm font-medium", children: r.title }),
|
|
107
|
+
/* @__PURE__ */ i("div", { className: "text-sm text-muted-foreground [overflow-wrap:anywhere]", children: r.message }),
|
|
108
|
+
r.action && (r.action.href ? /* @__PURE__ */ i(
|
|
109
|
+
"a",
|
|
110
|
+
{
|
|
111
|
+
href: r.action.href,
|
|
112
|
+
target: "_blank",
|
|
113
|
+
rel: "noreferrer",
|
|
114
|
+
className: "mt-1.5 inline-block text-xs font-medium text-foreground underline underline-offset-2",
|
|
115
|
+
children: r.action.label
|
|
116
|
+
}
|
|
117
|
+
) : /* @__PURE__ */ i(
|
|
118
|
+
"button",
|
|
119
|
+
{
|
|
120
|
+
type: "button",
|
|
121
|
+
onClick: () => {
|
|
122
|
+
var f, a;
|
|
123
|
+
(a = (f = r.action) == null ? void 0 : f.onClick) == null || a.call(f), d(r.id);
|
|
124
|
+
},
|
|
125
|
+
className: "mt-1.5 text-xs font-medium text-foreground underline underline-offset-2",
|
|
126
|
+
children: r.action.label
|
|
127
|
+
}
|
|
128
|
+
))
|
|
129
|
+
] }),
|
|
130
|
+
/* @__PURE__ */ i(
|
|
131
|
+
"button",
|
|
132
|
+
{
|
|
133
|
+
type: "button",
|
|
134
|
+
onClick: () => d(r.id),
|
|
135
|
+
"aria-label": "Dismiss",
|
|
136
|
+
className: "rounded-md p-1 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
|
|
137
|
+
children: /* @__PURE__ */ i(z, { className: "size-3.5" })
|
|
138
|
+
}
|
|
139
|
+
)
|
|
140
|
+
]
|
|
141
|
+
},
|
|
142
|
+
r.id
|
|
143
|
+
);
|
|
144
|
+
})
|
|
145
|
+
}
|
|
146
|
+
),
|
|
147
|
+
document.body
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
export {
|
|
151
|
+
S as ToastProvider,
|
|
152
|
+
j as Toaster,
|
|
153
|
+
W as useToast
|
|
154
|
+
};
|
|
155
|
+
//# sourceMappingURL=toast.js.map
|