neba 1.3.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -7
- package/dist/components/alert/Alert.d.ts +9 -1
- package/dist/components/alert/Alert.js +1 -1
- package/dist/components/area-chart/AreaChart.d.ts +54 -0
- package/dist/components/area-chart/AreaChart.js +1 -0
- package/dist/components/area-chart/index.d.ts +2 -0
- package/dist/components/area-chart/index.js +1 -0
- package/dist/components/bar-chart/BarChart.d.ts +63 -0
- package/dist/components/bar-chart/BarChart.js +1 -0
- package/dist/components/bar-chart/index.d.ts +2 -0
- package/dist/components/bar-chart/index.js +1 -0
- package/dist/components/bottom-navigation/BottomNavigation.d.ts +111 -0
- package/dist/components/bottom-navigation/BottomNavigation.js +1 -0
- package/dist/components/bottom-navigation/index.d.ts +1 -0
- package/dist/components/bottom-navigation/index.js +1 -0
- package/dist/components/breadcrumb/Breadcrumb.d.ts +35 -2
- package/dist/components/breadcrumb/Breadcrumb.js +1 -1
- package/dist/components/button/Button.d.ts +16 -0
- package/dist/components/button/Button.js +1 -1
- package/dist/components/carousel/Carousel.d.ts +10 -4
- package/dist/components/carousel/Carousel.js +1 -1
- package/dist/components/chip/Chip.d.ts +9 -1
- package/dist/components/chip/Chip.js +1 -1
- package/dist/components/collapsible/Collapsible.d.ts +88 -0
- package/dist/components/collapsible/Collapsible.js +1 -0
- package/dist/components/collapsible/index.d.ts +1 -0
- package/dist/components/collapsible/index.js +1 -0
- package/dist/components/combobox/Combobox.d.ts +19 -7
- package/dist/components/combobox/Combobox.js +1 -1
- package/dist/components/data-table/DataTable.d.ts +323 -0
- package/dist/components/data-table/DataTable.js +1 -0
- package/dist/components/data-table/index.d.ts +2 -0
- package/dist/components/data-table/index.js +1 -0
- package/dist/components/dialog/Dialog.d.ts +11 -5
- package/dist/components/dialog/Dialog.js +1 -1
- package/dist/components/drawer/Drawer.d.ts +11 -5
- package/dist/components/drawer/Drawer.js +1 -1
- package/dist/components/empty/Empty.d.ts +69 -0
- package/dist/components/empty/Empty.js +1 -0
- package/dist/components/empty/index.d.ts +2 -0
- package/dist/components/empty/index.js +1 -0
- package/dist/components/file-picker/FilePicker.d.ts +1 -3
- package/dist/components/file-picker/FilePicker.js +1 -1
- package/dist/components/floating-action-button/FloatingActionButton.d.ts +146 -0
- package/dist/components/floating-action-button/FloatingActionButton.js +1 -0
- package/dist/components/floating-action-button/index.d.ts +1 -0
- package/dist/components/floating-action-button/index.js +1 -0
- package/dist/components/heatmap-chart/HeatmapChart.d.ts +69 -0
- package/dist/components/heatmap-chart/HeatmapChart.js +1 -0
- package/dist/components/heatmap-chart/index.d.ts +2 -0
- package/dist/components/heatmap-chart/index.js +1 -0
- package/dist/components/highlight/Highlight.js +1 -1
- package/dist/components/line-chart/LineChart.d.ts +74 -0
- package/dist/components/line-chart/LineChart.js +1 -0
- package/dist/components/line-chart/index.d.ts +2 -0
- package/dist/components/line-chart/index.js +1 -0
- package/dist/components/mockup/Mockup.d.ts +151 -0
- package/dist/components/mockup/Mockup.js +1 -0
- package/dist/components/mockup/index.d.ts +2 -0
- package/dist/components/mockup/index.js +1 -0
- package/dist/components/number-field/NumberField.d.ts +10 -6
- package/dist/components/number-field/NumberField.js +1 -1
- package/dist/components/overlay/Overlay.d.ts +11 -6
- package/dist/components/overlay/Overlay.js +1 -1
- package/dist/components/pagination/Pagination.d.ts +28 -6
- package/dist/components/pagination/Pagination.js +1 -1
- package/dist/components/panes/Panes.js +1 -1
- package/dist/components/pie-chart/PieChart.d.ts +58 -0
- package/dist/components/pie-chart/PieChart.js +1 -0
- package/dist/components/pie-chart/index.d.ts +2 -0
- package/dist/components/pie-chart/index.js +1 -0
- package/dist/components/popover/Popover.d.ts +11 -5
- package/dist/components/popover/Popover.js +1 -1
- package/dist/components/progress-box/ProgressBox.js +1 -1
- package/dist/components/progress-circular/ProgressCircular.js +1 -1
- package/dist/components/progress-linear/ProgressLinear.js +1 -1
- package/dist/components/rating/Rating.d.ts +100 -0
- package/dist/components/rating/Rating.js +1 -0
- package/dist/components/rating/index.d.ts +1 -0
- package/dist/components/rating/index.js +1 -0
- package/dist/components/scatter-chart/ScatterChart.d.ts +45 -0
- package/dist/components/scatter-chart/ScatterChart.js +1 -0
- package/dist/components/scatter-chart/index.d.ts +2 -0
- package/dist/components/scatter-chart/index.js +1 -0
- package/dist/components/select/Select.d.ts +1 -3
- package/dist/components/select/Select.js +1 -1
- package/dist/components/sparkline/Sparkline.d.ts +67 -0
- package/dist/components/sparkline/Sparkline.js +1 -0
- package/dist/components/sparkline/index.d.ts +2 -0
- package/dist/components/sparkline/index.js +1 -0
- package/dist/components/statistic/Statistic.d.ts +7 -0
- package/dist/components/statistic/Statistic.js +1 -1
- package/dist/components/table/Table.d.ts +13 -2
- package/dist/components/table/Table.js +1 -1
- package/dist/components/text-link/TextLink.js +1 -1
- package/dist/components/time-picker/TimePicker.js +1 -1
- package/dist/components/timeline-chart/TimelineChart.d.ts +44 -0
- package/dist/components/timeline-chart/TimelineChart.js +1 -0
- package/dist/components/timeline-chart/index.d.ts +2 -0
- package/dist/components/timeline-chart/index.js +1 -0
- package/dist/components/toast/Toast.d.ts +10 -2
- package/dist/components/toast/Toast.js +1 -1
- package/dist/components/tooltip/Tooltip.d.ts +2 -4
- package/dist/components/tooltip/Tooltip.js +1 -1
- package/dist/components/tree-view/TreeView.js +1 -1
- package/dist/index.d.ts +15 -0
- package/dist/index.js +1 -1
- package/dist/internal/animate.d.ts +0 -9
- package/dist/internal/animate.js +1 -1
- package/dist/internal/calendar.js +1 -1
- package/dist/internal/chart-frame.d.ts +409 -0
- package/dist/internal/chart-frame.js +1 -0
- package/dist/internal/chart-line.d.ts +44 -0
- package/dist/internal/chart-line.js +1 -0
- package/dist/internal/chart.d.ts +456 -0
- package/dist/internal/chart.js +1 -0
- package/dist/internal/data-table.d.ts +170 -0
- package/dist/internal/data-table.js +1 -0
- package/dist/internal/date.d.ts +0 -2
- package/dist/internal/date.js +1 -1
- package/dist/internal/format.d.ts +29 -0
- package/dist/internal/format.js +1 -0
- package/dist/internal/i18n.d.ts +166 -0
- package/dist/internal/i18n.js +1 -1
- package/dist/internal/icons.d.ts +2 -0
- package/dist/internal/icons.js +1 -1
- package/dist/internal/mockup.d.ts +193 -0
- package/dist/internal/mockup.js +1 -0
- package/dist/internal/picker.d.ts +2 -4
- package/dist/internal/picker.js +1 -1
- package/dist/internal/progress.d.ts +1 -3
- package/dist/styles.css +1 -1
- package/dist/tailwind.css +231 -11
- package/dist/types.d.ts +214 -0
- package/package.json +19 -15
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { NebaElevation, NebaStyleProps } from '../../types';
|
|
3
|
+
export interface CollapsibleProps extends NebaStyleProps, Omit<React.ComponentPropsWithoutRef<'div'>, 'color' | 'title' | 'onChange'> {
|
|
4
|
+
/** Whether the panel is showing. Pass it to drive the Collapsible yourself. */
|
|
5
|
+
open?: boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Where an uncontrolled Collapsible starts.
|
|
8
|
+
* @default false
|
|
9
|
+
*/
|
|
10
|
+
defaultOpen?: boolean;
|
|
11
|
+
/** Called when the trigger opens or closes the panel. */
|
|
12
|
+
onOpenChange?: (open: boolean) => void;
|
|
13
|
+
/** The heading on the trigger. */
|
|
14
|
+
title?: React.ReactNode;
|
|
15
|
+
/** A second line under the title, one step down the type scale and muted. */
|
|
16
|
+
subtitle?: React.ReactNode;
|
|
17
|
+
/** Content before the title — an icon, a status dot, a count. */
|
|
18
|
+
startIcon?: React.ReactNode;
|
|
19
|
+
/**
|
|
20
|
+
* A control pinned to the end of the header, outside the trigger.
|
|
21
|
+
*
|
|
22
|
+
* Deliberately outside it: a header that both folds and holds a switch has two
|
|
23
|
+
* things to press, and one of them cannot be nested inside the other. The same
|
|
24
|
+
* shape AccordionItem and ListItem use.
|
|
25
|
+
*/
|
|
26
|
+
action?: React.ReactNode;
|
|
27
|
+
/**
|
|
28
|
+
* Replaces the header entirely with a control of your own — a Button, a Chip,
|
|
29
|
+
* a line of text you made pressable.
|
|
30
|
+
*
|
|
31
|
+
* The element you pass *becomes* the trigger: it is handed the click handler,
|
|
32
|
+
* `aria-expanded` and the `aria-controls` pointing at the panel, so nothing
|
|
33
|
+
* has to be wired up. `title` and the slots around it are for the far commoner
|
|
34
|
+
* case of wanting the header that is already there.
|
|
35
|
+
*/
|
|
36
|
+
trigger?: React.ReactElement;
|
|
37
|
+
/**
|
|
38
|
+
* The chevron at the end of the header, turned to report the state.
|
|
39
|
+
* @default true
|
|
40
|
+
*/
|
|
41
|
+
indicator?: boolean;
|
|
42
|
+
/** Unavailable. The trigger stops answering and the panel stays as it is. */
|
|
43
|
+
disabled?: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Inner padding around the panel's content. Turn it off for something that
|
|
46
|
+
* should reach the edges — a table, a picture, a list of its own.
|
|
47
|
+
* @default true
|
|
48
|
+
*/
|
|
49
|
+
padded?: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Drop shadow depth. `0` (the default) is flat.
|
|
52
|
+
* @default 0
|
|
53
|
+
*/
|
|
54
|
+
elevation?: NebaElevation;
|
|
55
|
+
/**
|
|
56
|
+
* Keeps a closed panel in the DOM so the browser's own page search can find
|
|
57
|
+
* and open it. Overrides `keepMounted`.
|
|
58
|
+
* @default false
|
|
59
|
+
*/
|
|
60
|
+
hiddenUntilFound?: boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Keeps a closed panel in the DOM. For content that is expensive to build, or
|
|
63
|
+
* that holds form state which should survive being folded away.
|
|
64
|
+
* @default false
|
|
65
|
+
*/
|
|
66
|
+
keepMounted?: boolean;
|
|
67
|
+
/** The body. */
|
|
68
|
+
children?: React.ReactNode;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* One section that folds, standing on its own.
|
|
72
|
+
*
|
|
73
|
+
* An [Accordion] is a *set* of these and owns which one of them is open; this is
|
|
74
|
+
* the same fold with nothing else beside it, so what it needs is an `open` of
|
|
75
|
+
* its own rather than a place in somebody's list. Reach for it for a "Show more"
|
|
76
|
+
* on a form, an optional block of settings, the details under a row.
|
|
77
|
+
*
|
|
78
|
+
* Base UI owns the parts that are genuinely hard: the `button` / panel pairing
|
|
79
|
+
* and the `aria-controls` / `aria-expanded` wiring between them, `hidden="until
|
|
80
|
+
* -found"`, and measuring the panel so it has a height to animate from.
|
|
81
|
+
*
|
|
82
|
+
* The panel's height *is* animated, which looks like an exception to the rule
|
|
83
|
+
* against moving things and is not: nothing is transformed, no text is
|
|
84
|
+
* resampled, and the content does not shift relative to the panel it is in —
|
|
85
|
+
* the panel is a window opening onto it. Content that appears instantly is a
|
|
86
|
+
* page that jumps, which is the failure the rule exists to prevent.
|
|
87
|
+
*/
|
|
88
|
+
export declare const Collapsible: React.ForwardRefExoticComponent<CollapsibleProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as e,jsxs as n}from"react/jsx-runtime";import*as a from"react";import{Collapsible as t}from"@base-ui/react/collapsible";import{boxPaddingXClasses as l,boxPaddingYClasses as i}from"../box/Box";import{ChevronIcon as r}from"../../internal/icons";import{gapClasses as o,hasContent as s,iconClasses as d,metaTextClasses as c,radiusClasses as p,sheetBodyClasses as f,sheetHeaderGapClasses as m,sheetTitleClasses as b,surfaceClasses as h,surfaceSlots as u,transitionClasses as x}from"../../internal/styles";const g={solid:[h,"text-(--neba-fg) bg-(--n-panel-hover)","[box-shadow:var(--n-elev),var(--neba-plate-solid)]"].join(" "),outline:[h,"border text-(--neba-fg) bg-(--n-panel)","[border-color:var(--n-line)]","[box-shadow:var(--n-elev),var(--neba-plate-glass)]"].join(" "),text:"text-(--neba-fg) bg-transparent"};export const Collapsible=a.forwardRef(function({variant:a="outline",size:h="md",color:v="primary",density:N="default",elevation:j=0,open:w,defaultOpen:y=!1,onOpenChange:_,title:k,subtitle:C,startIcon:O,action:$,trigger:B,indicator:F=!0,disabled:M=!1,padded:R=!0,hiddenUntilFound:T=!1,keepMounted:U=!1,className:z,style:I,children:P,...q},A){const D=l[N][h],E=i[N][h];return n(t.Root,{ref:A,open:w,defaultOpen:y,onOpenChange:e=>_?.(e),disabled:M,className:["flex flex-col overflow-hidden",p[h],g[a],x,z??""].filter(Boolean).join(" "),style:{...u(v,j),...I},...q,children:[B?e(t.Trigger,{render:B}):n("div",{className:"flex w-full items-center",children:[n(t.Trigger,{className:["flex min-w-0 flex-1 cursor-pointer items-center text-start",D,E,o[h],x,d,"focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:[outline-offset:-2px]","hover:bg-(--n-soft)","data-[panel-open]:text-(--n-accent)","disabled:cursor-not-allowed disabled:bg-transparent disabled:text-(--neba-disabled-fg)"].join(" "),children:[s(O)?e("span",{className:"flex h-[1lh] shrink-0 items-center text-(--neba-muted-fg)",children:O}):null,n("span",{className:`flex min-w-0 flex-1 flex-col ${m[h]}`,children:[s(k)?e("span",{className:`truncate font-semibold ${b[h]}`,children:k}):null,s(C)?e("span",{className:`truncate text-(--neba-muted-fg) ${c[h]}`,children:C}):null]}),F?e("span",{className:["flex h-[1lh] shrink-0 items-center text-(--neba-muted-fg)","[transition:rotate_var(--neba-duration)_var(--neba-ease)]","data-[panel-open]:rotate-180"].join(" "),children:e(r,{})}):null]}),s($)?e("span",{className:`flex shrink-0 items-center ${D}`,children:$}):null]}),e(t.Panel,{hiddenUntilFound:T,keepMounted:U,className:["h-(--collapsible-panel-height) overflow-hidden","[transition:height_var(--neba-duration)_var(--neba-ease)]","motion-reduce:[transition-duration:0ms]","data-[starting-style]:h-0 data-[ending-style]:h-0"].join(" "),children:e("div",{className:["min-w-0 text-(--neba-muted-fg)",f[h],R?D:"",R?B?E:"compact"===N?"pb-2":"pb-4":""].filter(Boolean).join(" "),children:P})})]})});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Collapsible';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export*from"./Collapsible";
|
|
@@ -25,7 +25,7 @@ export interface ComboboxOption {
|
|
|
25
25
|
}
|
|
26
26
|
/** One value, or an array of them, depending on `multiple`. */
|
|
27
27
|
type Selection<Multiple extends boolean | undefined> = Multiple extends true ? ComboboxValue[] : ComboboxValue | null;
|
|
28
|
-
export interface ComboboxProps<Multiple extends boolean | undefined = false> extends NebaStyleProps {
|
|
28
|
+
export interface ComboboxProps<Multiple extends boolean | undefined = false> extends NebaStyleProps, Omit<React.ComponentPropsWithoutRef<'div'>, 'color' | 'defaultValue' | 'children'> {
|
|
29
29
|
/**
|
|
30
30
|
* The options, as data — the same shape Select takes, and for the same
|
|
31
31
|
* reason: what a caller has is almost always an array already.
|
|
@@ -62,7 +62,18 @@ export interface ComboboxProps<Multiple extends boolean | undefined = false> ext
|
|
|
62
62
|
* @default false
|
|
63
63
|
*/
|
|
64
64
|
clearable?: boolean;
|
|
65
|
-
/**
|
|
65
|
+
/**
|
|
66
|
+
* Which language the combobox writes its own words in — a BCP 47 tag such as `ko`, `pt-BR` or
|
|
67
|
+
* `zh-Hant`. Unsupported tags fall back to English.
|
|
68
|
+
*
|
|
69
|
+
* The strings below write the words out instead; this is for the far more
|
|
70
|
+
* common case where the page already knows its own language.
|
|
71
|
+
*/
|
|
72
|
+
locale?: string;
|
|
73
|
+
/**
|
|
74
|
+
* Shown in the popup when nothing matches and no value may be added. Defaults
|
|
75
|
+
* to the `locale`'s wording.
|
|
76
|
+
*/
|
|
66
77
|
emptyMessage?: React.ReactNode;
|
|
67
78
|
/** The most rows the list will show at once. `-1` is all of them. @default -1 */
|
|
68
79
|
limit?: number;
|
|
@@ -99,15 +110,16 @@ export interface ComboboxProps<Multiple extends boolean | undefined = false> ext
|
|
|
99
110
|
/** Whether the popup starts open. */
|
|
100
111
|
defaultOpen?: boolean;
|
|
101
112
|
onOpenChange?: (open: boolean) => void;
|
|
102
|
-
/** Accessible name of the clear button. */
|
|
113
|
+
/** Accessible name of the clear button. Defaults to the `locale`'s word. */
|
|
103
114
|
clearLabel?: string;
|
|
104
|
-
/**
|
|
115
|
+
/**
|
|
116
|
+
* Accessible name of a chip's remove button. Receives the chip's label, and
|
|
117
|
+
* defaults to the `locale`'s wording.
|
|
118
|
+
*/
|
|
105
119
|
removeLabel?: (label: string) => string;
|
|
106
120
|
/** A ref to the text input the user types into. */
|
|
107
121
|
inputRef?: React.Ref<HTMLInputElement>;
|
|
108
122
|
id?: string;
|
|
109
|
-
className?: string;
|
|
110
|
-
style?: React.CSSProperties;
|
|
111
123
|
}
|
|
112
124
|
/**
|
|
113
125
|
* A field you can type into and also choose from.
|
|
@@ -127,5 +139,5 @@ export interface ComboboxProps<Multiple extends boolean | undefined = false> ext
|
|
|
127
139
|
* navigation across both the list and the chips, and the hidden input that
|
|
128
140
|
* makes the whole thing submit with a form.
|
|
129
141
|
*/
|
|
130
|
-
export declare function Combobox<Multiple extends boolean | undefined = false>({ variant, size, color, density, elevation, items, multiple, value, defaultValue, onValueChange, onInputValueChange, allowCustom, customLabel, clearable, emptyMessage, limit, placeholder, label, description, error, invalid, startIcon, fullWidth, disabled, readOnly, required, name, open, defaultOpen, onOpenChange, clearLabel, removeLabel, inputRef, id, className, style }: ComboboxProps<Multiple>): React.JSX.Element;
|
|
142
|
+
export declare function Combobox<Multiple extends boolean | undefined = false>({ variant, size, color, density, elevation, items, multiple, value, defaultValue, onValueChange, onInputValueChange, allowCustom, customLabel, clearable, locale, emptyMessage, limit, placeholder, label, description, error, invalid, startIcon, fullWidth, disabled, readOnly, required, name, open, defaultOpen, onOpenChange, clearLabel, removeLabel, inputRef, id, className, style, ...props }: ComboboxProps<Multiple>): React.JSX.Element;
|
|
131
143
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as e,jsxs as a}from"react/jsx-runtime";import*as l from"react";import{Combobox as n}from"@base-ui/react/combobox";import{Field as t}from"@base-ui/react/field";import{Chip as i}from"../chip/Chip";import{
|
|
1
|
+
import{jsx as e,jsxs as a}from"react/jsx-runtime";import*as l from"react";import{Combobox as n}from"@base-ui/react/combobox";import{Field as t}from"@base-ui/react/field";import{Chip as i}from"../chip/Chip";import{fillMessage as r,useMessages as o}from"../../internal/i18n";import{CheckIcon as s,ChevronIcon as c,CloseIcon as d,PlusIcon as m}from"../../internal/icons";import{chipRemoveClasses as u,controlHeightClasses as p,controlTextLeadingClasses as b,disabledClasses as h,fieldReadOnlyClasses as f,fieldRestClasses as g,focusWithinRingClasses as x,gapClasses as v,hasContent as y,iconClasses as w,metaTextClasses as N,paddingXClasses as C,radiusClasses as j,stackGapClasses as L,surfaceClasses as I,surfaceSlots as S,transitionClasses as $}from"../../internal/styles";const O=["group relative flex w-full cursor-text items-center","[-webkit-tap-highlight-color:transparent]",$,"focus-within:[transition-duration:0ms]",x,w].join(" "),V={xs:"min-h-5.5 py-0",sm:"min-h-6.5 py-[2px]",md:"min-h-8 py-[3px]",lg:"min-h-10 py-[4px]",xl:"min-h-12 py-[4px]"},_=[I,"max-h-[min(20rem,var(--available-height))] overflow-y-auto overscroll-contain","w-[var(--anchor-width)] border bg-(--n-panel-press) p-1","[border-color:var(--n-line)]","[box-shadow:var(--neba-shadow-3),var(--neba-plate-glass)]","[outline:none]"].join(" "),z=["relative flex cursor-pointer items-center gap-2 select-none","rounded-(--neba-radius-xs) py-1.5 pe-2 ps-7",$,"data-[highlighted]:bg-(--n-soft-hover) data-[highlighted]:text-(--n-accent)","data-[selected]:text-(--n-accent) data-[selected]:font-medium","data-[disabled]:cursor-not-allowed data-[disabled]:text-(--neba-disabled-fg)","[outline:none]"].join(" "),A=["inline-flex h-[1lh] shrink-0 cursor-pointer items-center justify-center","rounded-(--neba-radius-xs) text-(--neba-muted-fg)","[transition:color_var(--neba-duration)_var(--neba-ease)]","hover:text-(--n-accent)","focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:outline-offset-1","disabled:cursor-not-allowed disabled:text-(--neba-disabled-fg)"].join(" ");function M(e){return null==e?[]:Array.isArray(e)?e.slice():[e]}export function Combobox({variant:x="outline",size:w="md",color:I="primary",density:$="default",elevation:k=0,items:R,multiple:T,value:q,defaultValue:E,onValueChange:F,onInputValueChange:P,allowCustom:B=!0,customLabel:D,clearable:G=!1,locale:H,emptyMessage:W,limit:J,placeholder:K,label:Q,description:U,error:X,invalid:Y,startIcon:Z,fullWidth:ee=!1,disabled:ae=!1,readOnly:le=!1,required:ne=!1,name:te,open:ie,defaultOpen:re,onOpenChange:oe,clearLabel:se,removeLabel:ce,inputRef:de,id:me,className:ue,style:pe,...be}){const he=o(H),fe=ce??(e=>r(he.combobox.remove,{label:e})),ge=y(X),xe=Y??ge,ve=xe?"danger":I,ye=!0===T,we=l.useMemo(()=>R.map(e=>({value:e.value,label:e.label??String(e.value),disabled:e.disabled})),[R]),[Ne,Ce]=l.useState(()=>M(E)),je=void 0===q?Ne:M(q),[Le,Ie]=l.useState(""),Se=l.useMemo(()=>new Map(we.map(e=>[e.value,e])),[we]),$e=l.useCallback(e=>Se.get(e)??{value:e,label:String(e),custom:!0},[Se]),Oe=Le.trim(),Ve=Oe.toLocaleLowerCase(),_e=""===Oe||we.some(e=>e.label.toLocaleLowerCase()===Ve||String(e.value).toLocaleLowerCase()===Ve)||je.some(e=>String(e).toLocaleLowerCase()===Ve),ze=!B||le||ae||_e?null:Oe,Ae=l.useMemo(()=>null===ze?we:[...we,{value:ze,label:ze,custom:!0}],[we,ze]),Me=ye?je.map($e):je.length>0?$e(je[0]):null;const ke=C[$][w],Re=[O,b[w],j[w],v[w],ye?V[w]:p[w],`${ke} pe-1.5`,ae?h[x]:le?f[x]:g[x]].join(" "),Te=["min-w-0 flex-1 self-stretch bg-transparent [font:inherit] text-inherit","[outline:none]","placeholder:text-(--neba-muted-fg)","caret-(--n-accent) selection:bg-(--n-soft-press)","disabled:cursor-not-allowed"].join(" "),qe=a=>e(n.Input,{ref:de,placeholder:K,className:ye?`${Te} min-w-16 ${a?"ms-1.5":""}`:Te});return a(t.Root,{disabled:ae,invalid:xe,className:["flex-col align-top",L[w],ee?"flex w-full":"inline-flex",ue??""].filter(Boolean).join(" "),style:{...S(ve,k),...pe},...be,children:[Q?e(t.Label,{className:[N[w],"font-medium",ae?"text-(--neba-disabled-fg)":"text-(--neba-fg)"].join(" "),children:Q}):null,a(n.Root,{id:me,name:te,items:Ae,multiple:ye,value:Me,onValueChange:e=>{!function(e){void 0===q&&Ce(e),F?.(ye?e:e[0]??null)}((null===e?[]:Array.isArray(e)?e:[e]).map(e=>e.value))},onInputValueChange:e=>{Ie(e),P?.(e)},open:ie,defaultOpen:re,onOpenChange:e=>oe?.(e),autoHighlight:!0,itemToStringLabel:e=>e.label,itemToStringValue:e=>String(e.value),isItemEqualToValue:(e,a)=>e.value===a.value,limit:J,disabled:ae,readOnly:le,required:ne,children:[a(n.InputGroup,{className:Re,children:[Z?e("span",{className:"flex h-[1lh] shrink-0 items-center text-(--neba-muted-fg)",children:Z}):null,ye?e(n.Chips,{className:"flex min-w-0 flex-1 flex-wrap items-center gap-1",children:e(n.Value,{children:t=>a(l.Fragment,{children:[t.map(a=>e(n.Chip,{render:e(i,{variant:"outline",size:w,color:ve,density:"compact",disabled:ae,endIcon:le||ae?null:e(n.ChipRemove,{"aria-label":fe(a.label),className:u,children:e(d,{})})}),children:a.label},String(a.value))),qe(t.length>0)]})})}):qe(!1),G&&!le?e(n.Clear,{"aria-label":se??he.action.clear,className:A,children:e(d,{})}):null,e(n.Trigger,{"aria-label":"string"==typeof Q?void 0:"Open",className:A,children:e(n.Icon,{className:["flex items-center","[transition:rotate_var(--neba-duration)_var(--neba-ease)]","data-[popup-open]:rotate-180"].join(" "),children:e(c,{})})})]}),e(n.Portal,{children:e(n.Positioner,{className:"neba-portal z-50 [outline:none]",sideOffset:6,children:a(n.Popup,{className:`${_} ${j[w]} ${b[w]}`,style:S(ve,3),children:[e(n.Empty,{className:"px-2 py-1.5 text-(--neba-muted-fg) empty:hidden",children:W??he.combobox.empty}),e(n.List,{children:t=>e(n.Item,{value:t,disabled:t.disabled,className:z,children:t.custom?a(l.Fragment,{children:[e("span",{className:"absolute start-1.5 flex size-4 items-center justify-center text-(--n-accent) [&_svg]:size-4",children:e(m,{})}),e("span",{className:"truncate",children:D?D(t.label):`Add “${t.label}”`})]}):a(l.Fragment,{children:[e(n.ItemIndicator,{className:"absolute start-1.5 flex size-4 items-center justify-center",children:e(s,{})}),e("span",{className:"truncate",children:t.label})]})},`${t.custom?"custom:":""}${String(t.value)}`)})]})})})]}),U?e(t.Description,{className:`${N[w]} text-(--neba-muted-fg)`,children:U}):null,ge?e(t.Error,{match:!0,className:`${N[w]} text-(--n-accent)`,children:X}):null]})}
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { NebaAlign, NebaElevation, NebaStyleProps } from '../../types';
|
|
3
|
+
/** Which way a column runs when it is sorted. */
|
|
4
|
+
export type DataTableSortDirection = 'asc' | 'desc';
|
|
5
|
+
/** One key of the sort, and its direction. A sort is a list of these. */
|
|
6
|
+
export interface DataTableSort {
|
|
7
|
+
/** The column's `key`. */
|
|
8
|
+
key: string;
|
|
9
|
+
direction: DataTableSortDirection;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* How many rows may be chosen at once.
|
|
13
|
+
*
|
|
14
|
+
* `none` is the default: a table that highlights a row under the pointer but
|
|
15
|
+
* cannot be selected is a table that has promised something it does not do.
|
|
16
|
+
*/
|
|
17
|
+
export type DataTableSelectionMode = 'none' | 'single' | 'multiple';
|
|
18
|
+
/**
|
|
19
|
+
* Which rows carry the tint, counted the way a reader counts them — `odd` is
|
|
20
|
+
* the first, the third and the fifth.
|
|
21
|
+
*/
|
|
22
|
+
export type DataTableStripe = 'odd' | 'even';
|
|
23
|
+
/**
|
|
24
|
+
* How the rows are handed out.
|
|
25
|
+
*
|
|
26
|
+
* - `scroll` — all of them, in one scrolling body. With a `height` set this is
|
|
27
|
+
* the virtualized mode, and the one to reach for at any size.
|
|
28
|
+
* - `pages` — a slice at a time, with a footer to step through them. Right when
|
|
29
|
+
* the row's position in the whole set is information (a ledger, a log), and
|
|
30
|
+
* the only option when the rows are being fetched a page at a time.
|
|
31
|
+
*/
|
|
32
|
+
export type DataTablePaging = 'scroll' | 'pages';
|
|
33
|
+
/** The three things the table does to the rows before drawing them. */
|
|
34
|
+
export type DataTableStage = 'sort' | 'filter' | 'pages';
|
|
35
|
+
/**
|
|
36
|
+
* A column: its heading, how wide it is, how to get a value out of a row and
|
|
37
|
+
* how to draw one.
|
|
38
|
+
*
|
|
39
|
+
* The split between `value` and `render` is the whole shape of this type. A
|
|
40
|
+
* `render` decides what a reader sees; a `value` decides what the sort and the
|
|
41
|
+
* search see. Most columns need neither — the cell is `row[key]` and that is
|
|
42
|
+
* what is compared and matched. A column that draws a Chip needs `render`, and
|
|
43
|
+
* it needs `value` as well the moment it is sortable, because a React element
|
|
44
|
+
* has no order.
|
|
45
|
+
*/
|
|
46
|
+
export interface DataTableColumn<Row> {
|
|
47
|
+
/**
|
|
48
|
+
* Identifies the column — to `sort`, to `columnWidths`, and unless `value` or
|
|
49
|
+
* `render` says otherwise, it names the property to read off each row.
|
|
50
|
+
*/
|
|
51
|
+
key: string;
|
|
52
|
+
/** The heading. Defaults to the `key`, which is usually not what you want. */
|
|
53
|
+
label?: React.ReactNode;
|
|
54
|
+
/**
|
|
55
|
+
* The heading above this column and its neighbours.
|
|
56
|
+
*
|
|
57
|
+
* Adjacent columns carrying the same string are drawn under one merged cell
|
|
58
|
+
* in a second header row; a column with no `group` spans both rows. Merging
|
|
59
|
+
* by adjacency rather than by a separate model is deliberate — a group is a
|
|
60
|
+
* run of columns, and a table where "Address" covers columns 2, 5 and 9 is a
|
|
61
|
+
* table whose columns are in the wrong order.
|
|
62
|
+
*/
|
|
63
|
+
group?: string;
|
|
64
|
+
/**
|
|
65
|
+
* How wide, in pixels. Columns that do not say share whatever is left.
|
|
66
|
+
*
|
|
67
|
+
* Pixels rather than any CSS length, because the width is a number the resize
|
|
68
|
+
* drag does arithmetic on. A column that has been dragged keeps the dragged
|
|
69
|
+
* width until it is double-clicked.
|
|
70
|
+
*/
|
|
71
|
+
width?: number;
|
|
72
|
+
/** How narrow a drag may make it. @default 48 */
|
|
73
|
+
minWidth?: number;
|
|
74
|
+
/**
|
|
75
|
+
* Which edge the cells line up against. Numbers want `end` so their digits
|
|
76
|
+
* line up in a column.
|
|
77
|
+
* @default 'start'
|
|
78
|
+
*/
|
|
79
|
+
align?: NebaAlign;
|
|
80
|
+
/** The heading's own alignment, when it should differ from the cells'. */
|
|
81
|
+
headerAlign?: NebaAlign;
|
|
82
|
+
/** Whether this column can be sorted. Defaults to the table's `sortable`. */
|
|
83
|
+
sortable?: boolean;
|
|
84
|
+
/** Whether this column can be dragged wider. Defaults to `resizable`. */
|
|
85
|
+
resizable?: boolean;
|
|
86
|
+
/**
|
|
87
|
+
* Whether the search looks in this column.
|
|
88
|
+
* @default true
|
|
89
|
+
*/
|
|
90
|
+
searchable?: boolean;
|
|
91
|
+
/** Leaves the column out without removing it from the list. */
|
|
92
|
+
hidden?: boolean;
|
|
93
|
+
/**
|
|
94
|
+
* The value behind the cell: what is sorted, and what the search is matched
|
|
95
|
+
* against. Defaults to `row[key]`.
|
|
96
|
+
*/
|
|
97
|
+
value?: (row: Row) => unknown;
|
|
98
|
+
/**
|
|
99
|
+
* Orders two rows by this column, for a value the default comparison cannot
|
|
100
|
+
* rank — a status that goes `draft`, `review`, `live` rather than
|
|
101
|
+
* alphabetically. Always written ascending; the table reverses it.
|
|
102
|
+
*/
|
|
103
|
+
compare?: (a: Row, b: Row) => number;
|
|
104
|
+
/**
|
|
105
|
+
* Draws the cell. `index` is the row's place in the sorted, filtered order,
|
|
106
|
+
* counted from `0` across every page — so `(row, index) => index + 1` is a
|
|
107
|
+
* running row number.
|
|
108
|
+
*/
|
|
109
|
+
render?: (row: Row, index: number) => React.ReactNode;
|
|
110
|
+
}
|
|
111
|
+
export interface DataTableProps<Row> extends NebaStyleProps, Omit<React.ComponentPropsWithoutRef<'div'>, 'color' | 'children' | 'onSelect' | 'defaultValue'> {
|
|
112
|
+
/** The columns, in the order they appear. */
|
|
113
|
+
headers: readonly DataTableColumn<Row>[];
|
|
114
|
+
/** The rows. */
|
|
115
|
+
items: readonly Row[];
|
|
116
|
+
/**
|
|
117
|
+
* A stable identity per row, and the value `selected` is a list of.
|
|
118
|
+
*
|
|
119
|
+
* Defaults to the row's index in `items`, which is enough for a table that
|
|
120
|
+
* only ever displays. The moment rows can be chosen, sorted or filtered it is
|
|
121
|
+
* required in practice: an index identifies a position, and every one of
|
|
122
|
+
* those three changes which row is in it.
|
|
123
|
+
*/
|
|
124
|
+
getRowKey?: (row: Row, index: number) => React.Key;
|
|
125
|
+
/**
|
|
126
|
+
* Drop shadow depth. `0` (the default) is flat.
|
|
127
|
+
* @default 0
|
|
128
|
+
*/
|
|
129
|
+
elevation?: NebaElevation;
|
|
130
|
+
/**
|
|
131
|
+
* How tall the scrolling body is — a number is pixels, a string any CSS
|
|
132
|
+
* length. **This is what turns virtual scrolling on**: rows can only be left
|
|
133
|
+
* out of the DOM if something bounds the height they would have taken.
|
|
134
|
+
*/
|
|
135
|
+
height?: number | string;
|
|
136
|
+
/** The same, as a ceiling: the table is as tall as its rows, up to this. */
|
|
137
|
+
maxHeight?: number | string;
|
|
138
|
+
/**
|
|
139
|
+
* How tall one row is, in pixels. Defaults to the `size`/`density` ladder.
|
|
140
|
+
*
|
|
141
|
+
* Every row is this tall and cells never wrap — which is what makes the
|
|
142
|
+
* scroll position arithmetic rather than a measurement. Raise it for a table
|
|
143
|
+
* whose cells hold an Avatar or two lines of text.
|
|
144
|
+
*/
|
|
145
|
+
rowHeight?: number;
|
|
146
|
+
/**
|
|
147
|
+
* Tints every other row. `true` means `even` — the second, the fourth, the
|
|
148
|
+
* sixth — and the parity is counted over the whole set, so it does not change
|
|
149
|
+
* when the rows are scrolled or sorted.
|
|
150
|
+
* @default false
|
|
151
|
+
*/
|
|
152
|
+
striped?: boolean | DataTableStripe;
|
|
153
|
+
/**
|
|
154
|
+
* Lights the row under the pointer.
|
|
155
|
+
* @default true
|
|
156
|
+
*/
|
|
157
|
+
hoverable?: boolean;
|
|
158
|
+
/**
|
|
159
|
+
* Pins the header while the body scrolls.
|
|
160
|
+
* @default true
|
|
161
|
+
*/
|
|
162
|
+
stickyHeader?: boolean;
|
|
163
|
+
/** Shown above the table, and read out as its accessible name. */
|
|
164
|
+
caption?: React.ReactNode;
|
|
165
|
+
/** The name the grid is announced by, when there is no `caption`. */
|
|
166
|
+
label?: string;
|
|
167
|
+
/** What to show instead of rows when there are none. */
|
|
168
|
+
empty?: React.ReactNode;
|
|
169
|
+
/**
|
|
170
|
+
* Leaves the rows that are off screen out of the DOM. Needs a `height` or a
|
|
171
|
+
* `maxHeight` to have anything to measure against; without one every row is
|
|
172
|
+
* rendered whatever this says.
|
|
173
|
+
* @default true
|
|
174
|
+
*/
|
|
175
|
+
virtual?: boolean;
|
|
176
|
+
/**
|
|
177
|
+
* How many rows are kept rendered past each edge of the viewport, so a fast
|
|
178
|
+
* scroll does not show a band of nothing.
|
|
179
|
+
* @default 8
|
|
180
|
+
*/
|
|
181
|
+
overscan?: number;
|
|
182
|
+
/**
|
|
183
|
+
* Makes every column sortable. A column overrides it either way with its own
|
|
184
|
+
* `sortable`.
|
|
185
|
+
* @default false
|
|
186
|
+
*/
|
|
187
|
+
sortable?: boolean;
|
|
188
|
+
/**
|
|
189
|
+
* Whether more than one column can be sorted at a time. With `multiple`, a
|
|
190
|
+
* Shift-click adds a column to the sort instead of replacing it.
|
|
191
|
+
* @default 'single'
|
|
192
|
+
*/
|
|
193
|
+
sortMode?: 'single' | 'multiple';
|
|
194
|
+
/** The sort. Use with `onSortChange` for a controlled one. */
|
|
195
|
+
sort?: readonly DataTableSort[];
|
|
196
|
+
/** What it starts as, for an uncontrolled one. */
|
|
197
|
+
defaultSort?: readonly DataTableSort[];
|
|
198
|
+
onSortChange?: (sort: DataTableSort[]) => void;
|
|
199
|
+
/**
|
|
200
|
+
* Lets the headers be dragged wider or narrower. A double-click on the handle
|
|
201
|
+
* gives the column its original width back.
|
|
202
|
+
* @default false
|
|
203
|
+
*/
|
|
204
|
+
resizable?: boolean;
|
|
205
|
+
/** The widths, keyed by column. Use with `onColumnWidthsChange`. */
|
|
206
|
+
columnWidths?: Readonly<Record<string, number>>;
|
|
207
|
+
/** What they start as, for an uncontrolled table. */
|
|
208
|
+
defaultColumnWidths?: Readonly<Record<string, number>>;
|
|
209
|
+
onColumnWidthsChange?: (widths: Record<string, number>) => void;
|
|
210
|
+
/**
|
|
211
|
+
* How many rows may be chosen.
|
|
212
|
+
* @default 'none'
|
|
213
|
+
*/
|
|
214
|
+
selectionMode?: DataTableSelectionMode;
|
|
215
|
+
/** The chosen rows, as their keys. Use with `onSelectedChange`. */
|
|
216
|
+
selected?: readonly React.Key[];
|
|
217
|
+
/** Which start chosen, for an uncontrolled table. */
|
|
218
|
+
defaultSelected?: readonly React.Key[];
|
|
219
|
+
/** The keys, and the rows behind them — including rows on other pages. */
|
|
220
|
+
onSelectedChange?: (selected: React.Key[], rows: Row[]) => void;
|
|
221
|
+
/**
|
|
222
|
+
* Adds a column of ticks, and one in the header that chooses every displayed
|
|
223
|
+
* row at once. The rows stay clickable either way; this is for a table where
|
|
224
|
+
* choosing is the task rather than something done on the way past.
|
|
225
|
+
* @default false
|
|
226
|
+
*/
|
|
227
|
+
checkboxes?: boolean;
|
|
228
|
+
/** Fires on every press of a row, before the selection changes. */
|
|
229
|
+
onRowClick?: (row: Row, index: number, event: React.MouseEvent<HTMLTableRowElement>) => void;
|
|
230
|
+
/** Fires on a double-click, and on Enter. Opening the row is what this is. */
|
|
231
|
+
onRowActivate?: (row: Row, index: number) => void;
|
|
232
|
+
/**
|
|
233
|
+
* Whether the rows arrive all at once or a page at a time.
|
|
234
|
+
* @default 'scroll'
|
|
235
|
+
*/
|
|
236
|
+
paging?: DataTablePaging;
|
|
237
|
+
/** The current page, 1-based. Use with `onPageChange`. */
|
|
238
|
+
page?: number;
|
|
239
|
+
/** @default 1 */
|
|
240
|
+
defaultPage?: number;
|
|
241
|
+
onPageChange?: (page: number) => void;
|
|
242
|
+
/** How many rows a page holds. Use with `onPageSizeChange`. */
|
|
243
|
+
pageSize?: number;
|
|
244
|
+
/** @default 25 */
|
|
245
|
+
defaultPageSize?: number;
|
|
246
|
+
onPageSizeChange?: (pageSize: number) => void;
|
|
247
|
+
/**
|
|
248
|
+
* What the footer's page-size Select offers. An empty list drops the control.
|
|
249
|
+
* @default [10, 25, 50, 100]
|
|
250
|
+
*/
|
|
251
|
+
pageSizeOptions?: readonly number[];
|
|
252
|
+
/**
|
|
253
|
+
* The bar under the table: how many rows there are, how many are chosen, and
|
|
254
|
+
* the pages. On by default whenever `paging` is `pages`.
|
|
255
|
+
*/
|
|
256
|
+
footer?: boolean;
|
|
257
|
+
/**
|
|
258
|
+
* The query every searchable column is matched against. Use with
|
|
259
|
+
* `onSearchChange` for a controlled field.
|
|
260
|
+
*/
|
|
261
|
+
search?: string;
|
|
262
|
+
/** What it starts as, for an uncontrolled one. */
|
|
263
|
+
defaultSearch?: string;
|
|
264
|
+
onSearchChange?: (search: string) => void;
|
|
265
|
+
/** Draws the search field above the table. @default false */
|
|
266
|
+
searchable?: boolean;
|
|
267
|
+
/** Overrides the field's placeholder and its accessible name. */
|
|
268
|
+
searchPlaceholder?: string;
|
|
269
|
+
/**
|
|
270
|
+
* A filter of your own, applied after the search. Return `false` to drop a
|
|
271
|
+
* row.
|
|
272
|
+
*/
|
|
273
|
+
filter?: (row: Row, index: number) => boolean;
|
|
274
|
+
/** Content at the end of the bar the search field sits in. */
|
|
275
|
+
toolbar?: React.ReactNode;
|
|
276
|
+
/**
|
|
277
|
+
* Which stages the caller has already done — for a table whose rows come from
|
|
278
|
+
* a server a page at a time. `true` is all three.
|
|
279
|
+
*
|
|
280
|
+
* With `pages` in the list, `items` is taken to be one page and `rowCount`
|
|
281
|
+
* says how many rows there are in total.
|
|
282
|
+
* @default false
|
|
283
|
+
*/
|
|
284
|
+
manual?: boolean | readonly DataTableStage[];
|
|
285
|
+
/** How many rows there are in total, when the table is not doing the paging. */
|
|
286
|
+
rowCount?: number;
|
|
287
|
+
/**
|
|
288
|
+
* The language the table's own words are in — the search field's placeholder,
|
|
289
|
+
* the ticks' labels, the footer's count.
|
|
290
|
+
*
|
|
291
|
+
* It is also what the default sort compares strings with. Pass it whenever
|
|
292
|
+
* the markup is rendered on a server: without it the comparison follows the
|
|
293
|
+
* runtime's own locale, and a server that disagrees with the browser about
|
|
294
|
+
* that produces two different row orders for the same table.
|
|
295
|
+
*/
|
|
296
|
+
locale?: string;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* A table for a lot of rows.
|
|
300
|
+
*
|
|
301
|
+
* [Table](../display/table) draws a grid; this one is a place to work. The
|
|
302
|
+
* difference shows up in three decisions and everything else follows from them.
|
|
303
|
+
*
|
|
304
|
+
* **The rows are all the same height, and it is a number.** That is what lets
|
|
305
|
+
* the body render thirty rows out of two hundred thousand and still put the
|
|
306
|
+
* scrollbar in the right place — the offset of a row is its index times a
|
|
307
|
+
* constant, so nothing has to be measured on a scroll frame. It is also why
|
|
308
|
+
* cells truncate instead of wrapping: a cell that decides its own height would
|
|
309
|
+
* make every arithmetic answer above a guess.
|
|
310
|
+
*
|
|
311
|
+
* **Selecting is the file manager's, not the form's.** A click chooses a row
|
|
312
|
+
* and drops the rest, Ctrl adds one, Shift takes the run between, a drag takes
|
|
313
|
+
* the run under the pointer, and the arrow keys do all three with the same
|
|
314
|
+
* modifiers. Ticks are available and are not the default: a column of
|
|
315
|
+
* checkboxes says the task is choosing, and on most tables it is not.
|
|
316
|
+
*
|
|
317
|
+
* **The three stages are one pipeline, and the caller can take over any of
|
|
318
|
+
* them.** Search, then sort, then cut a page out — done here over `items` by
|
|
319
|
+
* default, and skipped stage by stage through `manual` for a table whose server
|
|
320
|
+
* is doing it. Both paths render the same, which is what stops a table that
|
|
321
|
+
* starts local and grows remote from becoming a second component.
|
|
322
|
+
*/
|
|
323
|
+
export declare function DataTable<Row>({ headers, items, getRowKey, variant, size, color, density, elevation, height, maxHeight, rowHeight: rowHeightProp, striped, hoverable, stickyHeader, caption, label, empty, virtual, overscan, sortable, sortMode, sort: sortProp, defaultSort, onSortChange, resizable, columnWidths, defaultColumnWidths, onColumnWidthsChange, selectionMode, selected, defaultSelected, onSelectedChange, checkboxes, onRowClick, onRowActivate, paging, page: pageProp, defaultPage, onPageChange, pageSize: pageSizeProp, defaultPageSize, onPageSizeChange, pageSizeOptions, footer, search: searchProp, defaultSearch, onSearchChange, searchable, searchPlaceholder, filter, toolbar, manual, rowCount, locale, className, style, ...boxProps }: DataTableProps<Row>): React.JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as e,jsxs as t,Fragment as n}from"react/jsx-runtime";import*as r from"react";import{Box as a}from"../box/Box";import{Checkbox as l}from"../checkbox/Checkbox";import{Pagination as o}from"../pagination/Pagination";import{Select as s}from"../select/Select";import{TextField as i}from"../text-field/TextField";import{compareValues as c,dataHeaderHeights as u,dataRowHeights as d,dataTickWidths as p,defaultColumnWidth as m,keysBetween as h,minColumnWidth as f,nextSort as g,pageBounds as v,searchText as y,sortRows as b,virtualWindow as k}from"../../internal/data-table";import{fillMessage as w,useMessages as x}from"../../internal/i18n";import{ChevronIcon as C}from"../../internal/icons";import{controlTextLeadingClasses as S,cx as M,hasContent as N,metaTextClasses as K,paddingXValues as z,srOnlyClasses as $}from"../../internal/styles";const E=["[--n-row:transparent]","[transition:background-color_var(--neba-duration)_var(--neba-ease)]"].join(" "),_={"--n-stripe":"color-mix(in oklab, var(--neba-fg) 4%, transparent)"},R=["group/sort flex w-full min-w-0 cursor-pointer items-center gap-1","text-inherit [outline:none]","[transition:color_var(--neba-duration)_var(--neba-ease)]","hover:text-(--n-accent)","focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:outline-offset-1","[&_svg]:pointer-events-none [&_svg]:size-[1.15em] [&_svg]:shrink-0"].join(" "),D=["absolute inset-y-0 z-10 w-2 cursor-col-resize select-none","end-0 translate-x-1/2 rtl:-translate-x-1/2","after:absolute after:inset-y-1 after:start-1/2 after:w-px","after:[background:transparent]","after:[transition:background_var(--neba-duration)_var(--neba-ease)]","hover:after:[background:var(--n-accent)]"].join(" ");function L(){return t("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:[e("circle",{cx:"7.25",cy:"7.25",r:"4.75",stroke:"currentColor",strokeWidth:"1.5"}),e("path",{d:"m10.75 10.75 2.75 2.75",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]})}function P(e){return"number"==typeof e?`${e}px`:e}export function DataTable({headers:A,items:T,getRowKey:j,variant:H="outline",size:B="sm",color:I="primary",density:W="compact",elevation:F=0,height:O,maxHeight:q,rowHeight:U,striped:X=!1,hoverable:Y=!0,stickyHeader:V=!0,caption:G,label:J,empty:Q,virtual:Z=!0,overscan:ee=8,sortable:te=!1,sortMode:ne="single",sort:re,defaultSort:ae,onSortChange:le,resizable:oe=!1,columnWidths:se,defaultColumnWidths:ie,onColumnWidthsChange:ce,selectionMode:ue="none",selected:de,defaultSelected:pe,onSelectedChange:me,checkboxes:he=!1,onRowClick:fe,onRowActivate:ge,paging:ve="scroll",page:ye,defaultPage:be=1,onPageChange:ke,pageSize:we,defaultPageSize:xe=25,onPageSizeChange:Ce,pageSizeOptions:Se=[10,25,50,100],footer:Me,search:Ne,defaultSearch:Ke,onSearchChange:ze,searchable:$e=!1,searchPlaceholder:Ee,filter:_e,toolbar:Re,manual:De=!1,rowCount:Le,locale:Pe,className:Ae,style:Te,...je}){const He=x(Pe),Be=r.useId(),Ie=U??d[W][B],We=u[W][B],Fe=z[W][B],Oe=r.useMemo(()=>new Set(!0===De?["sort","filter","pages"]:De||[]),[De]),qe=r.useMemo(()=>A.filter(e=>!e.hidden),[A]),Ue=qe.some(e=>void 0!==e.group),Xe="none"!==ue,Ye="multiple"===ue,Ve=Xe&&he,Ge=r.useMemo(()=>T.map((e,t)=>{const n=j?j(e,t):t;return{row:e,identity:n,key:String(n),origin:t}}),[T,j]),[Je,Qe]=r.useState(Ke??""),Ze=(Ne??Je).trim(),et=r.useMemo(()=>{if(Oe.has("filter"))return Ge;const e=y(Ze),t=qe.filter(e=>!1!==e.searchable);let n=Ge;return""!==e&&t.length>0&&(n=n.filter(n=>t.some(t=>{const r=t.value?t.value(n.row):n.row[t.key];return y(r).includes(e)}))),_e?n.filter(e=>_e(e.row,e.origin)):n},[Ge,qe,Ze,_e,Oe]),tt=r.useMemo(()=>new Intl.Collator(Pe,{numeric:!0,sensitivity:"base"}),[Pe]),[nt,rt]=r.useState(ae??[]),at=re??nt,lt=r.useMemo(()=>Oe.has("sort")?et:b(et,at,e=>{const t=qe.find(t=>t.key===e);if(!t)return null;if(t.compare)return(e,n)=>t.compare(e.row,n.row);const n=t.value?t.value:e=>e[t.key];return(e,t)=>c(n(e.row),n(t.row),tt)}),[et,at,qe,tt,Oe]),[ot,st]=r.useState(be),[it,ct]=r.useState(xe),ut=we??it,dt=Oe.has("pages")?Le??lt.length:lt.length,pt=v(dt,ye??ot,ut),mt=r.useMemo(()=>"pages"!==ve||Oe.has("pages")?lt:lt.slice(pt.start,pt.end),[lt,ve,Oe,pt.start,pt.end]),ht="pages"===ve?pt.start:0,ft=r.useMemo(()=>mt.map(e=>e.key),[mt]),gt=r.useMemo(()=>new Map(Ge.map(e=>[e.key,e])),[Ge]),[vt,yt]=r.useState(pe??[]),bt=de??vt,kt=r.useMemo(()=>new Set(bt.map(String)),[bt]),[wt,xt]=r.useState(null),Ct=r.useRef(null),St=r.useRef({paged:mt,pagedKeys:ft,byKey:gt,selectedKeys:kt,multiple:Ye});St.current={paged:mt,pagedKeys:ft,byKey:gt,selectedKeys:kt,multiple:Ye};const Mt=r.useCallback(e=>{const t=[],n=[];for(const r of e){const e=St.current.byKey.get(r);e&&(t.push(e.identity),n.push(e.row))}void 0===de&&yt(t),me?.(t,n)},[de,me]),Nt=r.useCallback(e=>{Ct.current=e,Mt([e])},[Mt]),Kt=r.useCallback(e=>{const t=St.current.selectedKeys,n=new Set(t);n.has(e)?n.delete(e):n.add(e),Ct.current=e,Mt([...n])},[Mt]),zt=r.useCallback((e,t)=>{const n=St.current.pagedKeys,r=Ct.current??n[0];if(void 0===r)return;const a=h(n,r,e);0!==a.length&&Mt(t?[...new Set([...St.current.selectedKeys,...a])]:a)},[Mt]),$t=r.useRef(null),Et=r.useRef(null),_t=r.useRef(null),[Rt,Dt]=r.useState(0),[Lt,Pt]=r.useState(0),At=void 0!==O||void 0!==q,Tt=Z&&At&&mt.length>0;r.useLayoutEffect(()=>{const e=$t.current;if(!e||!Tt)return;const t=new ResizeObserver(([e])=>{Dt(e.contentRect.height)});return t.observe(e),Dt(e.clientHeight),()=>t.disconnect()},[Tt]);const jt=r.useCallback(e=>{if(!Tt)return;const t=Math.floor(e.currentTarget.scrollTop/Ie)*Ie;Pt(e=>e===t?e:t)},[Tt,Ie]),Ht=Tt?k(Lt,Rt,Ie,mt.length,ee):{start:0,end:mt.length,before:0,after:0},Bt=mt.slice(Ht.start,Ht.end),It=Xe&&null!==wt&&Bt.some(e=>e.key===wt),[Wt,Ft]=r.useState(ie??{}),Ot=se??Wt,qt=r.useCallback(e=>{void 0===se&&Ft(e),ce?.(e)},[se,ce]),Ut=r.useRef(new Map),Xt=r.useCallback(e=>{const t=$t.current;if(!t||!At)return;const n=V?We*(Ue?2:1):0,r=e*Ie;r<t.scrollTop+n?t.scrollTop=Math.max(0,r-n):r+Ie>t.scrollTop+t.clientHeight&&(t.scrollTop=r+Ie-t.clientHeight)},[At,V,We,Ue,Ie]),Yt=(e,t)=>{const n=St.current.paged,r=Math.min(Math.max(e,0),n.length-1),a=n[r];a&&(t.preventDefault(),xt(a.key),Xt(r),t.shiftKey&&St.current.multiple?zt(a.key,!1):t.ctrlKey||t.metaKey||Nt(a.key))};const Vt=r.useCallback(e=>{const t=Et.current,n=St.current.paged;if(!t||0===n.length)return null;const r=t.getBoundingClientRect().top,a=Math.floor((e-r)/Ie);return Math.min(Math.max(a,0),n.length-1)},[Ie]),Gt=r.useRef(null),Jt=r.useCallback(e=>{const t=Vt(e),n=null===t?void 0:St.current.paged[t];n&&(xt(n.key),zt(n.key,!1))},[Vt,zt]),Qt=r.useRef(Jt);Qt.current=Jt;function Zt(e,t){if(Xe&&!t.target.closest('button, a, input, select, textarea, [role="button"]'))if(_t.current?.focus({preventScroll:!0}),xt(e.key),2!==t.button){if(0===t.button)return t.shiftKey&&Ye?(t.preventDefault(),void zt(e.key,t.ctrlKey||t.metaKey)):void((t.ctrlKey||t.metaKey)&&Ye?Kt(e.key):(Nt(e.key),Ye&&(e=>{if(Gt.current)return;const t=e=>{const t=Gt.current,r=$t.current;if(!t)return;if(t.y=e.clientY,Qt.current(t.y),!r||!At)return;const a=r.getBoundingClientRect(),l=a.top+Ie-t.y,o=t.y-(a.bottom-Ie);t.speed=l>0?-Math.min(l,40):o>0?Math.min(o,40):0,0!==t.speed&&null===t.frame&&(t.frame=requestAnimationFrame(n))},n=()=>{const e=Gt.current,t=$t.current;e&&t&&0!==e.speed?(t.scrollTop+=e.speed,Qt.current(e.y),e.frame=requestAnimationFrame(n)):e&&(e.frame=null)},r=()=>{const e=Gt.current;null!=e?.frame&&cancelAnimationFrame(e.frame),Gt.current=null,window.removeEventListener("pointermove",t),window.removeEventListener("pointerup",r),window.removeEventListener("pointercancel",r)};Gt.current={y:e,speed:0,frame:null,stop:r},window.addEventListener("pointermove",t),window.addEventListener("pointerup",r),window.addEventListener("pointercancel",r)})(t.clientY)))}else St.current.selectedKeys.has(e.key)||Nt(e.key)}r.useEffect(()=>()=>Gt.current?.stop(),[]);const en=r.useMemo(()=>ft.reduce((e,t)=>kt.has(t)?e+1:e,0),[ft,kt]),tn=ft.length>0&&en===ft.length,nn=p[B],rn=e=>Ot[e.key]??e.width,an=(Ve?nn:0)+qe.reduce((e,t)=>e+(rn(t)??f),0),ln=qe.length>0&&qe.every(e=>void 0!==rn(e)),on=qe.length+(Ve?1:0)+(ln?1:0),sn=r.useMemo(()=>{const e=[];return qe.forEach((t,n)=>{const r=e[e.length-1];r&&void 0!==r.label&&r.label===t.group?r.span+=1:e.push({label:t.group,span:1,from:n})}),e},[qe]),cn={padding:`0 ${Fe}`,borderBottom:"1px solid var(--n-line)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},un={...cn,height:`${We}px`,backgroundColor:"var(--n-panel-press)"},dn="odd"===X?0:1,pn=r.useMemo(()=>new Intl.NumberFormat(Pe),[Pe]),mn=Me??"pages"===ve,hn=w(He.table.range,{start:pn.format(0===dt?0:("pages"===ve?pt.start:0)+1),end:pn.format("pages"===ve?pt.end:dt),total:pn.format(dt)}),fn=e=>{void 0===ye&&st(e),ke?.(e)},gn=(n,r,a)=>{const l=n.sortable??te,o=n.resizable??oe,s=(i=n.key,at.find(e=>e.key===i));var i;const c=s?at.findIndex(e=>e.key===n.key)+1:0,u=n.headerAlign??n.align??"start";return t("th",{ref:e=>{e?Ut.current.set(n.key,e):Ut.current.delete(n.key)},scope:"col",rowSpan:a,"aria-sort":s?"asc"===s.direction?"ascending":"descending":void 0,className:M("relative font-semibold select-none",s?"text-(--n-accent)":"text-(--neba-muted-fg)",V?"sticky z-20 [backdrop-filter:var(--neba-blur)]":""),style:{...un,top:V?2!==a&&Ue?We:0:void 0,textAlign:u},children:[l?t("button",{type:"button",className:M(R,"end"===u?"justify-end":"center"===u?"justify-center":"justify-start"),onClick:e=>((e,t)=>{const n=g(at,e,t&&"multiple"===ne);void 0===re&&rt(n),le?.(n)})(n.key,e.shiftKey),children:[e("span",{className:"min-w-0 truncate",children:n.label??n.key}),e("span",{"aria-hidden":"true",className:M("flex items-center","desc"===s?.direction?"rotate-0":"rotate-180",s?"":"text-transparent group-hover/sort:text-inherit group-focus-visible/sort:text-inherit"),children:e(C,{})}),c>1?e("span",{"aria-hidden":"true",className:"text-[0.85em] tabular-nums",children:c}):null]}):e("span",{className:"block truncate",children:n.label??n.key}),o&&r<qe.length-1?e("span",{"aria-hidden":"true",className:D,onPointerDown:e=>((e,t)=>{t.preventDefault(),t.stopPropagation();const n=t.currentTarget,r={...Ot};for(const e of qe){const t=Ut.current.get(e.key);t&&void 0===r[e.key]&&(r[e.key]=Math.round(t.getBoundingClientRect().width))}const a="rtl"===getComputedStyle(n).direction,l=t.clientX,o=r[e]??m,s=qe.find(t=>t.key===e)?.minWidth??f;n.setPointerCapture(t.pointerId);const i=t=>{const n=(t.clientX-l)*(a?-1:1);qt({...r,[e]:Math.max(s,Math.round(o+n))})},c=()=>{n.removeEventListener("pointermove",i),n.removeEventListener("pointerup",c),n.removeEventListener("pointercancel",c)};n.addEventListener("pointermove",i),n.addEventListener("pointerup",c),n.addEventListener("pointercancel",c)})(n.key,e),onDoubleClick:()=>(e=>{const t={...Ot};delete t[e],qt(t)})(n.key)}):null]},n.key)},vn=t=>e("span",{className:"flex items-center justify-center",children:t}),yn=t=>e("td",{role:Xe?"gridcell":void 0,style:{...cn,padding:0,overflow:"visible"},children:vn(e(l,{size:B,color:I,checked:kt.has(t.key),"aria-label":He.table.selectRow,onCheckedChange:()=>{Ye?Kt(t.key):Nt(t.key)}}))}),bn=Ye?vn(e(l,{size:B,color:I,checked:tn,indeterminate:en>0&&!tn,"aria-label":He.table.selectAll,onCheckedChange:()=>{if(tn){const e=new Set(ft);Mt([...kt].filter(t=>!e.has(t)))}else Mt([...new Set([...kt,...ft])])}})):null,kn=ln?e("th",{"aria-hidden":"true",className:M(V?"sticky top-0 z-20 [backdrop-filter:var(--neba-blur)]":""),style:{...un,padding:0}}):null,wn=(t,n)=>n>0?e("tr",{"aria-hidden":"true",style:{height:`${n}px`},children:e("td",{colSpan:on,style:{padding:0,border:0}})},t):null;return t(a,{variant:H,size:B,color:I,density:W,elevation:F,padded:!1,className:M("flex flex-col overflow-hidden",Xe?"has-[:focus-visible]:[outline:2px_solid_var(--n-ring)] has-[:focus-visible]:outline-offset-2":"",Ae),style:{..._,...Te},...je,children:[$e||N(Re)?t("div",{className:"flex items-center gap-2",style:{padding:`${Fe} ${Fe}`,borderBottom:"1px solid var(--n-line)"},children:[$e?e(i,{size:B,color:I,density:W,variant:"outline",type:"search",className:"w-full max-w-64",startIcon:e(L,{}),placeholder:Ee??He.table.search,"aria-label":Ee??He.table.search,value:Ne??Je,onChange:e=>{const t=e.target.value;void 0===Ne&&Qe(t),fn(1),ze?.(t)}}):null,N(Re)?e("div",{className:"ms-auto flex items-center gap-2",children:Re}):null]}):null,e("div",{ref:$t,className:"min-h-0 flex-auto overflow-auto overscroll-contain",style:{height:P(O),maxHeight:P(q)},onScroll:jt,children:t("table",{ref:_t,role:Xe?"grid":void 0,"aria-label":J,"aria-multiselectable":Ye||void 0,"aria-rowcount":Tt?mt.length+1:void 0,"aria-activedescendant":It?`${Be}-${wt}`:void 0,tabIndex:Xe?0:void 0,className:M("w-full text-start [outline:none]",S[B],"text-(--neba-fg)",Xe?"select-none":""),style:{tableLayout:"fixed",borderCollapse:"separate",borderSpacing:0,minWidth:`${an}px`},onKeyDown:function(e){if(!Xe||e.target!==e.currentTarget)return;const t=St.current.paged;if(0===t.length)return;const n=null===wt?-1:St.current.pagedKeys.indexOf(wt),r=Math.max(1,Math.floor((Rt||10*Ie)/Ie)-1);switch(e.key){case"ArrowDown":Yt(n+1,e);break;case"ArrowUp":Yt(-1===n?0:n-1,e);break;case"Home":Yt(0,e);break;case"End":Yt(t.length-1,e);break;case"PageDown":Yt(-1===n?0:n+r,e);break;case"PageUp":Yt(-1===n?0:n-r,e);break;case" ":-1!==n&&(e.preventDefault(),(e.ctrlKey||e.metaKey)&&Ye?Kt(t[n].key):Nt(t[n].key));break;case"a":case"A":(e.ctrlKey||e.metaKey)&&Ye&&(e.preventDefault(),Mt(St.current.pagedKeys));break;case"Escape":e.preventDefault(),Mt([]);break;case"Enter":-1!==n&&ge&&(e.preventDefault(),ge(t[n].row,ht+n))}},children:[G?e("caption",{className:M(K[B],"text-(--neba-muted-fg)"),style:{padding:`0.5rem ${Fe}`,textAlign:"start"},children:G}):null,t("colgroup",{children:[Ve?e("col",{style:{width:`${nn}px`}}):null,qe.map(t=>{const n=rn(t);return e("col",{style:void 0===n?void 0:{width:`${n}px`}},t.key)}),ln?e("col",{}):null]}),t("thead",{children:[Ue?t("tr",{style:{height:`${We}px`},children:[Ve?e("th",{scope:"col",rowSpan:2,className:M(V?"sticky top-0 z-20 [backdrop-filter:var(--neba-blur)]":""),style:{...un,padding:0,overflow:"visible"},children:bn}):null,sn.map(t=>void 0===t.label?gn(qe[t.from],t.from,2):e("th",{scope:"colgroup",colSpan:t.span,className:M("font-semibold text-(--neba-muted-fg) select-none",V?"sticky top-0 z-20 [backdrop-filter:var(--neba-blur)]":""),style:{...un,textAlign:"center"},children:t.label},`group-${t.from}`)),ln?r.cloneElement(kn,{rowSpan:2}):null]}):null,t("tr",{style:{height:`${We}px`},children:[Ve&&!Ue?e("th",{scope:"col",className:M(V?"sticky top-0 z-20 [backdrop-filter:var(--neba-blur)]":""),style:{...un,padding:0,overflow:"visible"},children:bn}):null,qe.map((e,t)=>Ue&&void 0===e.group?null:gn(e,t)),ln&&!Ue?kn:null]})]}),e("tbody",{ref:Et,children:0===mt.length?e("tr",{children:e("td",{colSpan:on,className:"text-(--neba-muted-fg)",style:{padding:`2rem ${Fe}`,textAlign:"center"},children:Q??He.empty.title})}):t(n,{children:[wn("before",Ht.before),Bt.map((n,r)=>{const a=Ht.start+r,l=kt.has(n.key),o=wt===n.key;return t("tr",{id:`${Be}-${n.key}`,"aria-selected":Xe?l:void 0,"aria-rowindex":Tt?a+2:void 0,"data-neba-row":n.key,className:M(E,l?"[--n-row:var(--n-soft-press)]":!1!==X&&a%2===dn?"[--n-row:var(--n-stripe)]":"",!l&&Y?"hover:[--n-row:var(--n-soft)]":"",o&&Xe?"[box-shadow:inset_0_0_0_1px_var(--n-ring)]":"",Xe||fe?"cursor-default":""),style:{height:`${Ie}px`,backgroundColor:"var(--n-row)"},onPointerDown:e=>Zt(n,e),onClick:e=>fe?.(n.row,ht+a,e),onDoubleClick:()=>ge?.(n.row,ht+a),children:[Ve?yn(n):null,qe.map(t=>e("td",{role:Xe?"gridcell":void 0,style:{...cn,textAlign:t.align??"start"},children:t.render?t.render(n.row,ht+a):n.row[t.key]},t.key)),ln?e("td",{"aria-hidden":"true",style:{...cn,padding:0}}):null]},n.key)}),wn("after",Ht.after)]})})]})}),mn?t("div",{className:M("flex flex-wrap items-center gap-3",K[B]),style:{padding:`0.375rem ${Fe}`,borderTop:"1px solid var(--n-line)"},children:[e("span",{className:"text-(--neba-muted-fg) tabular-nums",children:hn}),Xe&&kt.size>0?e("span",{className:"text-(--n-accent) tabular-nums",children:w(He.table.selected,{count:pn.format(kt.size)})}):null,t("div",{className:"ms-auto flex items-center gap-2",children:["pages"===ve&&Se.length>0?e(n,{children:e(s,{size:B,color:I,density:W,variant:"outline",label:He.table.rowsPerPage,items:Se.map(e=>({value:e})),value:ut,onValueChange:e=>{const t=Number(e);void 0===we&&ct(t),fn(Math.floor(pt.start/t)+1),Ce?.(t)}})}):null,"pages"===ve?e(o,{size:B,color:I,count:pt.pages,page:pt.page,siblingCount:0,onPageChange:fn}):null]})]}):null,!mn&&Tt?e("span",{className:$,"aria-live":"polite",children:hn}):null]})}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{DataTable}from"./DataTable";
|
|
@@ -8,7 +8,7 @@ import type { NebaStyleProps } from '../../types';
|
|
|
8
8
|
* assert itself against the page around it", and a modal has already taken the
|
|
9
9
|
* page. There is no `elevation` either — see `popupClasses`.
|
|
10
10
|
*/
|
|
11
|
-
export interface DialogProps extends Pick<NebaStyleProps, 'size' | 'color' | 'density'> {
|
|
11
|
+
export interface DialogProps extends Pick<NebaStyleProps, 'size' | 'color' | 'density'>, Omit<React.ComponentPropsWithoutRef<'div'>, 'color' | 'title' | 'children'> {
|
|
12
12
|
/** The dialog is shown. Use with `onOpenChange` for a controlled dialog. */
|
|
13
13
|
open?: boolean;
|
|
14
14
|
/** Whether the dialog starts open, for an uncontrolled one. */
|
|
@@ -45,7 +45,15 @@ export interface DialogProps extends Pick<NebaStyleProps, 'size' | 'color' | 'de
|
|
|
45
45
|
* @default true
|
|
46
46
|
*/
|
|
47
47
|
showClose?: boolean;
|
|
48
|
-
/**
|
|
48
|
+
/**
|
|
49
|
+
* Which language the × is named in — a BCP 47 tag such as `ko`, `pt-BR` or
|
|
50
|
+
* `zh-Hant`. Unsupported tags fall back to English.
|
|
51
|
+
*
|
|
52
|
+
* `closeLabel` writes the word out instead; this is for the far more common
|
|
53
|
+
* case where the page already knows its own language.
|
|
54
|
+
*/
|
|
55
|
+
locale?: string;
|
|
56
|
+
/** Accessible name of the × button. Defaults to the `locale`'s word for it. */
|
|
49
57
|
closeLabel?: string;
|
|
50
58
|
/**
|
|
51
59
|
* A hard cap on the sheet's width, overriding the one `size` implies. Numbers
|
|
@@ -79,8 +87,6 @@ export interface DialogProps extends Pick<NebaStyleProps, 'size' | 'color' | 'de
|
|
|
79
87
|
dismissible?: boolean;
|
|
80
88
|
/** The body. */
|
|
81
89
|
children?: React.ReactNode;
|
|
82
|
-
className?: string;
|
|
83
|
-
style?: React.CSSProperties;
|
|
84
90
|
}
|
|
85
91
|
export type DialogCloseProps = React.ComponentPropsWithoutRef<typeof BaseUIDialog.Close>;
|
|
86
92
|
/**
|
|
@@ -108,4 +114,4 @@ export declare const DialogClose: React.ForwardRefExoticComponent<Omit<import("@
|
|
|
108
114
|
* the header and the actions stay put while only the body scrolls, which is why
|
|
109
115
|
* `dividers` matters more here than on a Card.
|
|
110
116
|
*/
|
|
111
|
-
export declare function Dialog({ size, color, density, open, defaultOpen, onOpenChange, trigger, title, description, actions, dividers, showClose, closeLabel, width, fullWidth, fullScreen, modal, dismissible, className, style, children }: DialogProps): React.JSX.Element;
|
|
117
|
+
export declare function Dialog({ size, color, density, open, defaultOpen, onOpenChange, trigger, title, description, actions, dividers, showClose, locale, closeLabel, width, fullWidth, fullScreen, modal, dismissible, className, style, children, ...props }: DialogProps): React.JSX.Element;
|