@datum-cloud/datum-ui 0.2.0-alpha.2 → 0.2.0-alpha.4

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 (133) hide show
  1. package/README.md +336 -0
  2. package/dist/alert/index.mjs +3 -0
  3. package/dist/alert-BC2Mccfo.mjs +95 -0
  4. package/dist/autocomplete/index.mjs +7 -0
  5. package/dist/autocomplete-DZtI97HP.mjs +295 -0
  6. package/dist/avatar-stack/index.mjs +5 -0
  7. package/dist/avatar-stack-JCfBlPB9.mjs +80 -0
  8. package/dist/badge/index.mjs +3 -0
  9. package/dist/badge-bFgeYceE.mjs +185 -0
  10. package/dist/breadcrumb/index.mjs +4 -0
  11. package/dist/breadcrumb-BGYJgom_.mjs +71 -0
  12. package/dist/button/index.mjs +4 -0
  13. package/dist/button-AzpnV-WB.mjs +49 -0
  14. package/dist/button-C1wRfGtT.mjs +230 -0
  15. package/dist/button-group/index.mjs +5 -0
  16. package/dist/button-group-C1IB2K5s.mjs +40 -0
  17. package/dist/calendar/index.mjs +5 -0
  18. package/dist/calendar-DlIHeWb0.mjs +113 -0
  19. package/dist/card/index.mjs +4 -0
  20. package/dist/card-3Kd0VdNf.mjs +63 -0
  21. package/dist/chart/index.mjs +4 -0
  22. package/dist/chart-BZqUKpkh.mjs +143 -0
  23. package/dist/checkbox/index.mjs +4 -0
  24. package/dist/checkbox-LG1OKTpG.mjs +34 -0
  25. package/dist/col-lrLMZaTJ.mjs +184 -0
  26. package/dist/collapsible/index.mjs +3 -0
  27. package/dist/collapsible-Bt9UYfv3.mjs +9 -0
  28. package/dist/command/index.mjs +5 -0
  29. package/dist/command-s0Yv3abE.mjs +86 -0
  30. package/dist/components/features/date-picker/index.d.ts +3 -0
  31. package/dist/components/features/date-picker/index.d.ts.map +1 -0
  32. package/dist/components/features/dropzone/index.d.ts +1 -0
  33. package/dist/components/features/dropzone/index.d.ts.map +1 -1
  34. package/dist/date-picker/index.mjs +9 -0
  35. package/dist/{datum.provider-D6VMjSV0.mjs → datum.provider-B77goJgl.mjs} +1 -1
  36. package/dist/dialog/index.mjs +5 -0
  37. package/dist/dialog-DXBaT9gA.mjs +86 -0
  38. package/dist/dialog-bnMMf9GD.mjs +73 -0
  39. package/dist/dropdown/index.mjs +3 -0
  40. package/dist/dropdown-DtSa_lqc.mjs +112 -0
  41. package/dist/dropzone/index.mjs +5 -0
  42. package/dist/dropzone-BkOnwrS4.mjs +221 -0
  43. package/dist/empty-content/index.mjs +3 -0
  44. package/dist/empty-content-BM9rzI13.mjs +196 -0
  45. package/dist/exports/map.d.ts +3 -0
  46. package/dist/exports/map.d.ts.map +1 -0
  47. package/dist/form/index.mjs +146 -0
  48. package/dist/grid/index.mjs +3 -0
  49. package/dist/hooks/index.mjs +2 -3
  50. package/dist/hover-card/index.mjs +4 -0
  51. package/dist/hover-card-CUPfFUqE.mjs +33 -0
  52. package/dist/icon-wrapper-9ticVbRL.mjs +14 -0
  53. package/dist/icons/index.mjs +3 -3
  54. package/dist/index.mjs +66 -8
  55. package/dist/input/index.mjs +5 -0
  56. package/dist/input-DuyjEKEW.mjs +17 -0
  57. package/dist/input-fzXBheCN.mjs +17 -0
  58. package/dist/input-group/index.mjs +7 -0
  59. package/dist/input-group-CPaFSTEV.mjs +80 -0
  60. package/dist/input-number/index.mjs +6 -0
  61. package/dist/input-number-9o62JHRl.mjs +106 -0
  62. package/dist/input-with-addons/index.mjs +3 -0
  63. package/dist/input-with-addons-BQn7KCTU.mjs +30 -0
  64. package/dist/label/index.mjs +4 -0
  65. package/dist/label-_ste_Re3.mjs +44 -0
  66. package/dist/link-button-TIF2Zdrk.mjs +36 -0
  67. package/dist/loader-overlay/index.mjs +3 -0
  68. package/dist/loader-overlay-DUaQSZQP.mjs +17 -0
  69. package/dist/map/index.mjs +13 -0
  70. package/dist/map-Df8QMcX0.mjs +1094 -0
  71. package/dist/more-actions/index.mjs +5 -0
  72. package/dist/more-actions-Ch1f6Mh3.mjs +54 -0
  73. package/dist/nprogress/index.mjs +32 -0
  74. package/dist/page-title/index.mjs +3 -0
  75. package/dist/page-title-BJuo81rT.mjs +26 -0
  76. package/dist/popover/index.mjs +4 -0
  77. package/dist/popover-SQlKSz6L.mjs +36 -0
  78. package/dist/provider/index.mjs +4 -0
  79. package/dist/radio-group/index.mjs +4 -0
  80. package/dist/radio-group-Oshv0b-U.mjs +49 -0
  81. package/dist/select/index.mjs +4 -0
  82. package/dist/select-DVlEzD2W.mjs +166 -0
  83. package/dist/separator/index.mjs +4 -0
  84. package/dist/separator-T2ppyD-8.mjs +18 -0
  85. package/dist/sheet/index.mjs +5 -0
  86. package/dist/sheet-BKiCwtNO.mjs +45 -0
  87. package/dist/sheet-CtnP6gTD.mjs +77 -0
  88. package/dist/sidebar/index.mjs +11 -0
  89. package/dist/sidebar-DfqezV8t.mjs +945 -0
  90. package/dist/skeleton/index.mjs +4 -0
  91. package/dist/skeleton-vzbxA-DQ.mjs +13 -0
  92. package/dist/spinner/index.mjs +4 -0
  93. package/dist/spinner-BE7k2bAD.mjs +16 -0
  94. package/dist/{icon-wrapper-BgPkifId.mjs → spinner.icon-Bg8zgGh0.mjs} +1 -12
  95. package/dist/stepper/index.mjs +5 -0
  96. package/dist/stepper-SWB-u_nM.mjs +323 -0
  97. package/dist/style.css +3 -0
  98. package/dist/switch/index.mjs +4 -0
  99. package/dist/switch-Calk7Gyw.mjs +32 -0
  100. package/dist/table/index.mjs +4 -0
  101. package/dist/table-CsXBcQLI.mjs +68 -0
  102. package/dist/tabs/index.mjs +3 -0
  103. package/dist/tabs-D8n-dqnw.mjs +52 -0
  104. package/dist/tag-input/index.mjs +5 -0
  105. package/dist/tag-input-Di7SDNbK.mjs +284 -0
  106. package/dist/task-queue/index.mjs +7 -0
  107. package/dist/task-queue-dropdown-DW72ikDH.mjs +1356 -0
  108. package/dist/textarea/index.mjs +5 -0
  109. package/dist/textarea-CxE3YbC7.mjs +17 -0
  110. package/dist/textarea-QYRcDEpK.mjs +15 -0
  111. package/dist/theme/index.mjs +4 -0
  112. package/dist/theme-script-XBouzsNR.mjs +66 -0
  113. package/dist/to-api-format-C2xjQUcI.mjs +1506 -0
  114. package/dist/toast/index.mjs +3 -0
  115. package/dist/tooltip/index.mjs +4 -0
  116. package/dist/tooltip-Dd3ActSS.mjs +74 -0
  117. package/dist/typography/index.mjs +3 -0
  118. package/dist/typography-UA7ZZvgJ.mjs +200 -0
  119. package/dist/use-copy-to-clipboard-ki-WoTml.mjs +31 -0
  120. package/dist/use-stepper-BaToCYMs.mjs +2017 -0
  121. package/dist/{use-copy-to-clipboard-BfrpD6G8.mjs → use-toast-mdn_CqRY.mjs} +34 -27
  122. package/dist/utils/index.mjs +0 -1
  123. package/dist/utils-Bfgoe-Gm.mjs +20 -0
  124. package/dist/visually-hidden/index.mjs +3 -0
  125. package/dist/visuallyhidden-aaTUk4Yo.mjs +7 -0
  126. package/package.json +208 -8
  127. package/dist/components/index.mjs +0 -8
  128. package/dist/providers/index.mjs +0 -4
  129. package/dist/theme-script-DHyLk25i.mjs +0 -11128
  130. /package/dist/{close.icon-chkXPAUC.mjs → close.icon-CMNMoXM_.mjs} +0 -0
  131. /package/dist/{map-leaflet-imports-OKaoesjZ.mjs → map-leaflet-imports-CdzvEnzY.mjs} +0 -0
  132. /package/dist/{theme.provider-DpFLwtHe.mjs → theme.provider-DgGshapa.mjs} +0 -0
  133. /package/dist/{use-debounce-BYB-jPeX.mjs → use-debounce-DQ1tmxOL.mjs} +0 -0
