@momentumworld/ui-react 0.17.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.
Files changed (138) hide show
  1. package/dist/chunk-2HQPCV2L.js +895 -0
  2. package/dist/chunk-2HQPCV2L.js.map +1 -0
  3. package/dist/form.d.ts +175 -0
  4. package/dist/form.js +356 -0
  5. package/dist/form.js.map +1 -0
  6. package/dist/index.d.ts +2162 -0
  7. package/dist/index.js +11640 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/input-JCZs61MO.d.ts +24 -0
  10. package/package.json +90 -0
  11. package/src/components/form/checkbox-group-field.tsx +101 -0
  12. package/src/components/form/date-field.tsx +79 -0
  13. package/src/components/form/date-range-field.tsx +106 -0
  14. package/src/components/form/form-context.ts +10 -0
  15. package/src/components/form/form.tsx +54 -0
  16. package/src/components/form/number-field.tsx +69 -0
  17. package/src/components/form/select-field.tsx +76 -0
  18. package/src/components/form/submit-button.tsx +28 -0
  19. package/src/components/form/text-field.tsx +107 -0
  20. package/src/components/layout/dashboard-header.tsx +54 -0
  21. package/src/components/layout/dashboard-panel.tsx +34 -0
  22. package/src/components/layout/dashboard-topbar.tsx +221 -0
  23. package/src/components/theme-provider.tsx +403 -0
  24. package/src/components/ui/accordion.tsx +69 -0
  25. package/src/components/ui/alert-dialog.tsx +169 -0
  26. package/src/components/ui/alert.tsx +80 -0
  27. package/src/components/ui/animated-counter.tsx +109 -0
  28. package/src/components/ui/animated-theme-toggler.tsx +265 -0
  29. package/src/components/ui/app-store-buttons.tsx +182 -0
  30. package/src/components/ui/aspect-ratio.tsx +23 -0
  31. package/src/components/ui/aurora-orb.tsx +163 -0
  32. package/src/components/ui/aurora-text.tsx +76 -0
  33. package/src/components/ui/autocomplete.tsx +296 -0
  34. package/src/components/ui/avatar-group.tsx +150 -0
  35. package/src/components/ui/avatar.tsx +285 -0
  36. package/src/components/ui/badge-group.tsx +160 -0
  37. package/src/components/ui/badge.tsx +172 -0
  38. package/src/components/ui/breadcrumb.tsx +112 -0
  39. package/src/components/ui/button.tsx +77 -0
  40. package/src/components/ui/calendar.tsx +137 -0
  41. package/src/components/ui/card.tsx +244 -0
  42. package/src/components/ui/carousel.tsx +258 -0
  43. package/src/components/ui/chart.tsx +379 -0
  44. package/src/components/ui/chat-divider.tsx +67 -0
  45. package/src/components/ui/chat.tsx +494 -0
  46. package/src/components/ui/checkbox-group.tsx +16 -0
  47. package/src/components/ui/checkbox.tsx +82 -0
  48. package/src/components/ui/collapsible.tsx +45 -0
  49. package/src/components/ui/color-picker.tsx +389 -0
  50. package/src/components/ui/combobox.tsx +411 -0
  51. package/src/components/ui/command.tsx +264 -0
  52. package/src/components/ui/confetti.tsx +196 -0
  53. package/src/components/ui/context-menu.tsx +271 -0
  54. package/src/components/ui/context-meter.tsx +134 -0
  55. package/src/components/ui/credit-card.tsx +214 -0
  56. package/src/components/ui/data-table-paged.tsx +163 -0
  57. package/src/components/ui/date-picker.tsx +154 -0
  58. package/src/components/ui/dialog.tsx +196 -0
  59. package/src/components/ui/drawer.tsx +135 -0
  60. package/src/components/ui/empty.tsx +127 -0
  61. package/src/components/ui/fab.tsx +45 -0
  62. package/src/components/ui/featured-icon.tsx +149 -0
  63. package/src/components/ui/field.tsx +88 -0
  64. package/src/components/ui/fieldset.tsx +29 -0
  65. package/src/components/ui/form.tsx +17 -0
  66. package/src/components/ui/frame.tsx +82 -0
  67. package/src/components/ui/generic-empty.tsx +142 -0
  68. package/src/components/ui/group.tsx +97 -0
  69. package/src/components/ui/help-tip.tsx +94 -0
  70. package/src/components/ui/horizontal-scroll-fader.tsx +228 -0
  71. package/src/components/ui/input-group.tsx +102 -0
  72. package/src/components/ui/input-otp.tsx +96 -0
  73. package/src/components/ui/input.tsx +66 -0
  74. package/src/components/ui/item.tsx +198 -0
  75. package/src/components/ui/kbd.tsx +30 -0
  76. package/src/components/ui/label.tsx +28 -0
  77. package/src/components/ui/markdown.tsx +188 -0
  78. package/src/components/ui/menu.tsx +312 -0
  79. package/src/components/ui/menubar.tsx +93 -0
  80. package/src/components/ui/meter.tsx +67 -0
  81. package/src/components/ui/multi-select.tsx +308 -0
  82. package/src/components/ui/navigation-menu.tsx +143 -0
  83. package/src/components/ui/number-field.tsx +160 -0
  84. package/src/components/ui/pagination-controls.tsx +74 -0
  85. package/src/components/ui/pagination.tsx +149 -0
  86. package/src/components/ui/pipeline.tsx +102 -0
  87. package/src/components/ui/popover.tsx +119 -0
  88. package/src/components/ui/preview-card.tsx +55 -0
  89. package/src/components/ui/progress.tsx +289 -0
  90. package/src/components/ui/qr-code.tsx +150 -0
  91. package/src/components/ui/radio-group.tsx +103 -0
  92. package/src/components/ui/resizable.tsx +56 -0
  93. package/src/components/ui/scroll-area.tsx +90 -0
  94. package/src/components/ui/scroller.tsx +38 -0
  95. package/src/components/ui/section-header.tsx +118 -0
  96. package/src/components/ui/segmented-control.tsx +83 -0
  97. package/src/components/ui/select.tsx +181 -0
  98. package/src/components/ui/separator.tsx +23 -0
  99. package/src/components/ui/sheet.tsx +224 -0
  100. package/src/components/ui/sidebar.tsx +774 -0
  101. package/src/components/ui/skeleton.tsx +16 -0
  102. package/src/components/ui/slider.tsx +108 -0
  103. package/src/components/ui/smooth-scroll.tsx +206 -0
  104. package/src/components/ui/social-button.tsx +247 -0
  105. package/src/components/ui/spinner-on-demand.tsx +32 -0
  106. package/src/components/ui/spinner.tsx +18 -0
  107. package/src/components/ui/stat.tsx +187 -0
  108. package/src/components/ui/stepper.tsx +167 -0
  109. package/src/components/ui/switch.tsx +56 -0
  110. package/src/components/ui/table.tsx +126 -0
  111. package/src/components/ui/tabs.tsx +90 -0
  112. package/src/components/ui/tag.tsx +242 -0
  113. package/src/components/ui/target-countdown.tsx +46 -0
  114. package/src/components/ui/text-editor.tsx +313 -0
  115. package/src/components/ui/textarea.tsx +51 -0
  116. package/src/components/ui/thinking-orb.tsx +6 -0
  117. package/src/components/ui/time-picker.tsx +308 -0
  118. package/src/components/ui/timeline.tsx +116 -0
  119. package/src/components/ui/toast.tsx +268 -0
  120. package/src/components/ui/toggle-group.tsx +101 -0
  121. package/src/components/ui/toggle.tsx +45 -0
  122. package/src/components/ui/toolbar.tsx +89 -0
  123. package/src/components/ui/tooltip.tsx +102 -0
  124. package/src/components/ui/vertical-scroll-fader.tsx +250 -0
  125. package/src/components/ui/video-player.tsx +275 -0
  126. package/src/components/upload/avatar-upload-base.tsx +131 -0
  127. package/src/components/upload/image-upload-base.tsx +112 -0
  128. package/src/form.ts +17 -0
  129. package/src/index.ts +143 -0
  130. package/src/lib/hooks/use-callback-ref.ts +15 -0
  131. package/src/lib/hooks/use-first-render.ts +11 -0
  132. package/src/lib/hooks/use-hover.ts +53 -0
  133. package/src/lib/hooks/use-is-tab-active.ts +17 -0
  134. package/src/lib/hooks/use-media-query.ts +164 -0
  135. package/src/lib/utils/css.ts +6 -0
  136. package/src/styles.css +329 -0
  137. package/src/types/helpers.ts +24 -0
  138. package/src/types/react.d.ts +7 -0
