tembro 6.1.0 → 6.1.1
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/dist/components/actions/action-menu.d.ts +11 -1
- package/dist/components/display/index.d.ts +0 -2
- package/dist/components/filters/index.d.ts +0 -1
- package/dist/components/inputs/time-picker.d.ts +11 -3
- package/dist/components/modern/file-manager.d.ts +1 -1
- package/dist/components/modern/index.d.ts +3 -1
- package/dist/components/modern/map.cjs +1 -0
- package/dist/components/modern/map.d.ts +29 -0
- package/dist/components/modern/map.js +1 -0
- package/dist/components/modern/media-player.cjs +1 -0
- package/dist/components/modern/media-player.d.ts +21 -0
- package/dist/components/modern/media-player.js +1 -0
- package/dist/components/modern/spreadsheet.cjs +1 -0
- package/dist/components/modern/spreadsheet.d.ts +35 -0
- package/dist/components/modern/spreadsheet.js +1 -0
- package/dist/components/overlay/drawer.d.ts +3 -1
- package/dist/index.d.ts +0 -2
- package/dist/src/components/actions/action-menu.cjs +1 -1
- package/dist/src/components/actions/action-menu.js +47 -39
- package/dist/src/components/actions/copy-button.cjs +1 -1
- package/dist/src/components/actions/copy-button.js +4 -1
- package/dist/src/components/calendar/date-picker.cjs +1 -1
- package/dist/src/components/calendar/date-picker.js +5 -8
- package/dist/src/components/calendar/date-range-picker.cjs +1 -1
- package/dist/src/components/calendar/date-range-picker.js +12 -27
- package/dist/src/components/data-table/data-table.cjs +1 -1
- package/dist/src/components/data-table/data-table.js +172 -171
- package/dist/src/components/display/index.cjs +1 -1
- package/dist/src/components/display/index.js +9 -11
- package/dist/src/components/filters/index.cjs +1 -1
- package/dist/src/components/filters/index.js +2 -3
- package/dist/src/components/inputs/color-picker.cjs +1 -1
- package/dist/src/components/inputs/color-picker.js +63 -46
- package/dist/src/components/inputs/slider.cjs +1 -1
- package/dist/src/components/inputs/slider.js +3 -3
- package/dist/src/components/inputs/tag-input.cjs +1 -1
- package/dist/src/components/inputs/tag-input.js +7 -4
- package/dist/src/components/inputs/time-picker.cjs +1 -1
- package/dist/src/components/inputs/time-picker.js +90 -34
- package/dist/src/components/modern/index.cjs +1 -1
- package/dist/src/components/modern/index.js +6 -4
- package/dist/src/components/modern/map.cjs +1 -0
- package/dist/src/components/modern/map.js +158 -0
- package/dist/src/components/modern/media-player.cjs +1 -0
- package/dist/src/components/modern/media-player.js +176 -0
- package/dist/src/components/modern/resizable-panel.cjs +1 -1
- package/dist/src/components/modern/resizable-panel.js +39 -32
- package/dist/src/components/modern/spreadsheet.cjs +1 -0
- package/dist/src/components/modern/spreadsheet.js +97 -0
- package/dist/src/components/navigation/pagination.cjs +1 -1
- package/dist/src/components/navigation/pagination.js +5 -5
- package/dist/src/components/notifications/toast.cjs +1 -1
- package/dist/src/components/notifications/toast.js +68 -63
- package/dist/src/components/overlay/alert-dialog.cjs +1 -1
- package/dist/src/components/overlay/alert-dialog.js +8 -6
- package/dist/src/components/overlay/drawer.cjs +1 -1
- package/dist/src/components/overlay/drawer.js +38 -20
- package/dist/src/components/ui/checkbox/index.cjs +1 -1
- package/dist/src/components/ui/checkbox/index.js +2 -1
- package/dist/src/components/ui/dialog/index.cjs +1 -1
- package/dist/src/components/ui/dialog/index.js +8 -8
- package/dist/src/components/ui/dropdown-menu/index.cjs +1 -1
- package/dist/src/components/ui/dropdown-menu/index.js +21 -19
- package/dist/src/components/ui/popover/index.cjs +1 -1
- package/dist/src/components/ui/popover/index.js +10 -10
- package/dist/src/components/ui/tabs/index.cjs +1 -1
- package/dist/src/components/ui/tabs/index.js +6 -6
- package/dist/src/components/ui/toggle-group/index.cjs +1 -1
- package/dist/src/components/ui/toggle-group/index.js +2 -2
- package/dist/src/index.cjs +1 -1
- package/dist/src/index.js +80 -83
- package/dist/src/public-component-surface.cjs +1 -1
- package/dist/src/public-component-surface.js +15 -20
- package/package.json +1 -2
- package/packages/cli/dist/index.cjs +58 -178
- package/packages/cli/vendor/src/components/actions/action-menu.tsx +47 -19
- package/packages/cli/vendor/src/components/actions/copy-button.tsx +2 -2
- package/packages/cli/vendor/src/components/calendar/date-picker.tsx +2 -5
- package/packages/cli/vendor/src/components/calendar/date-range-picker.tsx +5 -12
- package/packages/cli/vendor/src/components/data-table/data-table.tsx +45 -34
- package/packages/cli/vendor/src/components/display/index.ts +3 -5
- package/packages/cli/vendor/src/components/filters/index.ts +0 -1
- package/packages/cli/vendor/src/components/inputs/color-picker.tsx +15 -1
- package/packages/cli/vendor/src/components/inputs/slider.tsx +3 -3
- package/packages/cli/vendor/src/components/inputs/tag-input.tsx +4 -4
- package/packages/cli/vendor/src/components/inputs/time-picker.tsx +91 -38
- package/packages/cli/vendor/src/components/modern/file-manager.tsx +1 -1
- package/packages/cli/vendor/src/components/modern/index.ts +3 -1
- package/packages/cli/vendor/src/components/modern/map.tsx +146 -0
- package/packages/cli/vendor/src/components/modern/media-player.tsx +182 -0
- package/packages/cli/vendor/src/components/modern/resizable-panel.tsx +15 -5
- package/packages/cli/vendor/src/components/modern/spreadsheet.tsx +155 -0
- package/packages/cli/vendor/src/components/navigation/pagination.tsx +9 -5
- package/packages/cli/vendor/src/components/notifications/toast.tsx +20 -10
- package/packages/cli/vendor/src/components/overlay/alert-dialog.tsx +3 -5
- package/packages/cli/vendor/src/components/overlay/drawer.tsx +22 -11
- package/packages/cli/vendor/src/components/ui/checkbox/index.tsx +3 -1
- package/packages/cli/vendor/src/components/ui/dialog/index.tsx +4 -4
- package/packages/cli/vendor/src/components/ui/dropdown-menu/index.tsx +18 -22
- package/packages/cli/vendor/src/components/ui/popover/index.tsx +4 -4
- package/packages/cli/vendor/src/components/ui/tabs/index.tsx +8 -3
- package/packages/cli/vendor/src/components/ui/toggle-group/index.tsx +6 -6
- package/packages/cli/vendor/src/index.ts +0 -2
- package/packages/cli/vendor/src/public-component-surface.ts +3 -4
- package/packages/cli/vendor/templates/showcase/src/showcase/data/registry.ts +6 -6
- package/packages/cli/vendor/templates/showcase/src/showcase/layout/HeroSection.tsx +23 -8
- package/packages/cli/vendor/templates/showcase/src/showcase/layout/WorkbenchSidebar.tsx +1 -1
- package/packages/cli/vendor/templates/showcase/src/showcase/sections/PatternsSection.tsx +1 -1
- package/packages/cli/vendor/templates/styles/globals.css +0 -120
- package/registry.json +74 -141
- package/dist/components/display/info-card.cjs +0 -1
- package/dist/components/display/info-card.d.ts +0 -51
- package/dist/components/display/info-card.js +0 -1
- package/dist/components/display/statistic.cjs +0 -1
- package/dist/components/display/statistic.d.ts +0 -25
- package/dist/components/display/statistic.js +0 -1
- package/dist/components/filters/filter-bar.cjs +0 -1
- package/dist/components/filters/filter-bar.d.ts +0 -28
- package/dist/components/filters/filter-bar.js +0 -1
- package/dist/components/modern/image-cropper.cjs +0 -1
- package/dist/components/modern/image-cropper.d.ts +0 -39
- package/dist/components/modern/image-cropper.js +0 -1
- package/dist/components/ui/number-field/index.cjs +0 -1
- package/dist/components/ui/number-field/index.d.ts +0 -18
- package/dist/components/ui/number-field/index.js +0 -1
- package/dist/components/ui/toolbar/index.cjs +0 -1
- package/dist/components/ui/toolbar/index.d.ts +0 -14
- package/dist/components/ui/toolbar/index.js +0 -1
- package/dist/src/components/display/info-card.cjs +0 -1
- package/dist/src/components/display/info-card.js +0 -124
- package/dist/src/components/display/statistic.cjs +0 -1
- package/dist/src/components/display/statistic.js +0 -104
- package/dist/src/components/filters/filter-bar.cjs +0 -1
- package/dist/src/components/filters/filter-bar.js +0 -103
- package/dist/src/components/modern/image-cropper.cjs +0 -1
- package/dist/src/components/modern/image-cropper.js +0 -143
- package/dist/src/components/ui/number-field/index.cjs +0 -1
- package/dist/src/components/ui/number-field/index.js +0 -73
- package/dist/src/components/ui/toolbar/index.cjs +0 -1
- package/dist/src/components/ui/toolbar/index.js +0 -50
- package/packages/cli/vendor/src/components/display/info-card.tsx +0 -195
- package/packages/cli/vendor/src/components/display/statistic.tsx +0 -114
- package/packages/cli/vendor/src/components/filters/filter-bar.tsx +0 -163
- package/packages/cli/vendor/src/components/modern/image-cropper.tsx +0 -226
- package/packages/cli/vendor/src/components/ui/number-field/index.tsx +0 -89
- package/packages/cli/vendor/src/components/ui/toolbar/index.tsx +0 -67
|
@@ -33,7 +33,11 @@ export type ActionMenuItem = {
|
|
|
33
33
|
|
|
34
34
|
export type ActionMenuProps = {
|
|
35
35
|
actions: ActionMenuItem[]
|
|
36
|
+
open?: boolean
|
|
37
|
+
defaultOpen?: boolean
|
|
38
|
+
onOpenChange?: (open: boolean) => void
|
|
36
39
|
label?: React.ReactNode
|
|
40
|
+
triggerLabel?: string
|
|
37
41
|
trigger?: React.ReactElement
|
|
38
42
|
align?: "start" | "center" | "end"
|
|
39
43
|
side?: "top" | "right" | "bottom" | "left"
|
|
@@ -50,12 +54,19 @@ export type ActionMenuProps = {
|
|
|
50
54
|
menuWidth?: number | string
|
|
51
55
|
loadingLabel?: React.ReactNode
|
|
52
56
|
persistIconSpace?: boolean
|
|
57
|
+
itemRoleDescription?: string
|
|
58
|
+
renderItem?: (action: ActionMenuItem, state: { loading: boolean; close: () => void }) => React.ReactNode
|
|
59
|
+
onActionError?: (error: unknown, action: ActionMenuItem) => void
|
|
53
60
|
}
|
|
54
|
-
|
|
61
|
+
|
|
55
62
|
function ActionMenu({
|
|
56
|
-
actions,
|
|
57
|
-
|
|
58
|
-
|
|
63
|
+
actions,
|
|
64
|
+
open: openProp,
|
|
65
|
+
defaultOpen = false,
|
|
66
|
+
onOpenChange,
|
|
67
|
+
label,
|
|
68
|
+
triggerLabel = "Open actions",
|
|
69
|
+
trigger,
|
|
59
70
|
align = "end",
|
|
60
71
|
side = "bottom",
|
|
61
72
|
sideOffset = 4,
|
|
@@ -71,12 +82,21 @@ function ActionMenu({
|
|
|
71
82
|
menuWidth,
|
|
72
83
|
loadingLabel = "Working...",
|
|
73
84
|
persistIconSpace = true,
|
|
85
|
+
itemRoleDescription,
|
|
86
|
+
renderItem,
|
|
87
|
+
onActionError,
|
|
74
88
|
}: ActionMenuProps) {
|
|
75
89
|
const visibleActions = actions.filter((action) => !action.hidden)
|
|
76
90
|
const [loadingKey, setLoadingKey] = React.useState<string | null>(null)
|
|
77
|
-
const [
|
|
91
|
+
const [internalOpen, setInternalOpen] = React.useState(defaultOpen)
|
|
92
|
+
const open = openProp ?? internalOpen
|
|
78
93
|
const lastInvokedActionKeyRef = React.useRef<string | null>(null)
|
|
79
94
|
|
|
95
|
+
const setOpen = React.useCallback((nextOpen: boolean) => {
|
|
96
|
+
if (openProp === undefined) setInternalOpen(nextOpen)
|
|
97
|
+
onOpenChange?.(nextOpen)
|
|
98
|
+
}, [onOpenChange, openProp])
|
|
99
|
+
|
|
80
100
|
const handleSelect = async (action: ActionMenuItem) => {
|
|
81
101
|
if (action.disabled || action.loading || loadingKey) return
|
|
82
102
|
|
|
@@ -84,6 +104,9 @@ function ActionMenu({
|
|
|
84
104
|
setLoadingKey(action.key)
|
|
85
105
|
await action.onSelect?.()
|
|
86
106
|
if (closeOnSelect && !action.keepOpen) setOpen(false)
|
|
107
|
+
} catch (error) {
|
|
108
|
+
onActionError?.(error, action)
|
|
109
|
+
if (!onActionError) throw error
|
|
87
110
|
} finally {
|
|
88
111
|
setLoadingKey(null)
|
|
89
112
|
}
|
|
@@ -122,7 +145,7 @@ function ActionMenu({
|
|
|
122
145
|
>
|
|
123
146
|
{!trigger && <MoreHorizontalIcon />}
|
|
124
147
|
{!trigger && showChevron && <span className="text-[10px] font-medium uppercase tracking-[0.18em]">Menu</span>}
|
|
125
|
-
<span className="sr-only">
|
|
148
|
+
<span className="sr-only">{triggerLabel}</span>
|
|
126
149
|
</DropdownMenuTrigger>
|
|
127
150
|
<DropdownMenuContent
|
|
128
151
|
align={align}
|
|
@@ -155,6 +178,7 @@ function ActionMenu({
|
|
|
155
178
|
disabled={action.disabled || isLoading}
|
|
156
179
|
variant={action.destructive ? "destructive" : "default"}
|
|
157
180
|
closeOnSelect={closeOnSelect && !action.keepOpen}
|
|
181
|
+
aria-roledescription={itemRoleDescription}
|
|
158
182
|
className={cn(
|
|
159
183
|
"min-h-11 items-start gap-3 rounded-[calc(var(--radius-md)+1px)] border border-transparent py-2.5 transition-[background-color,color,border-color,box-shadow] data-[highlighted]:shadow-[inset_0_0_0_1px_color-mix(in_oklch,var(--primary),transparent_76%)] data-[disabled]:opacity-45",
|
|
160
184
|
itemClassName
|
|
@@ -173,19 +197,23 @@ function ActionMenu({
|
|
|
173
197
|
onMouseDown={stopInteractivePropagation}
|
|
174
198
|
onDoubleClick={stopInteractivePropagation}
|
|
175
199
|
>
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
{
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
200
|
+
{renderItem?.(action, { loading: isLoading, close: () => setOpen(false) }) ?? (
|
|
201
|
+
<>
|
|
202
|
+
<span className={cn("mt-0.5 flex size-5 shrink-0 items-center justify-center text-muted-foreground", !persistIconSpace && !isLoading && !action.icon && "hidden")}>
|
|
203
|
+
{isLoading ? <Loader2Icon className="size-4 animate-spin" /> : action.icon}
|
|
204
|
+
</span>
|
|
205
|
+
<span className="min-w-0 flex-1">
|
|
206
|
+
<span className="block truncate">{action.label}</span>
|
|
207
|
+
{action.description ? (
|
|
208
|
+
<DropdownMenuItemDescription className="mt-0.5 truncate">
|
|
209
|
+
{isLoading ? loadingLabel : action.description}
|
|
210
|
+
</DropdownMenuItemDescription>
|
|
211
|
+
) : null}
|
|
212
|
+
</span>
|
|
213
|
+
{action.shortcut && (
|
|
214
|
+
<DropdownMenuShortcut>{action.shortcut}</DropdownMenuShortcut>
|
|
215
|
+
)}
|
|
216
|
+
</>
|
|
189
217
|
)}
|
|
190
218
|
</DropdownMenuItem>
|
|
191
219
|
</React.Fragment>
|
|
@@ -97,8 +97,8 @@ function CopyButton({
|
|
|
97
97
|
aria-live="polite"
|
|
98
98
|
{...props}
|
|
99
99
|
>
|
|
100
|
-
{showIcon && (copied ? <CheckIcon data-icon="inline-start" /> : <CopyIcon data-icon="inline-start" />)}
|
|
101
|
-
{children ?? (copied ? copiedLabel : copyLabel)}
|
|
100
|
+
{showIcon && (copied ? <CheckIcon data-icon="inline-start" className="size-3.5" /> : <CopyIcon data-icon="inline-start" className="size-3.5" />)}
|
|
101
|
+
{children ?? (copied ? copiedLabel : copyLabel)}
|
|
102
102
|
</Button>
|
|
103
103
|
)
|
|
104
104
|
}
|
|
@@ -86,11 +86,8 @@ function DatePicker({
|
|
|
86
86
|
/>
|
|
87
87
|
}
|
|
88
88
|
>
|
|
89
|
-
<CalendarIcon data-icon="inline-start" className={cn(hasValue && "text-primary")} />
|
|
90
|
-
<span className=
|
|
91
|
-
{triggerVariant === "default" ? <span className="text-[11px] font-semibold uppercase tracking-[0.16em] text-muted-foreground">
|
|
92
|
-
{labels?.selected ?? "Date"}
|
|
93
|
-
</span> : null}
|
|
89
|
+
<CalendarIcon data-icon="inline-start" className={cn("size-4", hasValue && "text-primary")} />
|
|
90
|
+
<span className="grid min-w-0 flex-1">
|
|
94
91
|
<span className={cn("truncate text-sm", hasValue && "font-semibold text-foreground")}>
|
|
95
92
|
{hasValue ? formatValue(String(value)) : placeholder ?? labels?.placeholder ?? "Select date"}
|
|
96
93
|
</span>
|
|
@@ -176,22 +176,15 @@ function DateRangePicker({
|
|
|
176
176
|
/>
|
|
177
177
|
}
|
|
178
178
|
>
|
|
179
|
-
<CalendarIcon data-icon="inline-start" className={cn(hasValue && "text-primary")} />
|
|
179
|
+
<CalendarIcon data-icon="inline-start" className={cn("size-4", hasValue && "text-primary")} />
|
|
180
180
|
{hasValue ? (
|
|
181
|
-
<span className="
|
|
182
|
-
<span className="
|
|
183
|
-
<span className="text-[11px] font-semibold uppercase tracking-[0.16em] text-muted-foreground">{labels?.start ?? "Start"}</span>
|
|
184
|
-
<span className="truncate text-sm font-semibold text-foreground">{from ? formatValue(from) : "..."}</span>
|
|
185
|
-
</span>
|
|
181
|
+
<span className="flex min-w-0 flex-1 items-center gap-2">
|
|
182
|
+
<span className="min-w-0 truncate text-sm font-semibold text-foreground">{from ? formatValue(from) : "..."}</span>
|
|
186
183
|
<span className="text-muted-foreground">-</span>
|
|
187
|
-
<span className="
|
|
188
|
-
<span className="text-[11px] font-semibold uppercase tracking-[0.16em] text-muted-foreground">{labels?.end ?? "End"}</span>
|
|
189
|
-
<span className="truncate text-sm font-semibold text-foreground">{to ? formatValue(to) : "..."}</span>
|
|
190
|
-
</span>
|
|
184
|
+
<span className="min-w-0 truncate text-sm font-semibold text-foreground">{to ? formatValue(to) : "..."}</span>
|
|
191
185
|
</span>
|
|
192
186
|
) : (
|
|
193
|
-
<span className="grid min-w-0 flex-1
|
|
194
|
-
<span className="text-[11px] font-semibold uppercase tracking-[0.16em] text-muted-foreground">Range</span>
|
|
187
|
+
<span className="grid min-w-0 flex-1">
|
|
195
188
|
<span className="truncate text-sm">{label}</span>
|
|
196
189
|
</span>
|
|
197
190
|
)}
|
|
@@ -4,8 +4,9 @@ import * as React from "react"
|
|
|
4
4
|
import {
|
|
5
5
|
flexRender,
|
|
6
6
|
getCoreRowModel,
|
|
7
|
-
getPaginationRowModel,
|
|
8
|
-
|
|
7
|
+
getPaginationRowModel,
|
|
8
|
+
getSortedRowModel,
|
|
9
|
+
useReactTable,
|
|
9
10
|
type Cell,
|
|
10
11
|
type ColumnDef,
|
|
11
12
|
type Header,
|
|
@@ -288,40 +289,50 @@ function DataTable<TData, TValue = unknown>({
|
|
|
288
289
|
]
|
|
289
290
|
}, [columns, features?.rowActions, rowActions])
|
|
290
291
|
|
|
291
|
-
const paginationConfig = pagination === false ? undefined : pagination
|
|
292
|
-
const
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
const
|
|
299
|
-
const resolvedRowSelection = rowSelection ??
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
292
|
+
const paginationConfig = pagination === false ? undefined : pagination
|
|
293
|
+
const [internalSorting, setInternalSorting] = React.useState<SortingState>([])
|
|
294
|
+
const [internalColumnVisibility, setInternalColumnVisibility] = React.useState<VisibilityState>({})
|
|
295
|
+
const [internalRowSelection, setInternalRowSelection] = React.useState<RowSelectionState>({})
|
|
296
|
+
const [internalExpanded, setInternalExpanded] = React.useState<ExpandedState>({})
|
|
297
|
+
const [internalColumnPinning, setInternalColumnPinning] = React.useState<ColumnPinningState>({})
|
|
298
|
+
const resolvedSorting = sorting ?? internalSorting
|
|
299
|
+
const resolvedColumnVisibility = columnVisibility ?? internalColumnVisibility
|
|
300
|
+
const resolvedRowSelection = rowSelection ?? internalRowSelection
|
|
301
|
+
const resolvedExpanded = expanded ?? internalExpanded
|
|
302
|
+
const resolvedColumnPinning = columnPinning ?? internalColumnPinning
|
|
303
|
+
const controlledPagination = paginationConfig
|
|
304
|
+
? {
|
|
305
|
+
pageIndex: paginationConfig.pageIndex,
|
|
306
|
+
pageSize: paginationConfig.pageSize,
|
|
307
|
+
}
|
|
308
|
+
: undefined
|
|
309
|
+
const manualPagination = Boolean(paginationConfig && paginationConfig.manual !== false)
|
|
310
|
+
|
|
311
|
+
// TanStack Table returns imperative helpers that React Compiler flags by design.
|
|
312
|
+
// eslint-disable-next-line react-hooks/incompatible-library
|
|
313
|
+
const table = useReactTable({
|
|
304
314
|
data,
|
|
305
315
|
columns: resolvedColumns,
|
|
306
|
-
getRowId,
|
|
307
|
-
getCoreRowModel: getCoreRowModel(),
|
|
308
|
-
|
|
309
|
-
manualPagination,
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
316
|
+
getRowId,
|
|
317
|
+
getCoreRowModel: getCoreRowModel(),
|
|
318
|
+
getSortedRowModel: getSortedRowModel(),
|
|
319
|
+
getPaginationRowModel: paginationConfig && !manualPagination ? getPaginationRowModel() : undefined,
|
|
320
|
+
manualPagination,
|
|
321
|
+
pageCount: paginationConfig?.pageCount,
|
|
322
|
+
state: {
|
|
323
|
+
sorting: resolvedSorting,
|
|
324
|
+
columnVisibility: resolvedColumnVisibility,
|
|
325
|
+
rowSelection: resolvedRowSelection,
|
|
326
|
+
pagination: controlledPagination,
|
|
327
|
+
expanded: resolvedExpanded,
|
|
328
|
+
columnPinning: resolvedColumnPinning,
|
|
329
|
+
},
|
|
330
|
+
onSortingChange: onSortingChange ?? setInternalSorting,
|
|
331
|
+
onColumnVisibilityChange: onColumnVisibilityChange ?? setInternalColumnVisibility,
|
|
332
|
+
onRowSelectionChange: onRowSelectionChange ?? setInternalRowSelection,
|
|
333
|
+
onExpandedChange: onExpandedChange ?? setInternalExpanded,
|
|
334
|
+
onColumnPinningChange: onColumnPinningChange ?? setInternalColumnPinning,
|
|
335
|
+
enableRowSelection,
|
|
325
336
|
getRowCanExpand,
|
|
326
337
|
getExpandedRowModel: getExpandedRowModel(),
|
|
327
338
|
})
|
|
@@ -3,15 +3,13 @@ export * from "./activity-feed"
|
|
|
3
3
|
export * from "./avatar"
|
|
4
4
|
export * from "./kanban"
|
|
5
5
|
export * from "./code-block"
|
|
6
|
-
export * from "./data-state"
|
|
7
|
-
export * from "./list"
|
|
8
|
-
export * from "./progress"
|
|
9
|
-
export * from "./statistic"
|
|
6
|
+
export * from "./data-state"
|
|
7
|
+
export * from "./list"
|
|
8
|
+
export * from "./progress"
|
|
10
9
|
export * from "./status-dot"
|
|
11
10
|
export * from "./status-legend"
|
|
12
11
|
export * from "./timeline"
|
|
13
12
|
export * from "./tree-view"
|
|
14
|
-
export * from "./info-card"
|
|
15
13
|
export * from "./virtual-list"
|
|
16
14
|
export * from "./qr-code"
|
|
17
15
|
export * from "./carousel"
|
|
@@ -31,6 +31,14 @@ function withAlpha(value: string, alpha: number, includeAlpha: boolean) {
|
|
|
31
31
|
return `${opaque}${channel}`
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
function getAlphaTrackStyle(value: string): React.CSSProperties {
|
|
35
|
+
const opaque = getOpaqueColor(value)
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
background: `linear-gradient(90deg, ${opaque}00 0%, ${opaque}ff 100%)`,
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
34
42
|
export type ColorPickerProps = Omit<React.ComponentProps<"div">, "defaultValue" | "onChange"> & {
|
|
35
43
|
value?: string
|
|
36
44
|
defaultValue?: string
|
|
@@ -83,6 +91,11 @@ function ColorPicker({
|
|
|
83
91
|
{label ? <div className="text-sm font-medium text-foreground">{label}</div> : null}
|
|
84
92
|
<div className="flex min-w-0 items-center gap-2">
|
|
85
93
|
<label className="relative size-10 shrink-0 overflow-hidden rounded-md border bg-background shadow-sm focus-within:ring-2 focus-within:ring-ring">
|
|
94
|
+
<span
|
|
95
|
+
aria-hidden="true"
|
|
96
|
+
className="absolute inset-0 bg-[linear-gradient(45deg,#e2e8f0_25%,transparent_25%),linear-gradient(-45deg,#e2e8f0_25%,transparent_25%),linear-gradient(45deg,transparent_75%,#e2e8f0_75%),linear-gradient(-45deg,transparent_75%,#e2e8f0_75%)] bg-[length:10px_10px] bg-[position:0_0,0_5px,5px_-5px,-5px_0]"
|
|
97
|
+
/>
|
|
98
|
+
<span aria-hidden="true" className="absolute inset-0" style={{ backgroundColor: currentValue }} />
|
|
86
99
|
<span className="sr-only">{labels?.color ?? "Choose color"}</span>
|
|
87
100
|
<input
|
|
88
101
|
type="color"
|
|
@@ -120,7 +133,8 @@ function ColorPicker({
|
|
|
120
133
|
value={getAlphaPercent(currentValue)}
|
|
121
134
|
disabled={disabled}
|
|
122
135
|
aria-label={labels?.alpha ?? "Opacity"}
|
|
123
|
-
|
|
136
|
+
style={getAlphaTrackStyle(currentValue)}
|
|
137
|
+
className="h-2 w-full cursor-pointer appearance-none rounded-full border border-border/70 outline-none focus-visible:ring-4 focus-visible:ring-ring/20 disabled:cursor-not-allowed [&::-webkit-slider-thumb]:size-4 [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-background [&::-webkit-slider-thumb]:bg-foreground [&::-webkit-slider-thumb]:shadow-sm"
|
|
124
138
|
onChange={(event) => updateValue(withAlpha(currentValue, Number(event.target.value), true))}
|
|
125
139
|
/>
|
|
126
140
|
<span className="w-10 text-right tabular-nums">{getAlphaPercent(currentValue)}%</span>
|
|
@@ -83,7 +83,7 @@ function Slider({
|
|
|
83
83
|
step={step}
|
|
84
84
|
disabled={disabled}
|
|
85
85
|
style={getSliderTrackStyle(currentValue, min, max)}
|
|
86
|
-
className="h-3 w-full cursor-pointer appearance-none rounded-full border border-[color:var(--aui-surface-border)] bg-[color:var(--aui-control-bg)] shadow-[inset_0_1px_2px_rgba(15,23,42,0.08)] outline-none transition hover:brightness-[1.02] disabled:cursor-not-allowed disabled:opacity-50 [&::-moz-range-thumb]:size-5 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:border-[3px] [&::-moz-range-thumb]:border-[color:var(--aui-page-bg)] [&::-moz-range-thumb]:bg-[color:var(--aui-brand-strong)] [&::-moz-range-thumb]:shadow-[0_8px_24px_rgba(16,185,129,0.24)] [&::-moz-range-thumb]:transition [&::-moz-range-track]:h-3 [&::-moz-range-track]:rounded-full [&::-webkit-slider-runnable-track]:h-3 [&::-webkit-slider-runnable-track]:rounded-full [&::-webkit-slider-thumb]:mt-[-5px] [&::-webkit-slider-thumb]:size-5 [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border-[3px] [&::-webkit-slider-thumb]:border-[color:var(--aui-page-bg)] [&::-webkit-slider-thumb]:bg-[color:var(--aui-brand-strong)] [&::-webkit-slider-thumb]:shadow-[0_8px_24px_rgba(16,185,129,0.24)]"
|
|
86
|
+
className="h-3 w-full cursor-pointer appearance-none rounded-full border border-[color:var(--aui-surface-border)] bg-[color:var(--aui-control-bg)] shadow-[inset_0_1px_2px_rgba(15,23,42,0.08)] outline-none transition hover:brightness-[1.02] focus-visible:ring-4 focus-visible:ring-[color:color-mix(in_oklch,var(--aui-brand-strong),transparent_78%)] disabled:cursor-not-allowed disabled:opacity-50 [&::-moz-range-thumb]:size-5 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:border-[3px] [&::-moz-range-thumb]:border-[color:var(--aui-page-bg)] [&::-moz-range-thumb]:bg-[color:var(--aui-brand-strong)] [&::-moz-range-thumb]:shadow-[0_8px_24px_rgba(16,185,129,0.24)] [&::-moz-range-thumb]:transition [&::-moz-range-track]:h-3 [&::-moz-range-track]:rounded-full [&::-webkit-slider-runnable-track]:h-3 [&::-webkit-slider-runnable-track]:rounded-full [&::-webkit-slider-thumb]:mt-[-5px] [&::-webkit-slider-thumb]:size-5 [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border-[3px] [&::-webkit-slider-thumb]:border-[color:var(--aui-page-bg)] [&::-webkit-slider-thumb]:bg-[color:var(--aui-brand-strong)] [&::-webkit-slider-thumb]:shadow-[0_8px_24px_rgba(16,185,129,0.24)] [&::-webkit-slider-thumb]:transition-transform hover:[&::-webkit-slider-thumb]:scale-105"
|
|
87
87
|
onChange={(event) => updateValue(event.currentTarget.valueAsNumber)}
|
|
88
88
|
{...props}
|
|
89
89
|
/>
|
|
@@ -170,7 +170,7 @@ function RangeSlider({
|
|
|
170
170
|
max={max}
|
|
171
171
|
step={step}
|
|
172
172
|
disabled={disabled}
|
|
173
|
-
className="pointer-events-none absolute inset-0 h-6 w-full cursor-pointer appearance-none bg-transparent outline-none disabled:cursor-not-allowed disabled:opacity-50 [&::-moz-range-thumb]:pointer-events-auto [&::-moz-range-thumb]:size-5 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:border-[3px] [&::-moz-range-thumb]:border-[color:var(--aui-page-bg)] [&::-moz-range-thumb]:bg-[color:var(--aui-brand-strong)] [&::-moz-range-thumb]:shadow-[0_8px_24px_rgba(16,185,129,0.24)] [&::-moz-range-track]:h-3 [&::-moz-range-track]:rounded-full [&::-moz-range-track]:bg-transparent [&::-webkit-slider-runnable-track]:h-3 [&::-webkit-slider-runnable-track]:rounded-full [&::-webkit-slider-runnable-track]:bg-transparent [&::-webkit-slider-thumb]:pointer-events-auto [&::-webkit-slider-thumb]:mt-[-5px] [&::-webkit-slider-thumb]:size-5 [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border-[3px] [&::-webkit-slider-thumb]:border-[color:var(--aui-page-bg)] [&::-webkit-slider-thumb]:bg-[color:var(--aui-brand-strong)] [&::-webkit-slider-thumb]:shadow-[0_8px_24px_rgba(16,185,129,0.24)]"
|
|
173
|
+
className="pointer-events-none absolute inset-0 h-6 w-full cursor-pointer appearance-none bg-transparent outline-none focus-visible:ring-4 focus-visible:ring-[color:color-mix(in_oklch,var(--aui-brand-strong),transparent_78%)] disabled:cursor-not-allowed disabled:opacity-50 [&::-moz-range-thumb]:pointer-events-auto [&::-moz-range-thumb]:size-5 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:border-[3px] [&::-moz-range-thumb]:border-[color:var(--aui-page-bg)] [&::-moz-range-thumb]:bg-[color:var(--aui-brand-strong)] [&::-moz-range-thumb]:shadow-[0_8px_24px_rgba(16,185,129,0.24)] [&::-moz-range-track]:h-3 [&::-moz-range-track]:rounded-full [&::-moz-range-track]:bg-transparent [&::-webkit-slider-runnable-track]:h-3 [&::-webkit-slider-runnable-track]:rounded-full [&::-webkit-slider-runnable-track]:bg-transparent [&::-webkit-slider-thumb]:pointer-events-auto [&::-webkit-slider-thumb]:mt-[-5px] [&::-webkit-slider-thumb]:size-5 [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border-[3px] [&::-webkit-slider-thumb]:border-[color:var(--aui-page-bg)] [&::-webkit-slider-thumb]:bg-[color:var(--aui-brand-strong)] [&::-webkit-slider-thumb]:shadow-[0_8px_24px_rgba(16,185,129,0.24)] [&::-webkit-slider-thumb]:transition-transform hover:[&::-webkit-slider-thumb]:scale-105"
|
|
174
174
|
onChange={(event) => updateValue(0, event.currentTarget.valueAsNumber)}
|
|
175
175
|
{...props}
|
|
176
176
|
/>
|
|
@@ -181,7 +181,7 @@ function RangeSlider({
|
|
|
181
181
|
max={max}
|
|
182
182
|
step={step}
|
|
183
183
|
disabled={disabled}
|
|
184
|
-
className="pointer-events-none absolute inset-0 h-6 w-full cursor-pointer appearance-none bg-transparent outline-none disabled:cursor-not-allowed disabled:opacity-50 [&::-moz-range-thumb]:pointer-events-auto [&::-moz-range-thumb]:size-5 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:border-[3px] [&::-moz-range-thumb]:border-[color:var(--aui-page-bg)] [&::-moz-range-thumb]:bg-[color:var(--aui-brand-strong)] [&::-moz-range-thumb]:shadow-[0_8px_24px_rgba(16,185,129,0.24)] [&::-moz-range-track]:h-3 [&::-moz-range-track]:rounded-full [&::-moz-range-track]:bg-transparent [&::-webkit-slider-runnable-track]:h-3 [&::-webkit-slider-runnable-track]:rounded-full [&::-webkit-slider-runnable-track]:bg-transparent [&::-webkit-slider-thumb]:pointer-events-auto [&::-webkit-slider-thumb]:mt-[-5px] [&::-webkit-slider-thumb]:size-5 [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border-[3px] [&::-webkit-slider-thumb]:border-[color:var(--aui-page-bg)] [&::-webkit-slider-thumb]:bg-[color:var(--aui-brand-strong)] [&::-webkit-slider-thumb]:shadow-[0_8px_24px_rgba(16,185,129,0.24)]"
|
|
184
|
+
className="pointer-events-none absolute inset-0 h-6 w-full cursor-pointer appearance-none bg-transparent outline-none focus-visible:ring-4 focus-visible:ring-[color:color-mix(in_oklch,var(--aui-brand-strong),transparent_78%)] disabled:cursor-not-allowed disabled:opacity-50 [&::-moz-range-thumb]:pointer-events-auto [&::-moz-range-thumb]:size-5 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:border-[3px] [&::-moz-range-thumb]:border-[color:var(--aui-page-bg)] [&::-moz-range-thumb]:bg-[color:var(--aui-brand-strong)] [&::-moz-range-thumb]:shadow-[0_8px_24px_rgba(16,185,129,0.24)] [&::-moz-range-track]:h-3 [&::-moz-range-track]:rounded-full [&::-moz-range-track]:bg-transparent [&::-webkit-slider-runnable-track]:h-3 [&::-webkit-slider-runnable-track]:rounded-full [&::-webkit-slider-runnable-track]:bg-transparent [&::-webkit-slider-thumb]:pointer-events-auto [&::-webkit-slider-thumb]:mt-[-5px] [&::-webkit-slider-thumb]:size-5 [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border-[3px] [&::-webkit-slider-thumb]:border-[color:var(--aui-page-bg)] [&::-webkit-slider-thumb]:bg-[color:var(--aui-brand-strong)] [&::-webkit-slider-thumb]:shadow-[0_8px_24px_rgba(16,185,129,0.24)] [&::-webkit-slider-thumb]:transition-transform hover:[&::-webkit-slider-thumb]:scale-105"
|
|
185
185
|
onChange={(event) => updateValue(1, event.currentTarget.valueAsNumber)}
|
|
186
186
|
{...props}
|
|
187
187
|
/>
|
|
@@ -80,13 +80,13 @@ function TagInput({
|
|
|
80
80
|
<Badge
|
|
81
81
|
key={tag}
|
|
82
82
|
variant="secondary"
|
|
83
|
-
className="h-8 gap-1 rounded-full border border-[color:var(--aui-surface-border)] bg-[color:var(--aui-page-bg)] px-3 pr-1 text-[13px] font-medium shadow-sm"
|
|
83
|
+
className="h-8 gap-1.5 rounded-full border border-[color:var(--aui-surface-border)] bg-[color:var(--aui-page-bg)] px-3 pr-1.5 text-[13px] font-medium leading-none shadow-sm"
|
|
84
84
|
>
|
|
85
|
-
{tag}
|
|
85
|
+
<span className="leading-none">{tag}</span>
|
|
86
86
|
{!readOnly && !disabled && (
|
|
87
87
|
<button
|
|
88
88
|
type="button"
|
|
89
|
-
className="
|
|
89
|
+
className="inline-flex size-5 shrink-0 items-center justify-center rounded-full p-0 leading-none text-muted-foreground transition hover:bg-[color:var(--aui-control-bg)] hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40"
|
|
90
90
|
aria-label={`Remove ${tag}`}
|
|
91
91
|
onClick={(event) => {
|
|
92
92
|
stopInteractivePropagation(event)
|
|
@@ -95,7 +95,7 @@ function TagInput({
|
|
|
95
95
|
onMouseDown={stopInteractivePropagation}
|
|
96
96
|
onDoubleClick={stopInteractivePropagation}
|
|
97
97
|
>
|
|
98
|
-
<XIcon className="size-3" strokeWidth={2} />
|
|
98
|
+
<XIcon className="size-3" strokeWidth={2.25} />
|
|
99
99
|
</button>
|
|
100
100
|
)}
|
|
101
101
|
</Badge>
|
|
@@ -1,22 +1,31 @@
|
|
|
1
|
-
import * as React from "react"
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { CalendarClockIcon, ClockIcon, XIcon } from "lucide-react"
|
|
3
|
+
|
|
4
|
+
import { cn } from "@/lib/utils"
|
|
5
|
+
|
|
6
|
+
export type TimePickerProps = Omit<React.ComponentProps<"input">, "type"> & {
|
|
7
|
+
label?: React.ReactNode
|
|
8
|
+
clearable?: boolean
|
|
9
|
+
onClear?: () => void
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export type DateTimePickerProps = Omit<React.ComponentProps<"input">, "type"> & {
|
|
13
|
+
label?: React.ReactNode
|
|
14
|
+
clearable?: boolean
|
|
15
|
+
onClear?: () => void
|
|
16
|
+
}
|
|
12
17
|
|
|
13
18
|
export type TimeRangePickerProps = React.ComponentProps<"div"> & {
|
|
14
19
|
from?: string
|
|
15
20
|
to?: string
|
|
16
21
|
onFromChange?: (value: string) => void
|
|
17
|
-
onToChange?: (value: string) => void
|
|
18
|
-
disabled?: boolean
|
|
19
|
-
|
|
22
|
+
onToChange?: (value: string) => void
|
|
23
|
+
disabled?: boolean
|
|
24
|
+
labels?: {
|
|
25
|
+
from?: React.ReactNode
|
|
26
|
+
to?: React.ReactNode
|
|
27
|
+
}
|
|
28
|
+
}
|
|
20
29
|
|
|
21
30
|
function FieldShell({ label, className, children }: { label?: React.ReactNode; className?: string; children: React.ReactNode }) {
|
|
22
31
|
return (
|
|
@@ -27,29 +36,73 @@ function FieldShell({ label, className, children }: { label?: React.ReactNode; c
|
|
|
27
36
|
)
|
|
28
37
|
}
|
|
29
38
|
|
|
30
|
-
function
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
39
|
+
function clearInput(event: React.MouseEvent<HTMLButtonElement>, onChange: React.ChangeEventHandler<HTMLInputElement> | undefined, onClear: (() => void) | undefined) {
|
|
40
|
+
event.preventDefault()
|
|
41
|
+
event.stopPropagation()
|
|
42
|
+
onChange?.({ target: { value: "" }, currentTarget: { value: "" } } as React.ChangeEvent<HTMLInputElement>)
|
|
43
|
+
onClear?.()
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function TimePicker({ label, className, clearable = false, onClear, value, defaultValue, disabled, onChange, ...props }: TimePickerProps) {
|
|
47
|
+
const hasValue = value !== undefined ? String(value).length > 0 : defaultValue !== undefined && String(defaultValue).length > 0
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<FieldShell label={label}>
|
|
51
|
+
<span className="relative grid">
|
|
52
|
+
<ClockIcon className="pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
|
|
53
|
+
<input
|
|
54
|
+
type="time"
|
|
55
|
+
value={value}
|
|
56
|
+
defaultValue={defaultValue}
|
|
57
|
+
disabled={disabled}
|
|
58
|
+
onChange={onChange}
|
|
59
|
+
className={cn("h-11 rounded-[var(--aui-control-radius,var(--radius-md))] border border-input/82 bg-background px-10 text-sm tabular-nums outline-none transition-[border-color,box-shadow] hover:border-ring/30 focus-visible:border-ring focus-visible:ring-4 focus-visible:ring-ring/16 disabled:cursor-not-allowed disabled:bg-muted disabled:text-muted-foreground", className)}
|
|
60
|
+
{...props}
|
|
61
|
+
/>
|
|
62
|
+
{clearable && hasValue && !disabled ? (
|
|
63
|
+
<button type="button" aria-label="Clear time" className="absolute right-2 top-1/2 grid size-7 -translate-y-1/2 place-items-center rounded-md text-muted-foreground hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring" onClick={(event) => clearInput(event, onChange, onClear)}>
|
|
64
|
+
<XIcon className="size-3.5" />
|
|
65
|
+
</button>
|
|
66
|
+
) : null}
|
|
67
|
+
</span>
|
|
68
|
+
</FieldShell>
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function DateTimePicker({ label, className, clearable = false, onClear, value, defaultValue, disabled, onChange, ...props }: DateTimePickerProps) {
|
|
73
|
+
const hasValue = value !== undefined ? String(value).length > 0 : defaultValue !== undefined && String(defaultValue).length > 0
|
|
74
|
+
|
|
75
|
+
return (
|
|
76
|
+
<FieldShell label={label}>
|
|
77
|
+
<span className="relative grid">
|
|
78
|
+
<CalendarClockIcon className="pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
|
|
79
|
+
<input
|
|
80
|
+
type="datetime-local"
|
|
81
|
+
value={value}
|
|
82
|
+
defaultValue={defaultValue}
|
|
83
|
+
disabled={disabled}
|
|
84
|
+
onChange={onChange}
|
|
85
|
+
className={cn("h-11 rounded-[var(--aui-control-radius,var(--radius-md))] border border-input/82 bg-background px-10 text-sm tabular-nums outline-none transition-[border-color,box-shadow] hover:border-ring/30 focus-visible:border-ring focus-visible:ring-4 focus-visible:ring-ring/16 disabled:cursor-not-allowed disabled:bg-muted disabled:text-muted-foreground", className)}
|
|
86
|
+
{...props}
|
|
87
|
+
/>
|
|
88
|
+
{clearable && hasValue && !disabled ? (
|
|
89
|
+
<button type="button" aria-label="Clear date and time" className="absolute right-2 top-1/2 grid size-7 -translate-y-1/2 place-items-center rounded-md text-muted-foreground hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring" onClick={(event) => clearInput(event, onChange, onClear)}>
|
|
90
|
+
<XIcon className="size-3.5" />
|
|
91
|
+
</button>
|
|
92
|
+
) : null}
|
|
93
|
+
</span>
|
|
94
|
+
</FieldShell>
|
|
95
|
+
)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function TimeRangePicker({ from, to, onFromChange, onToChange, disabled, labels, className, ...props }: TimeRangePickerProps) {
|
|
99
|
+
return (
|
|
100
|
+
<div data-slot="time-range-picker" className={cn("grid gap-2 sm:grid-cols-[1fr_auto_1fr] sm:items-end", className)} {...props}>
|
|
101
|
+
<TimePicker label={labels?.from} value={from} clearable disabled={disabled} onChange={(event) => onFromChange?.(event.target.value)} onClear={() => onFromChange?.("")} />
|
|
102
|
+
<span className="hidden h-11 items-center text-sm text-muted-foreground sm:inline-flex">to</span>
|
|
103
|
+
<TimePicker label={labels?.to} value={to} clearable disabled={disabled} onChange={(event) => onToChange?.(event.target.value)} onClear={() => onToChange?.("")} />
|
|
104
|
+
</div>
|
|
105
|
+
)
|
|
106
|
+
}
|
|
54
107
|
|
|
55
108
|
export { DateTimePicker, TimePicker, TimeRangePicker }
|
|
@@ -18,7 +18,7 @@ export type FileManagerItem = {
|
|
|
18
18
|
status?: React.ReactNode
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
export type FileManagerProps = React.ComponentProps<"div"> & {
|
|
21
|
+
export type FileManagerProps = Omit<React.ComponentProps<"div">, "onSelect"> & {
|
|
22
22
|
items: FileManagerItem[]
|
|
23
23
|
selectedId?: string
|
|
24
24
|
onSelect?: (item: FileManagerItem) => void
|
|
@@ -2,5 +2,7 @@ export * from "./calendar-scheduler"
|
|
|
2
2
|
export * from "./dual-list-picker"
|
|
3
3
|
export * from "./resizable-panel"
|
|
4
4
|
export * from "./rich-text-editor"
|
|
5
|
-
export * from "./image-cropper"
|
|
6
5
|
export * from "./file-manager"
|
|
6
|
+
export * from "./map"
|
|
7
|
+
export * from "./media-player"
|
|
8
|
+
export * from "./spreadsheet"
|