xiod-ui 1.0.0
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/LICENSE +73 -0
- package/README.md +167 -0
- package/dist/components/accordion.d.ts +9 -0
- package/dist/components/accordion.js +46 -0
- package/dist/components/agent-steps.d.ts +47 -0
- package/dist/components/agent-steps.js +223 -0
- package/dist/components/alert-dialog.d.ts +21 -0
- package/dist/components/alert-dialog.js +74 -0
- package/dist/components/alert.d.ts +12 -0
- package/dist/components/alert.js +45 -0
- package/dist/components/aspect-ratio.d.ts +9 -0
- package/dist/components/aspect-ratio.js +22 -0
- package/dist/components/autocomplete.d.ts +35 -0
- package/dist/components/autocomplete.js +160 -0
- package/dist/components/avatar.d.ts +17 -0
- package/dist/components/avatar.js +65 -0
- package/dist/components/badge.d.ts +15 -0
- package/dist/components/badge.js +46 -0
- package/dist/components/breadcrumb.d.ts +12 -0
- package/dist/components/breadcrumb.js +75 -0
- package/dist/components/button-group.d.ts +14 -0
- package/dist/components/button-group.js +45 -0
- package/dist/components/button-split.d.ts +19 -0
- package/dist/components/button-split.js +73 -0
- package/dist/components/button.d.ts +15 -0
- package/dist/components/button.js +54 -0
- package/dist/components/calendar.d.ts +63 -0
- package/dist/components/calendar.js +425 -0
- package/dist/components/card.d.ts +17 -0
- package/dist/components/card.js +139 -0
- package/dist/components/carousel.d.ts +59 -0
- package/dist/components/carousel.js +503 -0
- package/dist/components/checkbox.d.ts +16 -0
- package/dist/components/checkbox.js +86 -0
- package/dist/components/circular-progress.d.ts +28 -0
- package/dist/components/circular-progress.js +127 -0
- package/dist/components/collapsible.d.ts +8 -0
- package/dist/components/collapsible.js +27 -0
- package/dist/components/color-picker.d.ts +159 -0
- package/dist/components/color-picker.js +1589 -0
- package/dist/components/combobox.d.ts +46 -0
- package/dist/components/combobox.js +237 -0
- package/dist/components/command.d.ts +22 -0
- package/dist/components/command.js +129 -0
- package/dist/components/context-menu.d.ts +38 -0
- package/dist/components/context-menu.js +164 -0
- package/dist/components/copy-to-clipboard.d.ts +32 -0
- package/dist/components/copy-to-clipboard.js +83 -0
- package/dist/components/corner-badge.d.ts +22 -0
- package/dist/components/corner-badge.js +84 -0
- package/dist/components/dashboard-grid.d.ts +83 -0
- package/dist/components/dashboard-grid.js +486 -0
- package/dist/components/date-picker.d.ts +29 -0
- package/dist/components/date-picker.js +261 -0
- package/dist/components/dialog.d.ts +26 -0
- package/dist/components/dialog.js +97 -0
- package/dist/components/dot-matrix.d.ts +32 -0
- package/dist/components/dot-matrix.js +707 -0
- package/dist/components/draggable.d.ts +42 -0
- package/dist/components/draggable.js +346 -0
- package/dist/components/drawer.d.ts +66 -0
- package/dist/components/drawer.js +304 -0
- package/dist/components/empty.d.ts +14 -0
- package/dist/components/empty.js +75 -0
- package/dist/components/field.d.ts +12 -0
- package/dist/components/field.js +44 -0
- package/dist/components/fieldset.d.ts +7 -0
- package/dist/components/fieldset.js +21 -0
- package/dist/components/file-upload.d.ts +61 -0
- package/dist/components/file-upload.js +482 -0
- package/dist/components/form.d.ts +6 -0
- package/dist/components/form.js +14 -0
- package/dist/components/frame.d.ts +10 -0
- package/dist/components/frame.js +47 -0
- package/dist/components/gauge.d.ts +27 -0
- package/dist/components/gauge.js +74 -0
- package/dist/components/grid.d.ts +26 -0
- package/dist/components/grid.js +204 -0
- package/dist/components/group.d.ts +19 -0
- package/dist/components/group.js +45 -0
- package/dist/components/input-group.d.ts +15 -0
- package/dist/components/input-group.js +61 -0
- package/dist/components/input-otp.d.ts +24 -0
- package/dist/components/input-otp.js +50 -0
- package/dist/components/input-payment.d.ts +131 -0
- package/dist/components/input-payment.js +1140 -0
- package/dist/components/input-phone.d.ts +70 -0
- package/dist/components/input-phone.js +657 -0
- package/dist/components/input-sensitive.d.ts +12 -0
- package/dist/components/input-sensitive.js +169 -0
- package/dist/components/input.d.ts +13 -0
- package/dist/components/input.js +26 -0
- package/dist/components/kbd.d.ts +6 -0
- package/dist/components/kbd.js +19 -0
- package/dist/components/kinetic-click.d.ts +48 -0
- package/dist/components/kinetic-click.js +1184 -0
- package/dist/components/label.d.ts +6 -0
- package/dist/components/label.js +18 -0
- package/dist/components/list-box.d.ts +20 -0
- package/dist/components/list-box.js +148 -0
- package/dist/components/loader.d.ts +13 -0
- package/dist/components/loader.js +430 -0
- package/dist/components/marker.d.ts +15 -0
- package/dist/components/marker.js +59 -0
- package/dist/components/menu.d.ts +42 -0
- package/dist/components/menu.js +186 -0
- package/dist/components/menubar.d.ts +40 -0
- package/dist/components/menubar.js +107 -0
- package/dist/components/message.d.ts +33 -0
- package/dist/components/message.js +112 -0
- package/dist/components/meter.d.ts +10 -0
- package/dist/components/meter.js +42 -0
- package/dist/components/morphic-toast.d.ts +61 -0
- package/dist/components/morphic-toast.js +916 -0
- package/dist/components/navigation-menu.d.ts +26 -0
- package/dist/components/navigation-menu.js +116 -0
- package/dist/components/number-field.d.ts +15 -0
- package/dist/components/number-field.js +86 -0
- package/dist/components/option-picker.d.ts +18 -0
- package/dist/components/option-picker.js +89 -0
- package/dist/components/orb.d.ts +38 -0
- package/dist/components/orb.js +1413 -0
- package/dist/components/pagination.d.ts +25 -0
- package/dist/components/pagination.js +147 -0
- package/dist/components/popover.d.ts +22 -0
- package/dist/components/popover.js +79 -0
- package/dist/components/preview-card.d.ts +16 -0
- package/dist/components/preview-card.js +60 -0
- package/dist/components/progress.d.ts +21 -0
- package/dist/components/progress.js +139 -0
- package/dist/components/radio.d.ts +16 -0
- package/dist/components/radio.js +68 -0
- package/dist/components/resizable.d.ts +58 -0
- package/dist/components/resizable.js +964 -0
- package/dist/components/ruler-picker.d.ts +27 -0
- package/dist/components/ruler-picker.js +253 -0
- package/dist/components/scroll-area.d.ts +13 -0
- package/dist/components/scroll-area.js +34 -0
- package/dist/components/scroll-bar.d.ts +13 -0
- package/dist/components/scroll-bar.js +47 -0
- package/dist/components/select.d.ts +29 -0
- package/dist/components/select.js +140 -0
- package/dist/components/separator.d.ts +6 -0
- package/dist/components/separator.js +15 -0
- package/dist/components/sidebar.d.ts +65 -0
- package/dist/components/sidebar.js +408 -0
- package/dist/components/skeleton.d.ts +5 -0
- package/dist/components/skeleton.js +12 -0
- package/dist/components/slider.d.ts +12 -0
- package/dist/components/slider.js +96 -0
- package/dist/components/sortable.d.ts +44 -0
- package/dist/components/sortable.js +327 -0
- package/dist/components/switch.d.ts +15 -0
- package/dist/components/switch.js +63 -0
- package/dist/components/table.d.ts +12 -0
- package/dist/components/table.js +65 -0
- package/dist/components/tabs.d.ts +12 -0
- package/dist/components/tabs.js +39 -0
- package/dist/components/text.d.ts +14 -0
- package/dist/components/text.js +69 -0
- package/dist/components/textarea.d.ts +9 -0
- package/dist/components/textarea.js +20 -0
- package/dist/components/theme-provider.d.ts +52 -0
- package/dist/components/theme-provider.js +148 -0
- package/dist/components/timeline.d.ts +34 -0
- package/dist/components/timeline.js +147 -0
- package/dist/components/toast.d.ts +17 -0
- package/dist/components/toast.js +161 -0
- package/dist/components/toggle-group.d.ts +14 -0
- package/dist/components/toggle-group.js +53 -0
- package/dist/components/toggle.d.ts +11 -0
- package/dist/components/toggle.js +36 -0
- package/dist/components/toolbar.d.ts +11 -0
- package/dist/components/toolbar.js +49 -0
- package/dist/components/tooltip.d.ts +17 -0
- package/dist/components/tooltip.js +56 -0
- package/dist/components/waveform.d.ts +61 -0
- package/dist/components/waveform.js +500 -0
- package/dist/components/wheel-picker.d.ts +44 -0
- package/dist/components/wheel-picker.js +771 -0
- package/dist/hooks/use-copy-to-clipboard.d.ts +9 -0
- package/dist/hooks/use-copy-to-clipboard.js +36 -0
- package/dist/hooks/use-media-query.d.ts +21 -0
- package/dist/hooks/use-media-query.js +58 -0
- package/dist/styles.css +202 -0
- package/dist/themes/afterglow.css +89 -0
- package/dist/themes/afterglow.scoped.css +90 -0
- package/dist/themes/blacklight.css +89 -0
- package/dist/themes/blacklight.scoped.css +90 -0
- package/dist/themes/cathode.css +89 -0
- package/dist/themes/cathode.scoped.css +90 -0
- package/dist/themes/cel.css +89 -0
- package/dist/themes/cel.scoped.css +90 -0
- package/dist/themes/cinder.css +89 -0
- package/dist/themes/cinder.scoped.css +90 -0
- package/dist/themes/clay.css +89 -0
- package/dist/themes/clay.scoped.css +90 -0
- package/dist/themes/cobalt.css +89 -0
- package/dist/themes/cobalt.scoped.css +90 -0
- package/dist/themes/crimson.css +89 -0
- package/dist/themes/crimson.scoped.css +90 -0
- package/dist/themes/ion.css +89 -0
- package/dist/themes/ion.scoped.css +90 -0
- package/dist/themes/iris.css +89 -0
- package/dist/themes/iris.scoped.css +90 -0
- package/dist/themes/lagoon.css +89 -0
- package/dist/themes/lagoon.scoped.css +90 -0
- package/dist/themes/mochi.css +89 -0
- package/dist/themes/mochi.scoped.css +90 -0
- package/dist/themes/riso.css +89 -0
- package/dist/themes/riso.scoped.css +90 -0
- package/dist/themes/roast.css +89 -0
- package/dist/themes/roast.scoped.css +90 -0
- package/dist/themes/sage.css +89 -0
- package/dist/themes/sage.scoped.css +90 -0
- package/dist/themes/sepia.css +89 -0
- package/dist/themes/sepia.scoped.css +90 -0
- package/dist/themes/sorbet.css +89 -0
- package/dist/themes/sorbet.scoped.css +90 -0
- package/dist/themes/taffy.css +89 -0
- package/dist/themes/taffy.scoped.css +90 -0
- package/dist/themes/toxin.css +89 -0
- package/dist/themes/toxin.scoped.css +90 -0
- package/package.json +140 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import * as React$1 from "react";
|
|
2
|
+
//#region src/components/theme-provider.d.ts
|
|
3
|
+
export type ThemeMode = "light" | "dark" | "system";
|
|
4
|
+
export type ResolvedTheme = "light" | "dark";
|
|
5
|
+
export interface ThemeContextValue {
|
|
6
|
+
/** The selected mode, which may be `"system"`. */
|
|
7
|
+
theme: ThemeMode;
|
|
8
|
+
/** The mode actually applied to the document — never `"system"`. */
|
|
9
|
+
resolvedTheme: ResolvedTheme;
|
|
10
|
+
setTheme: (theme: ThemeMode) => void;
|
|
11
|
+
/**
|
|
12
|
+
* The active palette, or `undefined` when none is set and the base tokens
|
|
13
|
+
* from `xiod-ui/styles` apply.
|
|
14
|
+
*/
|
|
15
|
+
palette: string | undefined;
|
|
16
|
+
/** Pass `undefined` to clear the palette and fall back to the base tokens. */
|
|
17
|
+
setPalette: (palette: string | undefined) => void;
|
|
18
|
+
}
|
|
19
|
+
export interface ThemeProviderProps {
|
|
20
|
+
children: React$1.ReactNode;
|
|
21
|
+
/** Mode to use before anything is read from storage. */
|
|
22
|
+
defaultTheme?: ThemeMode;
|
|
23
|
+
/** Follow `prefers-color-scheme` when the mode is `"system"`. */
|
|
24
|
+
enableSystemTheme?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* How the theme is written to `<html>`. `"class"` toggles the `light`/`dark`
|
|
27
|
+
* classes, which is what XiodUI's `dark` variant keys off. Any other value is
|
|
28
|
+
* set as an attribute (e.g. `"data-theme"`).
|
|
29
|
+
*/
|
|
30
|
+
attribute?: string;
|
|
31
|
+
/** localStorage key used to remember the choice. */
|
|
32
|
+
storageKey?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Palette to apply before anything is read from storage. Leave unset to ship
|
|
35
|
+
* a single palette the CSS way — `@import "xiod-ui/themes/<name>"` overrides
|
|
36
|
+
* the base tokens directly and needs no attribute on `<html>` at all. This
|
|
37
|
+
* prop is for apps that let their own users switch palettes at runtime, which
|
|
38
|
+
* requires the scoped stylesheets (`xiod-ui/themes/<name>/scoped`).
|
|
39
|
+
*/
|
|
40
|
+
defaultPalette?: string;
|
|
41
|
+
/**
|
|
42
|
+
* Attribute used to write the palette. Must differ from `attribute`, or the
|
|
43
|
+
* two axes overwrite each other on the same element.
|
|
44
|
+
*/
|
|
45
|
+
paletteAttribute?: string;
|
|
46
|
+
/** localStorage key used to remember the palette. */
|
|
47
|
+
paletteStorageKey?: string;
|
|
48
|
+
}
|
|
49
|
+
declare function ThemeProvider({ children, defaultTheme, enableSystemTheme, attribute, storageKey, defaultPalette, paletteAttribute, paletteStorageKey }: ThemeProviderProps): React$1.ReactElement;
|
|
50
|
+
declare function useTheme(): ThemeContextValue;
|
|
51
|
+
//#endregion
|
|
52
|
+
export { ThemeProvider, useTheme };
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as React$1 from "react";
|
|
4
|
+
//#region src/components/theme-provider.tsx
|
|
5
|
+
const ThemeContext = React$1.createContext(void 0);
|
|
6
|
+
const useIsomorphicLayoutEffect = typeof window === "undefined" ? React$1.useEffect : React$1.useLayoutEffect;
|
|
7
|
+
function isThemeMode(theme) {
|
|
8
|
+
return theme === "light" || theme === "dark" || theme === "system";
|
|
9
|
+
}
|
|
10
|
+
function getResolvedTheme(theme, enableSystemTheme) {
|
|
11
|
+
if (theme === "system") {
|
|
12
|
+
if (!enableSystemTheme) return "light";
|
|
13
|
+
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
14
|
+
}
|
|
15
|
+
return theme;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Suppress transitions for one frame while the theme swaps, so every
|
|
19
|
+
* transitioned property doesn't animate from the old palette to the new one.
|
|
20
|
+
*/
|
|
21
|
+
function disableThemeTransitions() {
|
|
22
|
+
if (typeof document === "undefined") return () => {};
|
|
23
|
+
const style = document.createElement("style");
|
|
24
|
+
style.dataset.themeTransitionGuard = "true";
|
|
25
|
+
style.appendChild(document.createTextNode("*,:before,:after{transition:none!important;transition-delay:0s!important;}"));
|
|
26
|
+
document.head.appendChild(style);
|
|
27
|
+
document.documentElement.getBoundingClientRect();
|
|
28
|
+
return () => {
|
|
29
|
+
window.requestAnimationFrame(() => {
|
|
30
|
+
window.requestAnimationFrame(() => {
|
|
31
|
+
style.remove();
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function applyTheme(theme, attribute, disableTransitions = false) {
|
|
37
|
+
const removeTransitionGuard = disableTransitions ? disableThemeTransitions() : void 0;
|
|
38
|
+
const root = document.documentElement;
|
|
39
|
+
if (attribute === "class") {
|
|
40
|
+
root.classList.remove("light", "dark");
|
|
41
|
+
root.classList.add(theme);
|
|
42
|
+
} else root.setAttribute(attribute, theme);
|
|
43
|
+
root.style.colorScheme = theme;
|
|
44
|
+
removeTransitionGuard?.();
|
|
45
|
+
}
|
|
46
|
+
function applyPalette(palette, attribute, disableTransitions = false) {
|
|
47
|
+
const removeTransitionGuard = disableTransitions ? disableThemeTransitions() : void 0;
|
|
48
|
+
const root = document.documentElement;
|
|
49
|
+
if (palette) root.setAttribute(attribute, palette);
|
|
50
|
+
else root.removeAttribute(attribute);
|
|
51
|
+
removeTransitionGuard?.();
|
|
52
|
+
}
|
|
53
|
+
function ThemeProvider({ children, defaultTheme = "system", enableSystemTheme = true, attribute = "class", storageKey = "theme", defaultPalette, paletteAttribute = "data-palette", paletteStorageKey = "palette" }) {
|
|
54
|
+
const [theme, setThemeState] = React$1.useState(defaultTheme);
|
|
55
|
+
const [resolvedTheme, setResolvedTheme] = React$1.useState("light");
|
|
56
|
+
const [palette, setPaletteState] = React$1.useState(defaultPalette);
|
|
57
|
+
const [mounted, setMounted] = React$1.useState(false);
|
|
58
|
+
if (process.env.NODE_ENV !== "production" && attribute === paletteAttribute) console.warn(`ThemeProvider: \`attribute\` and \`paletteAttribute\` are both "${attribute}". The light/dark mode and the palette would overwrite each other on the same attribute — give one of them a different name.`);
|
|
59
|
+
const setTheme = React$1.useCallback((newTheme) => {
|
|
60
|
+
const newResolvedTheme = getResolvedTheme(newTheme, enableSystemTheme);
|
|
61
|
+
applyTheme(newResolvedTheme, attribute, true);
|
|
62
|
+
setThemeState(newTheme);
|
|
63
|
+
setResolvedTheme(newResolvedTheme);
|
|
64
|
+
try {
|
|
65
|
+
localStorage.setItem(storageKey, newTheme);
|
|
66
|
+
} catch {}
|
|
67
|
+
}, [
|
|
68
|
+
attribute,
|
|
69
|
+
enableSystemTheme,
|
|
70
|
+
storageKey
|
|
71
|
+
]);
|
|
72
|
+
const setPalette = React$1.useCallback((newPalette) => {
|
|
73
|
+
applyPalette(newPalette, paletteAttribute, true);
|
|
74
|
+
setPaletteState(newPalette);
|
|
75
|
+
try {
|
|
76
|
+
if (newPalette) localStorage.setItem(paletteStorageKey, newPalette);
|
|
77
|
+
else localStorage.removeItem(paletteStorageKey);
|
|
78
|
+
} catch {}
|
|
79
|
+
}, [paletteAttribute, paletteStorageKey]);
|
|
80
|
+
React$1.useEffect(() => {
|
|
81
|
+
setMounted(true);
|
|
82
|
+
try {
|
|
83
|
+
const savedTheme = localStorage.getItem(storageKey);
|
|
84
|
+
if (isThemeMode(savedTheme)) setThemeState(savedTheme);
|
|
85
|
+
const savedPalette = localStorage.getItem(paletteStorageKey);
|
|
86
|
+
if (savedPalette) setPaletteState(savedPalette);
|
|
87
|
+
} catch {}
|
|
88
|
+
}, [storageKey, paletteStorageKey]);
|
|
89
|
+
useIsomorphicLayoutEffect(() => {
|
|
90
|
+
if (!mounted) return;
|
|
91
|
+
const newResolvedTheme = getResolvedTheme(theme, enableSystemTheme);
|
|
92
|
+
applyTheme(newResolvedTheme, attribute);
|
|
93
|
+
setResolvedTheme(newResolvedTheme);
|
|
94
|
+
}, [
|
|
95
|
+
theme,
|
|
96
|
+
mounted,
|
|
97
|
+
attribute,
|
|
98
|
+
enableSystemTheme
|
|
99
|
+
]);
|
|
100
|
+
useIsomorphicLayoutEffect(() => {
|
|
101
|
+
if (!mounted || palette === void 0) return;
|
|
102
|
+
applyPalette(palette, paletteAttribute);
|
|
103
|
+
}, [
|
|
104
|
+
palette,
|
|
105
|
+
mounted,
|
|
106
|
+
paletteAttribute
|
|
107
|
+
]);
|
|
108
|
+
React$1.useEffect(() => {
|
|
109
|
+
if (!mounted || theme !== "system" || !enableSystemTheme) return;
|
|
110
|
+
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
111
|
+
const handleChange = () => {
|
|
112
|
+
const newTheme = mediaQuery.matches ? "dark" : "light";
|
|
113
|
+
setResolvedTheme(newTheme);
|
|
114
|
+
applyTheme(newTheme, attribute);
|
|
115
|
+
};
|
|
116
|
+
mediaQuery.addEventListener("change", handleChange);
|
|
117
|
+
return () => mediaQuery.removeEventListener("change", handleChange);
|
|
118
|
+
}, [
|
|
119
|
+
theme,
|
|
120
|
+
mounted,
|
|
121
|
+
attribute,
|
|
122
|
+
enableSystemTheme
|
|
123
|
+
]);
|
|
124
|
+
const value = React$1.useMemo(() => ({
|
|
125
|
+
theme,
|
|
126
|
+
resolvedTheme,
|
|
127
|
+
setTheme,
|
|
128
|
+
palette,
|
|
129
|
+
setPalette
|
|
130
|
+
}), [
|
|
131
|
+
theme,
|
|
132
|
+
resolvedTheme,
|
|
133
|
+
setTheme,
|
|
134
|
+
palette,
|
|
135
|
+
setPalette
|
|
136
|
+
]);
|
|
137
|
+
return /* @__PURE__ */ jsx(ThemeContext.Provider, {
|
|
138
|
+
value,
|
|
139
|
+
children
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
function useTheme() {
|
|
143
|
+
const context = React$1.useContext(ThemeContext);
|
|
144
|
+
if (!context) throw new Error("useTheme must be used within a ThemeProvider");
|
|
145
|
+
return context;
|
|
146
|
+
}
|
|
147
|
+
//#endregion
|
|
148
|
+
export { ThemeProvider, useTheme };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { VariantProps } from "class-variance-authority";
|
|
2
|
+
import * as React$1 from "react";
|
|
3
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
4
|
+
//#region src/components/timeline.d.ts
|
|
5
|
+
export interface TimelineContextValue {
|
|
6
|
+
activeStep?: number;
|
|
7
|
+
setActiveStep: (step: number) => void;
|
|
8
|
+
}
|
|
9
|
+
export declare const TimelineContext: React$1.Context<TimelineContextValue | undefined>;
|
|
10
|
+
export declare function useTimeline(): TimelineContextValue | undefined;
|
|
11
|
+
export interface TimelineProps extends useRender.ComponentProps<"div"> {
|
|
12
|
+
defaultValue?: number;
|
|
13
|
+
value?: number;
|
|
14
|
+
onValueChange?: (value: number) => void;
|
|
15
|
+
orientation?: "horizontal" | "vertical";
|
|
16
|
+
}
|
|
17
|
+
export declare function Timeline({ defaultValue, value, onValueChange, orientation, className, render, ...props }: TimelineProps): React$1.ReactElement;
|
|
18
|
+
export interface TimelineItemProps extends useRender.ComponentProps<"div"> {
|
|
19
|
+
step?: number;
|
|
20
|
+
status?: "completed" | "active" | "pending";
|
|
21
|
+
}
|
|
22
|
+
export declare function TimelineItem({ step, status: statusProp, className, render, ...props }: TimelineItemProps): React$1.ReactElement;
|
|
23
|
+
export declare function TimelineHeader({ className, render, ...props }: useRender.ComponentProps<"div">): React$1.ReactElement;
|
|
24
|
+
export declare function TimelineTitle({ className, render, ...props }: useRender.ComponentProps<"h3">): React$1.ReactElement;
|
|
25
|
+
export declare function TimelineDate({ className, render, ...props }: useRender.ComponentProps<"time">): React$1.ReactElement;
|
|
26
|
+
export declare function TimelineContent({ className, render, ...props }: useRender.ComponentProps<"div">): React$1.ReactElement;
|
|
27
|
+
export declare const timelineIndicatorVariants: (props?: ({
|
|
28
|
+
variant?: "default" | "solid" | null | undefined;
|
|
29
|
+
size?: "sm" | "lg" | "default" | null | undefined;
|
|
30
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
31
|
+
export interface TimelineIndicatorProps extends useRender.ComponentProps<"div">, VariantProps<typeof timelineIndicatorVariants> {}
|
|
32
|
+
export declare function TimelineIndicator({ className, variant, size, render, ...props }: TimelineIndicatorProps): React$1.ReactElement;
|
|
33
|
+
export declare function TimelineSeparator({ className, render, ...props }: useRender.ComponentProps<"div">): React$1.ReactElement;
|
|
34
|
+
//#endregion
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "cn";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
import { cva } from "class-variance-authority";
|
|
5
|
+
import * as React$1 from "react";
|
|
6
|
+
import { mergeProps } from "@base-ui/react/merge-props";
|
|
7
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
8
|
+
//#region src/components/timeline.tsx
|
|
9
|
+
const TimelineContext = React$1.createContext(void 0);
|
|
10
|
+
function useTimeline() {
|
|
11
|
+
return React$1.useContext(TimelineContext);
|
|
12
|
+
}
|
|
13
|
+
function Timeline({ defaultValue, value, onValueChange, orientation = "vertical", className, render, ...props }) {
|
|
14
|
+
const [internalStep, setInternalStep] = React$1.useState(defaultValue);
|
|
15
|
+
const activeStep = value !== void 0 ? value : internalStep;
|
|
16
|
+
const setActiveStep = React$1.useCallback((step) => {
|
|
17
|
+
if (value === void 0) setInternalStep(step);
|
|
18
|
+
onValueChange?.(step);
|
|
19
|
+
}, [value, onValueChange]);
|
|
20
|
+
const contextValue = React$1.useMemo(() => ({
|
|
21
|
+
activeStep,
|
|
22
|
+
setActiveStep
|
|
23
|
+
}), [activeStep, setActiveStep]);
|
|
24
|
+
const defaultProps = {
|
|
25
|
+
className: cn("group/timeline flex w-full", orientation === "horizontal" ? "flex-row" : "flex-col", className),
|
|
26
|
+
"data-orientation": orientation,
|
|
27
|
+
"data-slot": "timeline"
|
|
28
|
+
};
|
|
29
|
+
return /* @__PURE__ */ jsx(TimelineContext.Provider, {
|
|
30
|
+
value: contextValue,
|
|
31
|
+
children: useRender({
|
|
32
|
+
defaultTagName: "div",
|
|
33
|
+
render,
|
|
34
|
+
props: mergeProps(defaultProps, props)
|
|
35
|
+
})
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
function TimelineItem({ step, status: statusProp, className, render, ...props }) {
|
|
39
|
+
const context = useTimeline();
|
|
40
|
+
let status = statusProp;
|
|
41
|
+
if (!status && step !== void 0 && context?.activeStep !== void 0) {
|
|
42
|
+
if (step < context.activeStep) status = "completed";
|
|
43
|
+
else if (step === context.activeStep) status = "active";
|
|
44
|
+
else status = "pending";
|
|
45
|
+
}
|
|
46
|
+
const resolvedStatus = status || "pending";
|
|
47
|
+
const defaultProps = {
|
|
48
|
+
className: cn("group/timeline-item relative flex flex-1 flex-col gap-1", "group-data-[orientation=vertical]/timeline:ms-8", "group-data-[orientation=vertical]/timeline:not-last:pb-8", "group-data-[orientation=horizontal]/timeline:mt-8", "group-data-[orientation=horizontal]/timeline:not-last:pe-8", className),
|
|
49
|
+
"data-status": resolvedStatus,
|
|
50
|
+
"data-slot": "timeline-item"
|
|
51
|
+
};
|
|
52
|
+
return useRender({
|
|
53
|
+
defaultTagName: "div",
|
|
54
|
+
render,
|
|
55
|
+
props: mergeProps(defaultProps, props)
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
function TimelineHeader({ className, render, ...props }) {
|
|
59
|
+
const defaultProps = {
|
|
60
|
+
className: cn("flex flex-col sm:flex-row sm:items-center sm:justify-between gap-1", className),
|
|
61
|
+
"data-slot": "timeline-header"
|
|
62
|
+
};
|
|
63
|
+
return useRender({
|
|
64
|
+
defaultTagName: "div",
|
|
65
|
+
render,
|
|
66
|
+
props: mergeProps(defaultProps, props)
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
function TimelineTitle({ className, render, ...props }) {
|
|
70
|
+
const defaultProps = {
|
|
71
|
+
className: cn("font-medium text-sm text-foreground", className),
|
|
72
|
+
"data-slot": "timeline-title"
|
|
73
|
+
};
|
|
74
|
+
return useRender({
|
|
75
|
+
defaultTagName: "h3",
|
|
76
|
+
render,
|
|
77
|
+
props: mergeProps(defaultProps, props)
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
function TimelineDate({ className, render, ...props }) {
|
|
81
|
+
const defaultProps = {
|
|
82
|
+
className: cn("text-xs text-muted-foreground tabular-nums", className),
|
|
83
|
+
"data-slot": "timeline-date"
|
|
84
|
+
};
|
|
85
|
+
return useRender({
|
|
86
|
+
defaultTagName: "time",
|
|
87
|
+
render,
|
|
88
|
+
props: mergeProps(defaultProps, props)
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
function TimelineContent({ className, render, ...props }) {
|
|
92
|
+
const defaultProps = {
|
|
93
|
+
className: cn("text-sm text-muted-foreground", className),
|
|
94
|
+
"data-slot": "timeline-content"
|
|
95
|
+
};
|
|
96
|
+
return useRender({
|
|
97
|
+
defaultTagName: "div",
|
|
98
|
+
render,
|
|
99
|
+
props: mergeProps(defaultProps, props)
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
const timelineIndicatorVariants = cva("absolute flex items-center justify-center rounded-full transition-colors duration-200 before:pointer-events-none before:absolute before:inset-0 before:rounded-full before:shadow-[0_1px_--theme(--color-black/4%)] dark:before:shadow-[0_-1px_--theme(--color-white/6%)]", {
|
|
103
|
+
variants: {
|
|
104
|
+
variant: {
|
|
105
|
+
default: "border border-border bg-background shadow-xs/5 not-dark:bg-clip-padding group-data-[status=completed]/timeline-item:border-primary group-data-[status=active]/timeline-item:border-primary",
|
|
106
|
+
solid: "border border-transparent bg-border shadow-xs/5 group-data-[status=completed]/timeline-item:bg-primary group-data-[status=active]/timeline-item:bg-primary"
|
|
107
|
+
},
|
|
108
|
+
size: {
|
|
109
|
+
sm: "size-3",
|
|
110
|
+
default: "size-4",
|
|
111
|
+
lg: "size-6"
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
defaultVariants: {
|
|
115
|
+
variant: "default",
|
|
116
|
+
size: "default"
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
function TimelineIndicator({ className, variant, size, render, ...props }) {
|
|
120
|
+
const defaultProps = {
|
|
121
|
+
"aria-hidden": true,
|
|
122
|
+
className: cn(timelineIndicatorVariants({
|
|
123
|
+
variant,
|
|
124
|
+
size
|
|
125
|
+
}), "group-data-[orientation=vertical]/timeline:-left-8 group-data-[orientation=vertical]/timeline:-translate-x-1/2", "group-data-[orientation=vertical]/timeline:top-1.5", "group-data-[orientation=horizontal]/timeline:-top-8 group-data-[orientation=horizontal]/timeline:-translate-y-1/2", "group-data-[orientation=horizontal]/timeline:left-0", className),
|
|
126
|
+
"data-slot": "timeline-indicator"
|
|
127
|
+
};
|
|
128
|
+
return useRender({
|
|
129
|
+
defaultTagName: "div",
|
|
130
|
+
render,
|
|
131
|
+
props: mergeProps(defaultProps, props)
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
function TimelineSeparator({ className, render, ...props }) {
|
|
135
|
+
const defaultProps = {
|
|
136
|
+
"aria-hidden": true,
|
|
137
|
+
className: cn("absolute bg-border transition-colors duration-200 group-last/timeline-item:hidden", "group-data-[status=completed]/timeline-item:bg-primary", "group-data-[orientation=vertical]/timeline:-left-8 group-data-[orientation=vertical]/timeline:-translate-x-1/2 group-data-[orientation=vertical]/timeline:w-px", "group-data-[orientation=vertical]/timeline:top-7 group-data-[orientation=vertical]/timeline:-bottom-1.5", "group-data-[orientation=horizontal]/timeline:-top-8 group-data-[orientation=horizontal]/timeline:-translate-y-1/2 group-data-[orientation=horizontal]/timeline:h-px", "group-data-[orientation=horizontal]/timeline:left-6 group-data-[orientation=horizontal]/timeline:-right-1.5", className),
|
|
138
|
+
"data-slot": "timeline-separator"
|
|
139
|
+
};
|
|
140
|
+
return useRender({
|
|
141
|
+
defaultTagName: "div",
|
|
142
|
+
render,
|
|
143
|
+
props: mergeProps(defaultProps, props)
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
//#endregion
|
|
147
|
+
export { Timeline, TimelineContent, TimelineContext, TimelineDate, TimelineHeader, TimelineIndicator, TimelineItem, TimelineSeparator, TimelineTitle, timelineIndicatorVariants, useTimeline };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as React$1 from "react";
|
|
2
|
+
import { Toast } from "@base-ui/react/toast";
|
|
3
|
+
//#region src/components/toast.d.ts
|
|
4
|
+
declare const toastManager: import("@base-ui/react").ToastManager<any>;
|
|
5
|
+
declare const anchoredToastManager: import("@base-ui/react").ToastManager<any>;
|
|
6
|
+
type ToastPosition = "top-left" | "top-center" | "top-right" | "bottom-left" | "bottom-center" | "bottom-right";
|
|
7
|
+
interface ToastProviderProps extends Toast.Provider.Props {
|
|
8
|
+
position?: ToastPosition;
|
|
9
|
+
closeButton?: boolean;
|
|
10
|
+
}
|
|
11
|
+
declare function ToastProvider({ children, position, closeButton, ...props }: ToastProviderProps): React$1.JSX.Element;
|
|
12
|
+
interface AnchoredToastProviderProps extends Toast.Provider.Props {
|
|
13
|
+
closeButton?: boolean;
|
|
14
|
+
}
|
|
15
|
+
declare function AnchoredToastProvider({ children, closeButton, ...props }: AnchoredToastProviderProps): React$1.JSX.Element;
|
|
16
|
+
//#endregion
|
|
17
|
+
export { AnchoredToastProvider, type AnchoredToastProviderProps, type ToastPosition, ToastProvider, type ToastProviderProps, anchoredToastManager, toastManager };
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { buttonVariants } from "./button.js";
|
|
3
|
+
import { cn } from "cn";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
import { Cancel } from "xiod-icons/icons/Cancel";
|
|
6
|
+
import { Toast } from "@base-ui/react/toast";
|
|
7
|
+
import { Alert } from "xiod-icons/icons/Alert";
|
|
8
|
+
import { AlertCircle } from "xiod-icons/icons/AlertCircle";
|
|
9
|
+
import { CheckmarkCircle } from "xiod-icons/icons/CheckmarkCircle";
|
|
10
|
+
import { InformationCircle } from "xiod-icons/icons/InformationCircle";
|
|
11
|
+
import { LoadingSpinner } from "xiod-icons/icons/LoadingSpinner";
|
|
12
|
+
//#region src/components/toast.tsx
|
|
13
|
+
const toastManager = Toast.createToastManager();
|
|
14
|
+
const anchoredToastManager = Toast.createToastManager();
|
|
15
|
+
const TOAST_ICONS = {
|
|
16
|
+
error: AlertCircle,
|
|
17
|
+
info: InformationCircle,
|
|
18
|
+
loading: LoadingSpinner,
|
|
19
|
+
success: CheckmarkCircle,
|
|
20
|
+
warning: Alert
|
|
21
|
+
};
|
|
22
|
+
function ToastProvider({ children, position = "bottom-right", closeButton = false, ...props }) {
|
|
23
|
+
return /* @__PURE__ */ jsxs(Toast.Provider, {
|
|
24
|
+
toastManager,
|
|
25
|
+
...props,
|
|
26
|
+
children: [children, /* @__PURE__ */ jsx(Toasts, {
|
|
27
|
+
position,
|
|
28
|
+
closeButton
|
|
29
|
+
})]
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
function Toasts({ position, closeButton = false }) {
|
|
33
|
+
const { toasts } = Toast.useToastManager();
|
|
34
|
+
const isTop = position.startsWith("top");
|
|
35
|
+
return /* @__PURE__ */ jsx(Toast.Portal, {
|
|
36
|
+
"data-slot": "toast-portal",
|
|
37
|
+
children: /* @__PURE__ */ jsx(Toast.Viewport, {
|
|
38
|
+
className: cn("fixed z-50 mx-auto flex w-[calc(100%-var(--toast-inset)*2)] max-w-90 [--toast-inset:--spacing(4)] sm:[--toast-inset:--spacing(8)]", "data-[position*=top]:top-(--toast-inset)", "data-[position*=bottom]:bottom-(--toast-inset)", "data-[position*=left]:left-(--toast-inset)", "data-[position*=right]:right-(--toast-inset)", "data-[position*=center]:-translate-x-1/2 data-[position*=center]:left-1/2"),
|
|
39
|
+
"data-position": position,
|
|
40
|
+
"data-slot": "toast-viewport",
|
|
41
|
+
children: toasts.map((toast) => {
|
|
42
|
+
const Icon = toast.type ? TOAST_ICONS[toast.type] : null;
|
|
43
|
+
const showCloseButton = toast.closeButton ?? toast.data?.closeButton ?? closeButton;
|
|
44
|
+
return /* @__PURE__ */ jsx(Toast.Root, {
|
|
45
|
+
className: cn("absolute z-[calc(9999-var(--toast-index))] h-(--toast-calc-height) w-full select-none rounded-lg border bg-popover not-dark:bg-clip-padding text-popover-foreground shadow-lg/5 [transition:transform_.5s_cubic-bezier(.22,1,.36,1),opacity_.5s,height_.15s] before:pointer-events-none before:absolute before:inset-0 before:rounded-[calc(var(--radius-lg)-1px)] before:shadow-[0_1px_--theme(--color-black/4%)] dark:before:shadow-[0_-1px_--theme(--color-white/6%)]", "data-[position*=right]:right-0 data-[position*=right]:left-auto", "data-[position*=left]:right-auto data-[position*=left]:left-0", "data-[position*=center]:right-0 data-[position*=center]:left-0", "data-[position*=top]:top-0 data-[position*=top]:bottom-auto data-[position*=top]:origin-top", "data-[position*=bottom]:top-auto data-[position*=bottom]:bottom-0 data-[position*=bottom]:origin-bottom", "after:absolute after:left-0 after:h-[calc(var(--toast-gap)+1px)] after:w-full", "data-[position*=top]:after:top-full", "data-[position*=bottom]:after:bottom-full", "[--toast-calc-height:var(--toast-frontmost-height,var(--toast-height))] [--toast-gap:--spacing(3)] [--toast-peek:--spacing(3)] [--toast-scale:calc(max(0,1-(var(--toast-index)*.1)))] [--toast-shrink:calc(1-var(--toast-scale))]", "data-[position*=top]:[--toast-calc-offset-y:calc(var(--toast-offset-y)+var(--toast-index)*var(--toast-gap)+var(--toast-swipe-movement-y))]", "data-[position*=bottom]:[--toast-calc-offset-y:calc(var(--toast-offset-y)*-1+var(--toast-index)*var(--toast-gap)*-1+var(--toast-swipe-movement-y))]", "data-[position*=top]:transform-[translateX(var(--toast-swipe-movement-x))_translateY(calc(var(--toast-swipe-movement-y)+(var(--toast-index)*var(--toast-peek))+(var(--toast-shrink)*var(--toast-calc-height))))_scale(var(--toast-scale))]", "data-[position*=bottom]:transform-[translateX(var(--toast-swipe-movement-x))_translateY(calc(var(--toast-swipe-movement-y)-(var(--toast-index)*var(--toast-peek))-(var(--toast-shrink)*var(--toast-calc-height))))_scale(var(--toast-scale))]", "data-limited:opacity-0", "data-expanded:h-(--toast-height)", "data-position:data-expanded:transform-[translateX(var(--toast-swipe-movement-x))_translateY(var(--toast-calc-offset-y))]", "data-[position*=top]:data-starting-style:transform-[translateY(calc(-100%-var(--toast-inset)))]", "data-[position*=bottom]:data-starting-style:transform-[translateY(calc(100%+var(--toast-inset)))]", "data-ending-style:opacity-0", "data-ending-style:not-data-limited:not-data-swipe-direction:transform-[translateY(calc(100%+var(--toast-inset)))]", "data-ending-style:data-[swipe-direction=left]:transform-[translateX(calc(var(--toast-swipe-movement-x)-100%-var(--toast-inset)))_translateY(var(--toast-calc-offset-y))]", "data-ending-style:data-[swipe-direction=right]:transform-[translateX(calc(var(--toast-swipe-movement-x)+100%+var(--toast-inset)))_translateY(var(--toast-calc-offset-y))]", "data-ending-style:data-[swipe-direction=up]:transform-[translateY(calc(var(--toast-swipe-movement-y)-100%-var(--toast-inset)))]", "data-ending-style:data-[swipe-direction=down]:transform-[translateY(calc(var(--toast-swipe-movement-y)+100%+var(--toast-inset)))]", "data-expanded:data-ending-style:data-[swipe-direction=left]:transform-[translateX(calc(var(--toast-swipe-movement-x)-100%-var(--toast-inset)))_translateY(var(--toast-calc-offset-y))]", "data-expanded:data-ending-style:data-[swipe-direction=right]:transform-[translateX(calc(var(--toast-swipe-movement-x)+100%+var(--toast-inset)))_translateY(var(--toast-calc-offset-y))]", "data-expanded:data-ending-style:data-[swipe-direction=up]:transform-[translateY(calc(var(--toast-swipe-movement-y)-100%-var(--toast-inset)))]", "data-expanded:data-ending-style:data-[swipe-direction=down]:transform-[translateY(calc(var(--toast-swipe-movement-y)+100%+var(--toast-inset)))]"),
|
|
46
|
+
"data-position": position,
|
|
47
|
+
swipeDirection: position.includes("center") ? [isTop ? "up" : "down"] : position.includes("left") ? ["left", isTop ? "up" : "down"] : ["right", isTop ? "up" : "down"],
|
|
48
|
+
toast,
|
|
49
|
+
children: /* @__PURE__ */ jsxs(Toast.Content, {
|
|
50
|
+
className: "pointer-events-auto flex items-center justify-between gap-1.5 overflow-hidden px-3.5 py-3 text-sm transition-opacity duration-250 data-behind:not-data-expanded:pointer-events-none data-behind:opacity-0 data-expanded:opacity-100",
|
|
51
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
52
|
+
className: "flex gap-2",
|
|
53
|
+
children: [Icon && /* @__PURE__ */ jsx("div", {
|
|
54
|
+
className: "[&>svg]:h-lh [&>svg]:w-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
55
|
+
"data-slot": "toast-icon",
|
|
56
|
+
children: /* @__PURE__ */ jsx(Icon, { className: "in-data-[type=loading]:animate-spin in-data-[type=error]:text-destructive in-data-[type=info]:text-info in-data-[type=success]:text-success in-data-[type=warning]:text-warning in-data-[type=loading]:opacity-80" })
|
|
57
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
58
|
+
className: "flex flex-col gap-0.5",
|
|
59
|
+
children: [/* @__PURE__ */ jsx(Toast.Title, {
|
|
60
|
+
className: "font-medium",
|
|
61
|
+
"data-slot": "toast-title"
|
|
62
|
+
}), /* @__PURE__ */ jsx(Toast.Description, {
|
|
63
|
+
className: "text-muted-foreground",
|
|
64
|
+
"data-slot": "toast-description"
|
|
65
|
+
})]
|
|
66
|
+
})]
|
|
67
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
68
|
+
className: "flex items-center gap-1.5 shrink-0",
|
|
69
|
+
children: [toast.actionProps && /* @__PURE__ */ jsx(Toast.Action, {
|
|
70
|
+
className: buttonVariants({ size: "xs" }),
|
|
71
|
+
"data-slot": "toast-action",
|
|
72
|
+
children: toast.actionProps.children
|
|
73
|
+
}), showCloseButton && /* @__PURE__ */ jsx(Toast.Close, {
|
|
74
|
+
"aria-label": "Close",
|
|
75
|
+
className: cn(buttonVariants({
|
|
76
|
+
size: "icon-xs",
|
|
77
|
+
variant: "ghost"
|
|
78
|
+
}), "text-muted-foreground hover:text-foreground select-none"),
|
|
79
|
+
children: /* @__PURE__ */ jsx(Cancel, { className: "size-4 sm:size-3.5" })
|
|
80
|
+
})]
|
|
81
|
+
})]
|
|
82
|
+
})
|
|
83
|
+
}, toast.id);
|
|
84
|
+
})
|
|
85
|
+
})
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
function AnchoredToastProvider({ children, closeButton = false, ...props }) {
|
|
89
|
+
return /* @__PURE__ */ jsxs(Toast.Provider, {
|
|
90
|
+
toastManager: anchoredToastManager,
|
|
91
|
+
...props,
|
|
92
|
+
children: [children, /* @__PURE__ */ jsx(AnchoredToasts, { closeButton })]
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
function AnchoredToasts({ closeButton = false }) {
|
|
96
|
+
const { toasts } = Toast.useToastManager();
|
|
97
|
+
return /* @__PURE__ */ jsx(Toast.Portal, {
|
|
98
|
+
"data-slot": "toast-portal-anchored",
|
|
99
|
+
children: /* @__PURE__ */ jsx(Toast.Viewport, {
|
|
100
|
+
className: "outline-none",
|
|
101
|
+
"data-slot": "toast-viewport-anchored",
|
|
102
|
+
children: toasts.map((toast) => {
|
|
103
|
+
const Icon = toast.type ? TOAST_ICONS[toast.type] : null;
|
|
104
|
+
const tooltipStyle = toast.data?.tooltipStyle ?? false;
|
|
105
|
+
const positionerProps = toast.positionerProps;
|
|
106
|
+
if (!positionerProps?.anchor) return null;
|
|
107
|
+
const showCloseButton = toast.closeButton ?? toast.data?.closeButton ?? closeButton;
|
|
108
|
+
return /* @__PURE__ */ jsx(Toast.Positioner, {
|
|
109
|
+
className: "z-50 max-w-[min(--spacing(64),var(--available-width))]",
|
|
110
|
+
"data-slot": "toast-positioner",
|
|
111
|
+
sideOffset: positionerProps.sideOffset ?? 4,
|
|
112
|
+
toast,
|
|
113
|
+
children: /* @__PURE__ */ jsx(Toast.Root, {
|
|
114
|
+
className: cn("relative text-balance border bg-popover not-dark:bg-clip-padding text-popover-foreground text-xs transition-[scale,opacity] before:pointer-events-none before:absolute before:inset-0 before:shadow-[0_1px_--theme(--color-black/4%)] data-ending-style:scale-98 data-starting-style:scale-98 data-ending-style:opacity-0 data-starting-style:opacity-0 dark:before:shadow-[0_-1px_--theme(--color-white/6%)]", tooltipStyle ? "rounded-md shadow-md/5 before:rounded-[calc(var(--radius-md)-1px)]" : "rounded-lg shadow-lg/5 before:rounded-[calc(var(--radius-lg)-1px)]"),
|
|
115
|
+
"data-slot": "toast-popup",
|
|
116
|
+
toast,
|
|
117
|
+
children: tooltipStyle ? /* @__PURE__ */ jsx(Toast.Content, {
|
|
118
|
+
className: "pointer-events-auto px-2 py-1",
|
|
119
|
+
children: /* @__PURE__ */ jsx(Toast.Title, { "data-slot": "toast-title" })
|
|
120
|
+
}) : /* @__PURE__ */ jsxs(Toast.Content, {
|
|
121
|
+
className: "pointer-events-auto flex items-center justify-between gap-1.5 overflow-hidden px-3.5 py-3 text-sm",
|
|
122
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
123
|
+
className: "flex gap-2",
|
|
124
|
+
children: [Icon && /* @__PURE__ */ jsx("div", {
|
|
125
|
+
className: "[&>svg]:h-lh [&>svg]:w-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
126
|
+
"data-slot": "toast-icon",
|
|
127
|
+
children: /* @__PURE__ */ jsx(Icon, { className: "in-data-[type=loading]:animate-spin in-data-[type=error]:text-destructive in-data-[type=info]:text-info in-data-[type=success]:text-success in-data-[type=warning]:text-warning in-data-[type=loading]:opacity-80" })
|
|
128
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
129
|
+
className: "flex flex-col gap-0.5",
|
|
130
|
+
children: [/* @__PURE__ */ jsx(Toast.Title, {
|
|
131
|
+
className: "font-medium",
|
|
132
|
+
"data-slot": "toast-title"
|
|
133
|
+
}), /* @__PURE__ */ jsx(Toast.Description, {
|
|
134
|
+
className: "text-muted-foreground",
|
|
135
|
+
"data-slot": "toast-description"
|
|
136
|
+
})]
|
|
137
|
+
})]
|
|
138
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
139
|
+
className: "flex items-center gap-1.5 shrink-0",
|
|
140
|
+
children: [toast.actionProps && /* @__PURE__ */ jsx(Toast.Action, {
|
|
141
|
+
className: buttonVariants({ size: "xs" }),
|
|
142
|
+
"data-slot": "toast-action",
|
|
143
|
+
children: toast.actionProps.children
|
|
144
|
+
}), showCloseButton && /* @__PURE__ */ jsx(Toast.Close, {
|
|
145
|
+
"aria-label": "Close",
|
|
146
|
+
className: cn(buttonVariants({
|
|
147
|
+
size: "icon-xs",
|
|
148
|
+
variant: "ghost"
|
|
149
|
+
}), "text-muted-foreground hover:text-foreground select-none"),
|
|
150
|
+
children: /* @__PURE__ */ jsx(Cancel, { className: "size-4 sm:size-3.5" })
|
|
151
|
+
})]
|
|
152
|
+
})]
|
|
153
|
+
})
|
|
154
|
+
})
|
|
155
|
+
}, toast.id);
|
|
156
|
+
})
|
|
157
|
+
})
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
//#endregion
|
|
161
|
+
export { AnchoredToastProvider, ToastProvider, anchoredToastManager, toastManager };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Separator } from "./separator.js";
|
|
2
|
+
import { toggleVariants } from "./toggle.js";
|
|
3
|
+
import { VariantProps } from "class-variance-authority";
|
|
4
|
+
import * as React$1 from "react";
|
|
5
|
+
import { ToggleGroup as ToggleGroup$1 } from "@base-ui/react/toggle-group";
|
|
6
|
+
import { Toggle as Toggle$1 } from "@base-ui/react/toggle";
|
|
7
|
+
//#region src/components/toggle-group.d.ts
|
|
8
|
+
declare function ToggleGroup({ className, variant, size, orientation, children, ...props }: ToggleGroup$1.Props & VariantProps<typeof toggleVariants>): React$1.JSX.Element;
|
|
9
|
+
declare function Toggle({ className, children, variant, size, ...props }: Toggle$1.Props & VariantProps<typeof toggleVariants>): React$1.JSX.Element;
|
|
10
|
+
declare function ToggleGroupSeparator({ className, orientation, ...props }: {
|
|
11
|
+
className?: string;
|
|
12
|
+
} & React$1.ComponentProps<typeof Separator>): React$1.JSX.Element;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { ToggleGroup, Toggle as ToggleGroupItem, ToggleGroupSeparator };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Separator } from "./separator.js";
|
|
3
|
+
import { Toggle as Toggle$1 } from "./toggle.js";
|
|
4
|
+
import { cn } from "cn";
|
|
5
|
+
import { jsx } from "react/jsx-runtime";
|
|
6
|
+
import * as React$1 from "react";
|
|
7
|
+
import { ToggleGroup as ToggleGroup$1 } from "@base-ui/react/toggle-group";
|
|
8
|
+
//#region src/components/toggle-group.tsx
|
|
9
|
+
const ToggleGroupContext = React$1.createContext({
|
|
10
|
+
size: "default",
|
|
11
|
+
variant: "default"
|
|
12
|
+
});
|
|
13
|
+
function ToggleGroup({ className, variant = "default", size = "default", orientation = "horizontal", children, ...props }) {
|
|
14
|
+
const contextValue = React$1.useMemo(() => ({
|
|
15
|
+
size,
|
|
16
|
+
variant
|
|
17
|
+
}), [size, variant]);
|
|
18
|
+
return /* @__PURE__ */ jsx(ToggleGroup$1, {
|
|
19
|
+
className: cn("flex w-fit *:focus-visible:z-10 dark:*:[[data-slot=separator]:has(+[data-slot=toggle]:hover)]:before:bg-input/64 dark:*:[[data-slot=separator]:has(+[data-slot=toggle][data-pressed])]:before:bg-input dark:*:[[data-slot=toggle]:hover+[data-slot=separator]]:before:bg-input/64 dark:*:[[data-slot=toggle][data-pressed]+[data-slot=separator]]:before:bg-input", orientation === "horizontal" ? "*:pointer-coarse:after:min-w-auto" : "*:pointer-coarse:after:min-h-auto", variant === "default" ? "gap-0.5" : orientation === "horizontal" ? "*:not-first:not-data-[slot=separator]:before:inset-s-[-0.5px] *:not-last:not-data-[slot=separator]:before:inset-e-[-0.5px] *:not-first:rounded-s-none *:not-last:rounded-e-none *:not-first:border-s-0 *:not-last:border-e-0 *:not-first:before:rounded-s-none *:not-last:before:rounded-e-none" : "*:not-first:not-data-[slot=separator]:before:top-[-0.5px] *:not-last:not-data-[slot=separator]:before:bottom-[-0.5px] flex-col *:not-first:rounded-t-none *:not-last:rounded-b-none *:not-first:border-t-0 *:not-last:border-b-0 *:not-first:before:rounded-t-none *:not-last:before:rounded-b-none *:data-[slot=toggle]:not-last:before:hidden dark:*:last:before:hidden dark:*:first:before:block", className),
|
|
20
|
+
"data-size": size,
|
|
21
|
+
"data-slot": "toggle-group",
|
|
22
|
+
"data-variant": variant,
|
|
23
|
+
orientation,
|
|
24
|
+
...props,
|
|
25
|
+
children: /* @__PURE__ */ jsx(ToggleGroupContext.Provider, {
|
|
26
|
+
value: contextValue,
|
|
27
|
+
children
|
|
28
|
+
})
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
function Toggle({ className, children, variant, size, ...props }) {
|
|
32
|
+
const context = React$1.useContext(ToggleGroupContext);
|
|
33
|
+
const resolvedVariant = context.variant || variant;
|
|
34
|
+
const resolvedSize = context.size || size;
|
|
35
|
+
return /* @__PURE__ */ jsx(Toggle$1, {
|
|
36
|
+
className: cn(className),
|
|
37
|
+
"data-size": resolvedSize,
|
|
38
|
+
"data-variant": resolvedVariant,
|
|
39
|
+
size: resolvedSize,
|
|
40
|
+
variant: resolvedVariant,
|
|
41
|
+
...props,
|
|
42
|
+
children
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
function ToggleGroupSeparator({ className, orientation = "vertical", ...props }) {
|
|
46
|
+
return /* @__PURE__ */ jsx(Separator, {
|
|
47
|
+
className: cn("pointer-events-none relative bg-input before:absolute before:inset-0 dark:before:bg-input/32", className),
|
|
48
|
+
orientation,
|
|
49
|
+
...props
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
//#endregion
|
|
53
|
+
export { ToggleGroup, Toggle as ToggleGroupItem, ToggleGroupSeparator };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { VariantProps } from "class-variance-authority";
|
|
2
|
+
import * as React$1 from "react";
|
|
3
|
+
import { Toggle as Toggle$1 } from "@base-ui/react/toggle";
|
|
4
|
+
//#region src/components/toggle.d.ts
|
|
5
|
+
declare const toggleVariants: (props?: ({
|
|
6
|
+
size?: "sm" | "lg" | "default" | null | undefined;
|
|
7
|
+
variant?: "default" | "outline" | null | undefined;
|
|
8
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
9
|
+
declare function Toggle({ className, variant, size, ...props }: Toggle$1.Props & VariantProps<typeof toggleVariants>): React$1.JSX.Element;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { Toggle, toggleVariants };
|