@@ -0,0 +1,403 @@
1
+ "use client";
2
+
3
+ /*
4
+ This file is adapted from next-themes to work with tanstack start.
5
+ next-themes can be found at https://github.com/pacocoursey/next-themes under the MIT license.
6
+ */
7
+
8
+ import {
9
+ createContext,
10
+ memo,
11
+ useCallback,
12
+ useContext,
13
+ useEffect,
14
+ useMemo,
15
+ useState,
16
+ } from "react";
17
+
18
+ interface ValueObject {
19
+ [themeName: string]: string;
20
+ }
21
+
22
+ export interface UseThemeProps {
23
+ /** List of all available theme names */
24
+ themes: string[];
25
+ /** Forced theme name for the current page */
26
+ forcedTheme?: string | undefined;
27
+ /** Update the theme */
28
+ setTheme: React.Dispatch<React.SetStateAction<string>>;
29
+ /** Active theme name */
30
+ theme?: string | undefined;
31
+ /** If `enableSystem` is true and the active theme is "system", this returns whether the system preference resolved to "dark" or "light". Otherwise, identical to `theme` */
32
+ resolvedTheme?: string | undefined;
33
+ /** If enableSystem is true, returns the System theme preference ("dark" or "light"), regardless what the active theme is */
34
+ systemTheme?: "dark" | "light" | undefined;
35
+ }
36
+
37
+ export type Attribute = `data-${string}` | "class";
38
+
39
+ export interface ThemeProviderProps extends React.PropsWithChildren {
40
+ /** List of all available theme names */
41
+ themes?: string[] | undefined;
42
+ /** Forced theme name for the current page */
43
+ forcedTheme?: string | undefined;
44
+ /** Whether to switch between dark and light themes based on prefers-color-scheme */
45
+ enableSystem?: boolean | undefined;
46
+ /** Disable all CSS transitions when switching themes */
47
+ disableTransitionOnChange?: boolean | undefined;
48
+ /** Whether to indicate to browsers which color scheme is used (dark or light) for built-in UI like inputs and buttons */
49
+ enableColorScheme?: boolean | undefined;
50
+ /** Key used to store theme setting in localStorage */
51
+ storageKey?: string | undefined;
52
+ /** Default theme name (for v0.0.12 and lower the default was light). If `enableSystem` is false, the default theme is light */
53
+ defaultTheme?: string | undefined;
54
+ /** HTML attribute modified based on the active theme. Accepts `class`, `data-*` (meaning any data attribute, `data-mode`, `data-color`, etc.), or an array which could include both */
55
+ attribute?: Attribute | Attribute[] | undefined;
56
+ /** Mapping of theme name to HTML attribute value. Object where key is the theme name and value is the attribute value */
57
+ value?: ValueObject | undefined;
58
+ /** Nonce string to pass to the inline script for CSP headers */
59
+ nonce?: string | undefined;
60
+ }
61
+
62
+ const colorSchemes = ["light", "dark"];
63
+ const MEDIA = "(prefers-color-scheme: dark)";
64
+ const isServer = typeof window === "undefined";
65
+ const ThemeContext = createContext<UseThemeProps | undefined>(undefined);
66
+ const defaultContext: UseThemeProps = { setTheme: (_) => {}, themes: [] };
67
+
68
+ export const useTheme = () => useContext(ThemeContext) ?? defaultContext;
69
+
70
+ export const ThemeProvider = (props: ThemeProviderProps): React.ReactNode => {
71
+ const context = useContext(ThemeContext);
72
+
73
+ // Ignore nested context providers, just passthrough children
74
+ if (context) return props.children;
75
+ return <Theme {...props} />;
76
+ };
77
+
78
+ const defaultThemes = ["light", "dark"];
79
+
80
+ export const ThemeContextOverride = ({
81
+ children,
82
+ value,
83
+ }: {
84
+ children: React.ReactNode;
85
+ value: string;
86
+ }) => {
87
+ const context = useContext(ThemeContext);
88
+
89
+ if (!context) return children;
90
+ return (
91
+ <ThemeContext.Provider
92
+ value={{
93
+ ...context,
94
+ resolvedTheme: value,
95
+ forcedTheme: value,
96
+ theme: value,
97
+ }}
98
+ >
99
+ {children}
100
+ </ThemeContext.Provider>
101
+ );
102
+ };
103
+
104
+ const Theme = ({
105
+ forcedTheme,
106
+ disableTransitionOnChange = false,
107
+ enableSystem = true,
108
+ enableColorScheme = true,
109
+ storageKey = "theme",
110
+ themes = defaultThemes,
111
+ defaultTheme = enableSystem ? "system" : "light",
112
+ attribute = "data-theme",
113
+ value,
114
+ children,
115
+ nonce,
116
+ }: ThemeProviderProps) => {
117
+ const [theme, setThemeState] = useState(() =>
118
+ getTheme(storageKey, defaultTheme),
119
+ );
120
+ const [resolvedTheme, setResolvedTheme] = useState(() =>
121
+ theme === "system" ? getSystemTheme() : theme,
122
+ );
123
+ const attrs = !value ? themes : Object.values(value);
124
+
125
+ // apply selected theme function (light, dark, system)
126
+ // biome-ignore lint/correctness/useExhaustiveDependencies: Code is copied from the library
127
+ const applyTheme = useCallback((theme: string | undefined) => {
128
+ let resolved = theme;
129
+ if (!resolved) return;
130
+
131
+ // If theme is system, resolve it before setting theme
132
+ if (theme === "system" && enableSystem) {
133
+ resolved = getSystemTheme();
134
+ }
135
+
136
+ const name = value ? value[resolved] : resolved;
137
+ const enable = disableTransitionOnChange ? disableAnimation() : null;
138
+ const d = document.documentElement;
139
+
140
+ const handleAttribute = (attr: Attribute) => {
141
+ if (attr === "class") {
142
+ d.classList.remove(...attrs);
143
+ if (name) d.classList.add(name);
144
+ } else if (attr.startsWith("data-")) {
145
+ if (name) {
146
+ d.setAttribute(attr, name);
147
+ } else {
148
+ d.removeAttribute(attr);
149
+ }
150
+ }
151
+ };
152
+
153
+ if (Array.isArray(attribute)) attribute.forEach(handleAttribute);
154
+ else handleAttribute(attribute);
155
+
156
+ if (enableColorScheme) {
157
+ const fallback = colorSchemes.includes(defaultTheme)
158
+ ? defaultTheme
159
+ : null;
160
+ const colorScheme = colorSchemes.includes(resolved) ? resolved : fallback;
161
+ // @ts-expect-error
162
+ d.style.colorScheme = colorScheme;
163
+ }
164
+
165
+ enable?.();
166
+ }, []);
167
+
168
+ // Set theme state and save to local storage
169
+ // biome-ignore lint/correctness/useExhaustiveDependencies: Code is copied from the library
170
+ const setTheme = useCallback(
171
+ // biome-ignore lint/suspicious/noExplicitAny: Code is copied from the library
172
+ (value: any) => {
173
+ const newTheme = typeof value === "function" ? value(theme) : value;
174
+ setThemeState(newTheme);
175
+
176
+ // Save to storage
177
+ try {
178
+ localStorage.setItem(storageKey, newTheme);
179
+ } catch {
180
+ // Unsupported
181
+ }
182
+ },
183
+ [theme],
184
+ );
185
+
186
+ // biome-ignore lint/correctness/useExhaustiveDependencies: Code is copied from the library
187
+ const handleMediaQuery = useCallback(
188
+ (e: MediaQueryListEvent | MediaQueryList) => {
189
+ const resolved = getSystemTheme(e);
190
+ setResolvedTheme(resolved);
191
+
192
+ if (theme === "system" && enableSystem && !forcedTheme) {
193
+ applyTheme("system");
194
+ }
195
+ },
196
+ [theme, forcedTheme],
197
+ );
198
+
199
+ // Always listen to System preference
200
+ useEffect(() => {
201
+ const media = window.matchMedia(MEDIA);
202
+
203
+ // Intentionally use deprecated listener methods to support iOS & old browsers
204
+ media.addListener(handleMediaQuery);
205
+ handleMediaQuery(media);
206
+
207
+ return () => media.removeListener(handleMediaQuery);
208
+ }, [handleMediaQuery]);
209
+
210
+ // localStorage event handling, allow to sync theme changes between tabs
211
+ // biome-ignore lint/correctness/useExhaustiveDependencies: The code is copied
212
+ useEffect(() => {
213
+ const handleStorage = (e: StorageEvent) => {
214
+ if (e.key !== storageKey) {
215
+ return;
216
+ }
217
+
218
+ // If default theme set, use it if localstorage === null (happens on local storage manual deletion)
219
+ const theme = e.newValue || defaultTheme;
220
+ setTheme(theme);
221
+ };
222
+
223
+ window.addEventListener("storage", handleStorage);
224
+ return () => window.removeEventListener("storage", handleStorage);
225
+ }, [setTheme]);
226
+
227
+ // Whenever theme or forcedTheme changes, apply it
228
+ // biome-ignore lint/correctness/useExhaustiveDependencies: The code is copied
229
+ useEffect(() => {
230
+ applyTheme(forcedTheme ?? theme);
231
+ }, [forcedTheme, theme]);
232
+
233
+ const providerValue = useMemo(
234
+ () => ({
235
+ theme,
236
+ setTheme,
237
+ forcedTheme,
238
+ themes: enableSystem ? [...themes, "system"] : themes,
239
+ resolvedTheme: theme === "system" ? resolvedTheme : theme,
240
+ systemTheme: (enableSystem ? resolvedTheme : undefined) as
241
+ | "light"
242
+ | "dark"
243
+ | undefined,
244
+ }),
245
+ [theme, setTheme, forcedTheme, enableSystem, themes, resolvedTheme],
246
+ );
247
+
248
+ return (
249
+ <ThemeContext.Provider value={providerValue}>
250
+ <ThemeScript
251
+ {...{
252
+ forcedTheme,
253
+ storageKey,
254
+ attribute,
255
+ enableSystem,
256
+ enableColorScheme,
257
+ defaultTheme,
258
+ value,
259
+ themes,
260
+ nonce,
261
+ }}
262
+ />
263
+ {children}
264
+ </ThemeContext.Provider>
265
+ );
266
+ };
267
+
268
+ const ThemeScript = memo(
269
+ ({
270
+ forcedTheme,
271
+ storageKey,
272
+ attribute,
273
+ enableSystem,
274
+ enableColorScheme,
275
+ defaultTheme,
276
+ value,
277
+ themes,
278
+ nonce,
279
+ }: Omit<ThemeProviderProps, "children"> & { defaultTheme: string }) => {
280
+ const scriptArgs = JSON.stringify([
281
+ attribute,
282
+ storageKey,
283
+ defaultTheme,
284
+ forcedTheme,
285
+ themes,
286
+ value,
287
+ enableSystem,
288
+ enableColorScheme,
289
+ ]).slice(1, -1);
290
+
291
+ return (
292
+ <script
293
+ suppressHydrationWarning
294
+ nonce={typeof window === "undefined" ? nonce : ""}
295
+ // biome-ignore lint/security/noDangerouslySetInnerHtml: Needed to inject script before hydration
296
+ dangerouslySetInnerHTML={{
297
+ __html: `(${script.toString()})(${scriptArgs})`,
298
+ }}
299
+ />
300
+ // <></>
301
+ );
302
+ },
303
+ );
304
+
305
+ // Helpers
306
+ const getTheme = (key: string, fallback?: string) => {
307
+ if (isServer) return undefined;
308
+ let theme: string | undefined;
309
+ try {
310
+ theme = localStorage.getItem(key) || undefined;
311
+ } catch {
312
+ // Unsupported
313
+ }
314
+ return theme || fallback;
315
+ };
316
+
317
+ const disableAnimation = () => {
318
+ const css = document.createElement("style");
319
+ css.appendChild(
320
+ document.createTextNode(
321
+ "*,*::before,*::after{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}",
322
+ ),
323
+ );
324
+ document.head.appendChild(css);
325
+
326
+ return () => {
327
+ // Force restyle
328
+ (() => window.getComputedStyle(document.body))();
329
+
330
+ // Wait for next tick before removing
331
+ setTimeout(() => {
332
+ document.head.removeChild(css);
333
+ }, 1);
334
+ };
335
+ };
336
+
337
+ const getSystemTheme = (e?: MediaQueryList | MediaQueryListEvent) => {
338
+ const event = e ?? window.matchMedia(MEDIA);
339
+ const isDark = event.matches;
340
+ const systemTheme = isDark ? "dark" : "light";
341
+ return systemTheme;
342
+ };
343
+
344
+ /*
345
+ This file is adapted from next-themes to work with tanstack start.
346
+ next-themes can be found at https://github.com/pacocoursey/next-themes under the MIT license.
347
+ */
348
+
349
+ // biome-ignore lint/suspicious/noExplicitAny: Code is copied from the library
350
+ export const script: (...args: any[]) => void = (
351
+ attribute,
352
+ storageKey,
353
+ defaultTheme,
354
+ forcedTheme,
355
+ themes,
356
+ value,
357
+ enableSystem,
358
+ enableColorScheme,
359
+ ) => {
360
+ const el = document.documentElement;
361
+ const systemThemes = ["light", "dark"];
362
+ const isClass = attribute === "class";
363
+ const classes =
364
+ isClass && value
365
+ ? themes.map((t: string | number) => value[t] || t)
366
+ : themes;
367
+
368
+ function updateDOM(theme: string) {
369
+ if (isClass) {
370
+ el.classList.remove(...classes);
371
+ el.classList.add(theme);
372
+ } else {
373
+ el.setAttribute(attribute, theme);
374
+ }
375
+
376
+ setColorScheme(theme);
377
+ }
378
+
379
+ function setColorScheme(theme: string) {
380
+ if (enableColorScheme && systemThemes.includes(theme)) {
381
+ el.style.colorScheme = theme;
382
+ }
383
+ }
384
+
385
+ function getSystemTheme() {
386
+ return window.matchMedia("(prefers-color-scheme: dark)").matches
387
+ ? "dark"
388
+ : "light";
389
+ }
390
+
391
+ if (forcedTheme) {
392
+ updateDOM(forcedTheme);
393
+ } else {
394
+ try {
395
+ const themeName = localStorage.getItem(storageKey) || defaultTheme;
396
+ const isSystem = enableSystem && themeName === "system";
397
+ const theme = isSystem ? getSystemTheme() : themeName;
398
+ updateDOM(theme);
399
+ } catch {
400
+ //
401
+ }
402
+ }
403
+ };
@@ -0,0 +1,69 @@
1
+ "use client";
2
+
3
+ import { Accordion as AccordionPrimitive } from "@base-ui/react/accordion";
4
+ import { ChevronDownIcon } from "lucide-react";
5
+
6
+ import { cn } from "../../lib/utils/css";
7
+
8
+ function Accordion(props: AccordionPrimitive.Root.Props) {
9
+ return <AccordionPrimitive.Root data-slot="accordion" {...props} />;
10
+ }
11
+
12
+ function AccordionItem({ className, ...props }: AccordionPrimitive.Item.Props) {
13
+ return (
14
+ <AccordionPrimitive.Item
15
+ className={cn("border-b last:border-b-0", className)}
16
+ data-slot="accordion-item"
17
+ {...props}
18
+ />
19
+ );
20
+ }
21
+
22
+ function AccordionTrigger({
23
+ className,
24
+ children,
25
+ ...props
26
+ }: AccordionPrimitive.Trigger.Props) {
27
+ return (
28
+ <AccordionPrimitive.Header className="flex">
29
+ <AccordionPrimitive.Trigger
30
+ className={cn(
31
+ "flex flex-1 cursor-pointer items-start justify-between gap-4 rounded-md py-4 text-left font-medium text-sm outline-none transition-all focus-visible:ring-[3px] focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-64 data-panel-open:*:data-[slot=accordion-indicator]:rotate-180",
32
+ className,
33
+ )}
34
+ data-slot="accordion-trigger"
35
+ {...props}
36
+ >
37
+ {children}
38
+ <ChevronDownIcon
39
+ className="pointer-events-none size-4 shrink-0 translate-y-0.5 opacity-80 transition-transform duration-200 ease-in-out"
40
+ data-slot="accordion-indicator"
41
+ />
42
+ </AccordionPrimitive.Trigger>
43
+ </AccordionPrimitive.Header>
44
+ );
45
+ }
46
+
47
+ function AccordionPanel({
48
+ className,
49
+ children,
50
+ ...props
51
+ }: AccordionPrimitive.Panel.Props) {
52
+ return (
53
+ <AccordionPrimitive.Panel
54
+ className="h-(--accordion-panel-height) overflow-hidden text-muted-foreground text-sm transition-[height] duration-200 ease-in-out data-ending-style:h-0 data-starting-style:h-0"
55
+ data-slot="accordion-panel"
56
+ {...props}
57
+ >
58
+ <div className={cn("pt-0 pb-4", className)}>{children}</div>
59
+ </AccordionPrimitive.Panel>
60
+ );
61
+ }
62
+
63
+ export {
64
+ Accordion,
65
+ AccordionItem,
66
+ AccordionTrigger,
67
+ AccordionPanel,
68
+ AccordionPanel as AccordionContent,
69
+ };
@@ -0,0 +1,169 @@
1
+ "use client";
2
+
3
+ import { AlertDialog as AlertDialogPrimitive } from "@base-ui/react/alert-dialog";
4
+
5
+ import { cn } from "../../lib/utils/css";
6
+
7
+ const AlertDialogCreateHandle = AlertDialogPrimitive.createHandle;
8
+
9
+ const AlertDialog = AlertDialogPrimitive.Root;
10
+
11
+ const AlertDialogPortal = AlertDialogPrimitive.Portal;
12
+
13
+ function AlertDialogTrigger(props: AlertDialogPrimitive.Trigger.Props) {
14
+ return (
15
+ <AlertDialogPrimitive.Trigger data-slot="alert-dialog-trigger" {...props} />
16
+ );
17
+ }
18
+
19
+ function AlertDialogBackdrop({
20
+ className,
21
+ ...props
22
+ }: AlertDialogPrimitive.Backdrop.Props) {
23
+ return (
24
+ <AlertDialogPrimitive.Backdrop
25
+ className={cn(
26
+ "fixed inset-0 z-50 bg-black/32 backdrop-blur-sm transition-all duration-200 ease-out data-ending-style:opacity-0 data-starting-style:opacity-0",
27
+ className,
28
+ )}
29
+ data-slot="alert-dialog-backdrop"
30
+ {...props}
31
+ />
32
+ );
33
+ }
34
+
35
+ function AlertDialogViewport({
36
+ className,
37
+ ...props
38
+ }: AlertDialogPrimitive.Viewport.Props) {
39
+ return (
40
+ <AlertDialogPrimitive.Viewport
41
+ className={cn(
42
+ "fixed inset-0 z-50 grid grid-rows-[1fr_auto_3fr] justify-items-center p-4",
43
+ className,
44
+ )}
45
+ data-slot="alert-dialog-viewport"
46
+ {...props}
47
+ />
48
+ );
49
+ }
50
+
51
+ function AlertDialogPopup({
52
+ className,
53
+ bottomStickOnMobile = true,
54
+ ...props
55
+ }: AlertDialogPrimitive.Popup.Props & {
56
+ bottomStickOnMobile?: boolean;
57
+ }) {
58
+ return (
59
+ <AlertDialogPortal>
60
+ <AlertDialogBackdrop />
61
+ <AlertDialogViewport
62
+ className={cn(
63
+ bottomStickOnMobile &&
64
+ "max-sm:grid-rows-[1fr_auto] max-sm:p-0 max-sm:pt-12",
65
+ )}
66
+ >
67
+ <AlertDialogPrimitive.Popup
68
+ className={cn(
69
+ "-translate-y-[calc(1.25rem*var(--nested-dialogs))] relative row-start-2 flex max-h-full min-h-0 w-full min-w-0 max-w-lg scale-[calc(1-0.1*var(--nested-dialogs))] flex-col rounded-2xl border bg-popover not-dark:bg-clip-padding text-popover-foreground opacity-[calc(1-0.1*var(--nested-dialogs))] shadow-lg/5 transition-[scale,opacity,translate] duration-200 ease-in-out will-change-transform before:pointer-events-none before:absolute before:inset-0 before:rounded-[calc(var(--radius-2xl)-1px)] before:shadow-[0_1px_--theme(--color-black/6%)] data-nested:data-ending-style:translate-y-8 data-nested:data-starting-style:translate-y-8 data-nested-dialog-open:origin-top 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%)]",
70
+ bottomStickOnMobile &&
71
+ "max-sm:max-w-none max-sm:rounded-none max-sm:border-x-0 max-sm:border-t max-sm:border-b-0 max-sm:opacity-[calc(1-min(var(--nested-dialogs),1))] max-sm:data-ending-style:translate-y-4 max-sm:data-starting-style:translate-y-4 max-sm:before:hidden max-sm:before:rounded-none",
72
+ className,
73
+ )}
74
+ data-slot="alert-dialog-popup"
75
+ {...props}
76
+ />
77
+ </AlertDialogViewport>
78
+ </AlertDialogPortal>
79
+ );
80
+ }
81
+
82
+ function AlertDialogHeader({
83
+ className,
84
+ ...props
85
+ }: React.ComponentProps<"div">) {
86
+ return (
87
+ <div
88
+ className={cn(
89
+ "flex flex-col gap-2 p-6 text-center max-sm:pb-4 sm:text-left",
90
+ className,
91
+ )}
92
+ data-slot="alert-dialog-header"
93
+ {...props}
94
+ />
95
+ );
96
+ }
97
+
98
+ function AlertDialogFooter({
99
+ className,
100
+ variant = "default",
101
+ ...props
102
+ }: React.ComponentProps<"div"> & {
103
+ variant?: "default" | "bare";
104
+ }) {
105
+ return (
106
+ <div
107
+ className={cn(
108
+ "flex flex-col-reverse gap-2 px-6 sm:flex-row sm:justify-end sm:rounded-b-[calc(var(--radius-2xl)-1px)]",
109
+ variant === "default" && "border-t bg-muted/72 py-4",
110
+ variant === "bare" && "pb-6",
111
+ className,
112
+ )}
113
+ data-slot="alert-dialog-footer"
114
+ {...props}
115
+ />
116
+ );
117
+ }
118
+
119
+ function AlertDialogTitle({
120
+ className,
121
+ ...props
122
+ }: AlertDialogPrimitive.Title.Props) {
123
+ return (
124
+ <AlertDialogPrimitive.Title
125
+ className={cn(
126
+ "font-heading font-semibold text-xl leading-none",
127
+ className,
128
+ )}
129
+ data-slot="alert-dialog-title"
130
+ {...props}
131
+ />
132
+ );
133
+ }
134
+
135
+ function AlertDialogDescription({
136
+ className,
137
+ ...props
138
+ }: AlertDialogPrimitive.Description.Props) {
139
+ return (
140
+ <AlertDialogPrimitive.Description
141
+ className={cn("text-muted-foreground text-sm", className)}
142
+ data-slot="alert-dialog-description"
143
+ {...props}
144
+ />
145
+ );
146
+ }
147
+
148
+ function AlertDialogClose(props: AlertDialogPrimitive.Close.Props) {
149
+ return (
150
+ <AlertDialogPrimitive.Close data-slot="alert-dialog-close" {...props} />
151
+ );
152
+ }
153
+
154
+ export {
155
+ AlertDialogCreateHandle,
156
+ AlertDialog,
157
+ AlertDialogPortal,
158
+ AlertDialogBackdrop,
159
+ AlertDialogBackdrop as AlertDialogOverlay,
160
+ AlertDialogTrigger,
161
+ AlertDialogPopup,
162
+ AlertDialogPopup as AlertDialogContent,
163
+ AlertDialogHeader,
164
+ AlertDialogFooter,
165
+ AlertDialogTitle,
166
+ AlertDialogDescription,
167
+ AlertDialogClose,
168
+ AlertDialogViewport,
169
+ };