package/README.md ADDED
@@ -0,0 +1,336 @@
1
+ # @datum-cloud/datum-ui
2
+
3
+ Datum Cloud's React design system and component library. Themed, composable components built on [shadcn/ui](https://ui.shadcn.com), [Radix UI](https://www.radix-ui.com), and [Tailwind CSS v4](https://tailwindcss.com).
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @datum-cloud/datum-ui
9
+ # or
10
+ yarn add @datum-cloud/datum-ui
11
+ # or
12
+ pnpm add @datum-cloud/datum-ui
13
+ # or
14
+ bun add @datum-cloud/datum-ui
15
+ ```
16
+
17
+ ## Setup
18
+
19
+ Wrap your app with `DatumProvider` to enable theming and styles:
20
+
21
+ ```tsx
22
+ import { DatumProvider } from '@datum-cloud/datum-ui/provider'
23
+
24
+ function App() {
25
+ return (
26
+ <DatumProvider>
27
+ {/* your app */}
28
+ </DatumProvider>
29
+ )
30
+ }
31
+ ```
32
+
33
+ `DatumProvider` automatically loads all design tokens, theme variables, and component styles — no extra CSS import needed.
34
+
35
+ ## Imports
36
+
37
+ Each component has its own subpath export. Import only what you need:
38
+
39
+ ```tsx
40
+ import { Button } from '@datum-cloud/datum-ui/button'
41
+ import { Dialog } from '@datum-cloud/datum-ui/dialog'
42
+ import { Form, FormField, FormInput } from '@datum-cloud/datum-ui/form'
43
+ ```
44
+
45
+ This keeps your bundle small and means you only install peer dependencies for the components you actually use.
46
+
47
+ ### Shared Exports
48
+
49
+ | Import Path | Description |
50
+ | -------------------------------- | ----------------------------------------------------- |
51
+ | `@datum-cloud/datum-ui` | Root barrel — all components (requires all peer deps) |
52
+ | `@datum-cloud/datum-ui/provider` | `DatumProvider` (loads CSS + theme) |
53
+ | `@datum-cloud/datum-ui/theme` | Theme utilities and types |
54
+ | `@datum-cloud/datum-ui/hooks` | `useCopyToClipboard`, `useDebounce` |
55
+ | `@datum-cloud/datum-ui/icons` | `CloseIcon`, `IconWrapper`, `SpinnerIcon` |
56
+ | `@datum-cloud/datum-ui/utils` | `cn` (className merge utility) |
57
+ | `@datum-cloud/datum-ui/styles` | Global CSS (fonts, tokens, component styles) |
58
+
59
+ ### Grouped Exports
60
+
61
+ Some components with shared heavy dependencies are grouped under a single subpath:
62
+
63
+ | Import Path | Includes | Peer Dependencies |
64
+ | ----------------------------------- | ------------------------------------------ | --------------------------------------------- |
65
+ | `@datum-cloud/datum-ui/date-picker` | `CalendarDatePicker`, `TimeRangePicker` | `react-day-picker`, `date-fns`, `date-fns-tz` |
66
+ | `@datum-cloud/datum-ui/map` | `Map`, `PlaceAutocomplete`, + map controls | `leaflet`, `react-leaflet`, + leaflet plugins |
67
+ | `@datum-cloud/datum-ui/dropzone` | `Dropzone`, `FileInputButton` | `react-dropzone` |
68
+ | `@datum-cloud/datum-ui/chart` | `ChartContainer`, `ChartTooltip`, etc. | `recharts` |
69
+ | `@datum-cloud/datum-ui/form` | `Form`, `FormField`, `FormInput`, etc. | `@conform-to/react`, `@conform-to/zod`, `zod` |
70
+
71
+ ## Components
72
+
73
+ ### Base Components
74
+
75
+ Thin wrappers around shadcn/Radix primitives with Datum styling.
76
+
77
+ | Component | Peer Dependencies | Description |
78
+ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------- |
79
+ | `Alert`, `AlertTitle`, `AlertDescription` | — | Status alert banners |
80
+ | `Badge` | — | Labels and status indicators with `type` and `theme` variants |
81
+ | `Breadcrumb`, `BreadcrumbItem`, `BreadcrumbLink`, `BreadcrumbSeparator`, `BreadcrumbList`, `BreadcrumbPage`, `BreadcrumbEllipsis` | — | Navigation breadcrumbs |
82
+ | `Button` | `@radix-ui/react-slot` | Button with `type` (primary/secondary/danger/warning/success) and `theme` (solid/outline/ghost/link) variants |
83
+ | `ButtonGroup` | — | Group buttons horizontally |
84
+ | `Calendar` | `react-day-picker` | Date picker calendar |
85
+ | `Card`, `CardHeader`, `CardTitle`, `CardDescription`, `CardContent`, `CardFooter` | — | Content container |
86
+ | `Chart` (ChartContainer, ChartTooltip, etc.) | `recharts` | Data visualization wrapper |
87
+ | `Checkbox` | `@radix-ui/react-checkbox` | Toggle checkbox |
88
+ | `Collapsible`, `CollapsibleTrigger`, `CollapsibleContent` | `@radix-ui/react-collapsible` | Expandable sections |
89
+ | `Command`, `CommandInput`, `CommandList`, `CommandItem`, `CommandGroup` | `cmdk` | Command palette / search |
90
+ | `Dialog`, `DialogTrigger`, `DialogContent`, `DialogHeader`, `DialogTitle`, `DialogDescription`, `DialogFooter`, `DialogClose` | `@radix-ui/react-dialog` | Modal dialog |
91
+ | `HoverCard`, `HoverCardTrigger`, `HoverCardContent` | `@radix-ui/react-hover-card` | Hover-triggered popover |
92
+ | `Input` | — | Text input |
93
+ | `InputGroup`, `InputGroupInput`, `InputGroupText` | — | Input with prefix/suffix elements |
94
+ | `Label` | `@radix-ui/react-label` | Form label |
95
+ | `Map`, `MapTileLayer`, `MapMarker`, `MapPopup`, `MapTooltip`, `MapZoomControl`, `MapFullscreenControl`, `MapLayers`, `MapLayersControl`, `MapLayerGroup`, `MapCircle`, `MapPolygon`, `MapRectangle`, `MapPolyline`, `MapDrawControl`, `MapDrawMarker`, `MapDrawPolyline`, `MapDrawCircle`, `MapDrawPolygon`, `MapDrawEdit`, `MapDrawDelete`, `MapDrawUndo`, `MapLocateControl`, `MapSearchControl`, `MapControlContainer` | `leaflet`, `react-leaflet`, `leaflet-draw`, `leaflet.fullscreen`, `leaflet.markercluster`, `react-leaflet-markercluster` | Interactive map (SSR-safe, lazy-loaded) |
96
+ | `PlaceAutocomplete` | — | Google Places address autocomplete |
97
+ | `Popover`, `PopoverTrigger`, `PopoverContent` | `@radix-ui/react-popover` | Click-triggered popover |
98
+ | `RadioGroup`, `RadioGroupItem` | `@radix-ui/react-radio-group` | Radio button group |
99
+ | `Select`, `SelectTrigger`, `SelectContent`, `SelectItem`, `SelectValue`, `SelectGroup`, `SelectLabel`, `SelectSeparator` | `@radix-ui/react-select` | Dropdown select |
100
+ | `Separator` | `@radix-ui/react-separator` | Visual divider |
101
+ | `Sheet`, `SheetTrigger`, `SheetContent`, `SheetHeader`, `SheetTitle`, `SheetDescription`, `SheetFooter`, `SheetClose` | `@radix-ui/react-dialog` | Slide-out panel |
102
+ | `Skeleton` | — | Loading placeholder |
103
+ | `Spinner` | — | Loading spinner |
104
+ | `Switch` | `@radix-ui/react-switch` | Toggle switch |
105
+ | `Table`, `TableHeader`, `TableBody`, `TableFooter`, `TableHead`, `TableRow`, `TableCell`, `TableCaption` | — | Data table |
106
+ | `Tabs`, `TabsList`, `TabsTrigger`, `TabsContent` | `@radix-ui/react-tabs` | Tabbed interface |
107
+ | `Textarea` | — | Multi-line text input |
108
+ | `Tooltip`, `TooltipTrigger`, `TooltipContent`, `TooltipProvider` | `@radix-ui/react-tooltip` | Hover tooltip |
109
+ | `Title`, `Text`, `Paragraph`, `Link`, `List`, `ListItem`, `Blockquote`, `Code` | — | Typography components with `level`, `size`, `weight`, `color`, `type` variants |
110
+ | `VisuallyHidden` | `@radix-ui/react-visually-hidden` | Screen-reader only content |
111
+
112
+ ### Feature Components
113
+
114
+ Complex, fully-customized components with significant business logic.
115
+
116
+ | Component | Peer Dependencies | Description |
117
+ | -------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- | ----------------------------------------- |
118
+ | `Autocomplete` | `cmdk` | Search autocomplete input |
119
+ | `AvatarStack` | `@radix-ui/react-avatar`, `@radix-ui/react-tooltip` | Stacked avatar display |
120
+ | `CalendarDatePicker` | `react-day-picker`, `date-fns` | Date/range picker with presets |
121
+ | `Dropdown`, `DropdownHeader`, `DropdownItem`, `DropdownSection` | `@radix-ui/react-dropdown-menu` | Dropdown menu |
122
+ | `Dropzone` | `react-dropzone` | File drag-and-drop upload area |
123
+ | `EmptyContent` | — | Empty state placeholder |
124
+ | `FileInputButton` | — | File upload button |
125
+ | `Form`, `FormField`, `FormInput`, `FormTextarea`, `FormSelect`, `FormCheckbox`, `FormSwitch`, `FormRadioGroup`, `FormFieldArray` | `@conform-to/react`, `@conform-to/zod`, `zod` | Form system with validation |
126
+ | `Grid` | `@tanstack/react-virtual` | Virtualized data grid |
127
+ | `InputNumber` | `react-number-format` | Numeric input with formatting |
128
+ | `InputWithAddons` | — | Input with prefix/suffix addons |
129
+ | `LoaderOverlay` | — | Full-screen loading overlay |
130
+ | `MoreActions` | `@radix-ui/react-dropdown-menu` | Three-dot actions menu |
131
+ | `NProgress` | `nprogress` | Page navigation progress bar |
132
+ | `PageTitle` | — | Page header with breadcrumbs |
133
+ | `Sidebar`, `SidebarHeader`, `SidebarContent`, `SidebarFooter`, `SidebarMenu`, `SidebarMenuItem`, `SidebarMenuButton` | — | App sidebar navigation |
134
+ | `Stepper` | `@stepperize/react` | Multi-step wizard |
135
+ | `TagInput` | — | Tag/chip input |
136
+ | `TaskQueue`, `TaskQueueProvider`, `TaskQueueDropdown`, `TaskPanelHeader`, `TaskSummaryDialog` | — | Background task queue with progress UI |
137
+ | `TimeRangePicker` | `date-fns`, `date-fns-tz` | Time range selector with timezone support |
138
+ | `Toast`, `Toaster`, `useToast` | `sonner` | Toast notifications |
139
+
140
+ ## Usage Examples
141
+
142
+ ### Button
143
+
144
+ ```tsx
145
+ import { Button } from '@datum-cloud/datum-ui/button'
146
+
147
+ // Variants: type × theme
148
+ <Button type="primary" theme="solid">Save</Button>
149
+ <Button type="danger" theme="outline">Delete</Button>
150
+ <Button type="secondary" theme="ghost">Cancel</Button>
151
+ ```
152
+
153
+ ### Typography
154
+
155
+ ```tsx
156
+ import { Title, Text, Paragraph, Code } from '@datum-cloud/datum-ui/typography'
157
+
158
+ <Title level={1}>Page Title</Title>
159
+ <Title level={3} color="primary">Section</Title>
160
+ <Text size="sm" color="secondary">Subtitle text</Text>
161
+ <Paragraph>Body paragraph with default styling.</Paragraph>
162
+ <Code copyable>npm install @datum-cloud/datum-ui</Code>
163
+ ```
164
+
165
+ ### Form with Validation
166
+
167
+ ```tsx
168
+ import { Form, FormField, FormInput, FormSelect } from '@datum-cloud/datum-ui/form'
169
+ import { z } from 'zod'
170
+
171
+ const schema = z.object({
172
+ name: z.string().min(1),
173
+ role: z.enum(['admin', 'user']),
174
+ })
175
+
176
+ <Form schema={schema} onSubmit={handleSubmit}>
177
+ <FormField name="name">
178
+ <FormInput label="Name" />
179
+ </FormField>
180
+ <FormField name="role">
181
+ <FormSelect label="Role" options={[
182
+ { label: 'Admin', value: 'admin' },
183
+ { label: 'User', value: 'user' },
184
+ ]} />
185
+ </FormField>
186
+ </Form>
187
+ ```
188
+
189
+ ### Map
190
+
191
+ ```tsx
192
+ import {
193
+ Map, MapTileLayer, MapMarker, MapPopup, MapZoomControl,
194
+ } from '@datum-cloud/datum-ui/map'
195
+
196
+ <div className="h-[500px] w-full">
197
+ <Map center={[51.505, -0.09]} zoom={13}>
198
+ <MapTileLayer />
199
+ <MapZoomControl position="topright" />
200
+ <MapMarker position={[51.505, -0.09]}>
201
+ <MapPopup>Hello from London!</MapPopup>
202
+ </MapMarker>
203
+ </Map>
204
+ </div>
205
+ ```
206
+
207
+ ### Dialog
208
+
209
+ ```tsx
210
+ import {
211
+ Dialog, DialogTrigger, DialogContent,
212
+ DialogHeader, DialogTitle, DialogDescription,
213
+ } from '@datum-cloud/datum-ui/dialog'
214
+
215
+ <Dialog>
216
+ <DialogTrigger asChild>
217
+ <Button>Open</Button>
218
+ </DialogTrigger>
219
+ <DialogContent>
220
+ <DialogHeader>
221
+ <DialogTitle>Confirm</DialogTitle>
222
+ <DialogDescription>Are you sure?</DialogDescription>
223
+ </DialogHeader>
224
+ </DialogContent>
225
+ </Dialog>
226
+ ```
227
+
228
+ ### Toast
229
+
230
+ ```tsx
231
+ import { Toaster, useToast } from '@datum-cloud/datum-ui/toast'
232
+
233
+ function App() {
234
+ return (
235
+ <DatumProvider>
236
+ <Toaster />
237
+ <MyComponent />
238
+ </DatumProvider>
239
+ )
240
+ }
241
+
242
+ function MyComponent() {
243
+ const { toast } = useToast()
244
+ return <Button onClick={() => toast.success('Saved!')}>Save</Button>
245
+ }
246
+ ```
247
+
248
+ ### Task Queue
249
+
250
+ ```tsx
251
+ import {
252
+ TaskQueueProvider, TaskQueueDropdown, useTaskQueue,
253
+ } from '@datum-cloud/datum-ui/task-queue'
254
+
255
+ <TaskQueueProvider config={{ concurrency: 3 }}>
256
+ <TaskQueueDropdown />
257
+ <MyComponent />
258
+ </TaskQueueProvider>
259
+
260
+ function MyComponent() {
261
+ const { enqueue } = useTaskQueue()
262
+
263
+ const handleUpload = () => {
264
+ enqueue({
265
+ id: 'upload-1',
266
+ label: 'Uploading file.pdf',
267
+ run: async () => { /* upload logic */ },
268
+ })
269
+ }
270
+
271
+ return <Button onClick={handleUpload}>Upload</Button>
272
+ }
273
+ ```
274
+
275
+ ## Theming
276
+
277
+ `DatumProvider` includes a theme provider with dark mode support:
278
+
279
+ ```tsx
280
+ import { DatumProvider } from '@datum-cloud/datum-ui/provider'
281
+
282
+ // Props: defaultTheme, storageKey, disableTransitionOnChange
283
+ <DatumProvider defaultTheme="system">
284
+ {children}
285
+ </DatumProvider>
286
+ ```
287
+
288
+ Theme values: `'light'`, `'dark'`, `'system'`.
289
+
290
+ Access the current theme:
291
+
292
+ ```tsx
293
+ import { useTheme } from '@datum-cloud/datum-ui/theme'
294
+
295
+ const { theme, setTheme, resolvedTheme } = useTheme()
296
+ ```
297
+
298
+ ## Peer Dependencies
299
+
300
+ All peer dependencies are **optional** — install only what you use.
301
+
302
+ > Replace `npm install` with `yarn add`, `pnpm add`, or `bun add` for your package manager.
303
+
304
+ ```bash
305
+ # Forms
306
+ npm install @conform-to/react @conform-to/zod zod
307
+
308
+ # Maps
309
+ npm install leaflet react-leaflet leaflet-draw leaflet.fullscreen leaflet.markercluster react-leaflet-markercluster
310
+
311
+ # Charts
312
+ npm install recharts
313
+
314
+ # Date pickers
315
+ npm install react-day-picker date-fns date-fns-tz
316
+
317
+ # Animations
318
+ npm install motion
319
+ ```
320
+
321
+ ## Tech Stack
322
+
323
+ - **React 19** with server component support
324
+ - **Tailwind CSS v4** for styling
325
+ - **Radix UI** for accessible primitives
326
+ - **CVA** (class-variance-authority) for variant-based component APIs
327
+ - **TypeScript** — fully typed with exported types
328
+
329
+ ## Links
330
+
331
+ - [GitHub](https://github.com/datum-cloud/datum-ui)
332
+ - [npm](https://www.npmjs.com/package/@datum-cloud/datum-ui)
333
+
334
+ ## License
335
+
336
+ MIT
@@ -0,0 +1,3 @@
1
+ import { n as AlertDescription, r as AlertTitle, t as Alert } from "../alert-BC2Mccfo.mjs";
2
+
3
+ export { Alert, AlertDescription, AlertTitle };
@@ -0,0 +1,95 @@
1
+ import { t as cn } from "./cn-DWCc1QRE.mjs";
2
+ import { cva } from "class-variance-authority";
3
+ import { CircleXIcon } from "lucide-react";
4
+ import * as React$1 from "react";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+
7
+ //#region src/components/base/alert/alert.tsx
8
+ /**
9
+ * Datum Alert Component
10
+ * Extends shadcn Alert with Datum-specific variants: success, info, warning
11
+ */
12
+ const variantDefinitions = {
13
+ default: {
14
+ classes: "bg-background text-foreground",
15
+ closeButtonColor: "text-foreground"
16
+ },
17
+ secondary: {
18
+ classes: "bg-muted text-primary [&>svg]:text-primary",
19
+ closeButtonColor: "text-primary"
20
+ },
21
+ outline: {
22
+ classes: "border-muted text-muted-foreground",
23
+ closeButtonColor: "text-muted-foreground"
24
+ },
25
+ destructive: {
26
+ classes: "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive",
27
+ closeButtonColor: "text-destructive"
28
+ },
29
+ success: {
30
+ classes: "border-success-300 bg-success-100 text-success-500",
31
+ closeButtonColor: "text-success-500"
32
+ },
33
+ info: {
34
+ classes: "border-info-300 bg-info-100 text-info-500! [&>svg]:text-info-500",
35
+ closeButtonColor: "text-info-500"
36
+ },
37
+ warning: {
38
+ classes: "border-yellow-500 bg-yellow-50 text-yellow-700! [&>svg]:text-yellow-700",
39
+ closeButtonColor: "text-yellow-700"
40
+ }
41
+ };
42
+ const alertVariants = cva("relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground", {
43
+ variants: { variant: {
44
+ default: variantDefinitions.default.classes,
45
+ secondary: variantDefinitions.secondary.classes,
46
+ outline: variantDefinitions.outline.classes,
47
+ destructive: variantDefinitions.destructive.classes,
48
+ success: variantDefinitions.success.classes,
49
+ info: variantDefinitions.info.classes,
50
+ warning: variantDefinitions.warning.classes
51
+ } },
52
+ defaultVariants: { variant: "default" }
53
+ });
54
+ function Alert({ className, variant, closable = false, onClose, ...props }) {
55
+ const [isVisible, setIsVisible] = React$1.useState(true);
56
+ const handleClose = () => {
57
+ if (onClose) onClose();
58
+ else setIsVisible(false);
59
+ };
60
+ if (!isVisible) return null;
61
+ return /* @__PURE__ */ jsxs("div", {
62
+ role: "alert",
63
+ className: cn(alertVariants({ variant }), closable && "pr-10", className),
64
+ ...props,
65
+ children: [props.children, closable && /* @__PURE__ */ jsx("span", {
66
+ onClick: handleClose,
67
+ role: "button",
68
+ tabIndex: 0,
69
+ onKeyDown: (e) => {
70
+ if (e.key === "Enter" || e.key === " ") {
71
+ e.preventDefault();
72
+ handleClose();
73
+ }
74
+ },
75
+ className: "absolute top-4 right-4 z-10 cursor-pointer opacity-70 transition-opacity hover:opacity-100",
76
+ "aria-label": "Close alert",
77
+ children: /* @__PURE__ */ jsx(CircleXIcon, { className: cn("size-4", variant && variantDefinitions[variant]?.closeButtonColor) })
78
+ })]
79
+ });
80
+ }
81
+ function AlertTitle({ className, ...props }) {
82
+ return /* @__PURE__ */ jsx("div", {
83
+ className: cn("col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight", className),
84
+ ...props
85
+ });
86
+ }
87
+ function AlertDescription({ className, ...props }) {
88
+ return /* @__PURE__ */ jsx("div", {
89
+ className: cn("text-muted-foreground col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed", className),
90
+ ...props
91
+ });
92
+ }
93
+
94
+ //#endregion
95
+ export { AlertDescription as n, AlertTitle as r, Alert as t };
@@ -0,0 +1,7 @@
1
+ import "../utils-Bfgoe-Gm.mjs";
2
+ import "../dialog-DXBaT9gA.mjs";
3
+ import "../command-s0Yv3abE.mjs";
4
+ import "../popover-SQlKSz6L.mjs";
5
+ import { t as Autocomplete } from "../autocomplete-DZtI97HP.mjs";
6
+
7
+ export { Autocomplete };