neba 1.4.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.
Files changed (119) hide show
  1. package/README.md +6 -4
  2. package/dist/components/alert/Alert.d.ts +9 -1
  3. package/dist/components/alert/Alert.js +1 -1
  4. package/dist/components/area-chart/AreaChart.d.ts +54 -0
  5. package/dist/components/area-chart/AreaChart.js +1 -0
  6. package/dist/components/area-chart/index.d.ts +2 -0
  7. package/dist/components/area-chart/index.js +1 -0
  8. package/dist/components/bar-chart/BarChart.d.ts +63 -0
  9. package/dist/components/bar-chart/BarChart.js +1 -0
  10. package/dist/components/bar-chart/index.d.ts +2 -0
  11. package/dist/components/bar-chart/index.js +1 -0
  12. package/dist/components/bottom-navigation/BottomNavigation.d.ts +111 -0
  13. package/dist/components/bottom-navigation/BottomNavigation.js +1 -0
  14. package/dist/components/bottom-navigation/index.d.ts +1 -0
  15. package/dist/components/bottom-navigation/index.js +1 -0
  16. package/dist/components/breadcrumb/Breadcrumb.d.ts +35 -2
  17. package/dist/components/breadcrumb/Breadcrumb.js +1 -1
  18. package/dist/components/button/Button.d.ts +16 -0
  19. package/dist/components/button/Button.js +1 -1
  20. package/dist/components/carousel/Carousel.d.ts +10 -4
  21. package/dist/components/carousel/Carousel.js +1 -1
  22. package/dist/components/chip/Chip.d.ts +9 -1
  23. package/dist/components/chip/Chip.js +1 -1
  24. package/dist/components/collapsible/Collapsible.d.ts +88 -0
  25. package/dist/components/collapsible/Collapsible.js +1 -0
  26. package/dist/components/collapsible/index.d.ts +1 -0
  27. package/dist/components/collapsible/index.js +1 -0
  28. package/dist/components/combobox/Combobox.d.ts +19 -7
  29. package/dist/components/combobox/Combobox.js +1 -1
  30. package/dist/components/dialog/Dialog.d.ts +11 -5
  31. package/dist/components/dialog/Dialog.js +1 -1
  32. package/dist/components/drawer/Drawer.d.ts +11 -5
  33. package/dist/components/drawer/Drawer.js +1 -1
  34. package/dist/components/file-picker/FilePicker.d.ts +1 -3
  35. package/dist/components/file-picker/FilePicker.js +1 -1
  36. package/dist/components/floating-action-button/FloatingActionButton.d.ts +146 -0
  37. package/dist/components/floating-action-button/FloatingActionButton.js +1 -0
  38. package/dist/components/floating-action-button/index.d.ts +1 -0
  39. package/dist/components/floating-action-button/index.js +1 -0
  40. package/dist/components/heatmap-chart/HeatmapChart.d.ts +69 -0
  41. package/dist/components/heatmap-chart/HeatmapChart.js +1 -0
  42. package/dist/components/heatmap-chart/index.d.ts +2 -0
  43. package/dist/components/heatmap-chart/index.js +1 -0
  44. package/dist/components/highlight/Highlight.js +1 -1
  45. package/dist/components/line-chart/LineChart.d.ts +74 -0
  46. package/dist/components/line-chart/LineChart.js +1 -0
  47. package/dist/components/line-chart/index.d.ts +2 -0
  48. package/dist/components/line-chart/index.js +1 -0
  49. package/dist/components/number-field/NumberField.d.ts +10 -6
  50. package/dist/components/number-field/NumberField.js +1 -1
  51. package/dist/components/overlay/Overlay.d.ts +11 -6
  52. package/dist/components/overlay/Overlay.js +1 -1
  53. package/dist/components/pagination/Pagination.d.ts +28 -6
  54. package/dist/components/pagination/Pagination.js +1 -1
  55. package/dist/components/panes/Panes.js +1 -1
  56. package/dist/components/pie-chart/PieChart.d.ts +58 -0
  57. package/dist/components/pie-chart/PieChart.js +1 -0
  58. package/dist/components/pie-chart/index.d.ts +2 -0
  59. package/dist/components/pie-chart/index.js +1 -0
  60. package/dist/components/popover/Popover.d.ts +11 -5
  61. package/dist/components/popover/Popover.js +1 -1
  62. package/dist/components/progress-box/ProgressBox.js +1 -1
  63. package/dist/components/progress-circular/ProgressCircular.js +1 -1
  64. package/dist/components/progress-linear/ProgressLinear.js +1 -1
  65. package/dist/components/rating/Rating.d.ts +100 -0
  66. package/dist/components/rating/Rating.js +1 -0
  67. package/dist/components/rating/index.d.ts +1 -0
  68. package/dist/components/rating/index.js +1 -0
  69. package/dist/components/scatter-chart/ScatterChart.d.ts +45 -0
  70. package/dist/components/scatter-chart/ScatterChart.js +1 -0
  71. package/dist/components/scatter-chart/index.d.ts +2 -0
  72. package/dist/components/scatter-chart/index.js +1 -0
  73. package/dist/components/select/Select.d.ts +1 -3
  74. package/dist/components/select/Select.js +1 -1
  75. package/dist/components/sparkline/Sparkline.d.ts +67 -0
  76. package/dist/components/sparkline/Sparkline.js +1 -0
  77. package/dist/components/sparkline/index.d.ts +2 -0
  78. package/dist/components/sparkline/index.js +1 -0
  79. package/dist/components/statistic/Statistic.d.ts +7 -0
  80. package/dist/components/statistic/Statistic.js +1 -1
  81. package/dist/components/table/Table.d.ts +13 -2
  82. package/dist/components/table/Table.js +1 -1
  83. package/dist/components/text-link/TextLink.js +1 -1
  84. package/dist/components/time-picker/TimePicker.js +1 -1
  85. package/dist/components/timeline-chart/TimelineChart.d.ts +44 -0
  86. package/dist/components/timeline-chart/TimelineChart.js +1 -0
  87. package/dist/components/timeline-chart/index.d.ts +2 -0
  88. package/dist/components/timeline-chart/index.js +1 -0
  89. package/dist/components/toast/Toast.d.ts +10 -2
  90. package/dist/components/toast/Toast.js +1 -1
  91. package/dist/components/tooltip/Tooltip.d.ts +2 -4
  92. package/dist/components/tooltip/Tooltip.js +1 -1
  93. package/dist/components/tree-view/TreeView.js +1 -1
  94. package/dist/index.d.ts +12 -0
  95. package/dist/index.js +1 -1
  96. package/dist/internal/animate.d.ts +0 -9
  97. package/dist/internal/animate.js +1 -1
  98. package/dist/internal/calendar.js +1 -1
  99. package/dist/internal/chart-frame.d.ts +409 -0
  100. package/dist/internal/chart-frame.js +1 -0
  101. package/dist/internal/chart-line.d.ts +44 -0
  102. package/dist/internal/chart-line.js +1 -0
  103. package/dist/internal/chart.d.ts +456 -0
  104. package/dist/internal/chart.js +1 -0
  105. package/dist/internal/date.d.ts +0 -2
  106. package/dist/internal/date.js +1 -1
  107. package/dist/internal/format.d.ts +29 -0
  108. package/dist/internal/format.js +1 -0
  109. package/dist/internal/i18n.d.ts +115 -0
  110. package/dist/internal/i18n.js +1 -1
  111. package/dist/internal/icons.d.ts +2 -0
  112. package/dist/internal/icons.js +1 -1
  113. package/dist/internal/picker.d.ts +2 -4
  114. package/dist/internal/picker.js +1 -1
  115. package/dist/internal/progress.d.ts +1 -3
  116. package/dist/styles.css +1 -1
  117. package/dist/tailwind.css +205 -0
  118. package/dist/types.d.ts +214 -0
  119. package/package.json +15 -11
@@ -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
- /** Shown in the popup when nothing matches and no value may be added. */
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
- /** Accessible name of a chip's remove button. Receives the chip's label. */
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{CheckIcon as r,ChevronIcon as o,CloseIcon as s,PlusIcon as c}from"../../internal/icons";import{chipRemoveClasses as d,controlHeightClasses as u,controlTextLeadingClasses as m,disabledClasses as p,fieldReadOnlyClasses as h,fieldRestClasses as b,focusWithinRingClasses as f,gapClasses as g,hasContent as x,iconClasses as v,metaTextClasses as y,paddingXClasses as N,radiusClasses as w,stackGapClasses as C,surfaceClasses as j,surfaceSlots as L,transitionClasses as $}from"../../internal/styles";const I=["group relative flex w-full cursor-text items-center","[-webkit-tap-highlight-color:transparent]",$,"focus-within:[transition-duration:0ms]",f,v].join(" "),S={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]"},O=[j,"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(" "),V=["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(" "),_=["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 z(e){return null==e?[]:Array.isArray(e)?e.slice():[e]}export function Combobox({variant:f="outline",size:v="md",color:j="primary",density:$="default",elevation:A=0,items:R,multiple:k,value:T,defaultValue:q,onValueChange:E,onInputValueChange:F,allowCustom:M=!0,customLabel:P,clearable:B=!1,emptyMessage:D="No matches",limit:G,placeholder:H,label:W,description:J,error:K,invalid:Q,startIcon:U,fullWidth:X=!1,disabled:Y=!1,readOnly:Z=!1,required:ee=!1,name:ae,open:le,defaultOpen:ne,onOpenChange:te,clearLabel:ie="Clear",removeLabel:re=e=>`Remove ${e}`,inputRef:oe,id:se,className:ce,style:de}){const ue=x(K),me=Q??ue,pe=me?"danger":j,he=!0===k,be=l.useMemo(()=>R.map(e=>({value:e.value,label:e.label??String(e.value),disabled:e.disabled})),[R]),[fe,ge]=l.useState(()=>z(q)),xe=void 0===T?fe:z(T),[ve,ye]=l.useState(""),Ne=l.useCallback(e=>be.find(a=>a.value===e)??{value:e,label:String(e),custom:!0},[be]),we=ve.trim(),Ce=we.toLocaleLowerCase(),je=""===we||be.some(e=>e.label.toLocaleLowerCase()===Ce||String(e.value).toLocaleLowerCase()===Ce)||xe.some(e=>String(e).toLocaleLowerCase()===Ce),Le=!M||Z||Y||je?null:we,$e=l.useMemo(()=>null===Le?be:[...be,{value:Le,label:Le,custom:!0}],[be,Le]),Ie=he?xe.map(Ne):xe.length>0?Ne(xe[0]):null;const Se=N[$][v],Oe=[I,m[v],w[v],g[v],he?S[v]:u[v],`${Se} pe-1.5`,Y?p[f]:Z?h[f]:b[f]].join(" "),Ve=["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(" "),_e=a=>e(n.Input,{ref:oe,placeholder:H,className:he?`${Ve} min-w-16 ${a?"ms-1.5":""}`:Ve});return a(t.Root,{disabled:Y,invalid:me,className:["flex-col align-top",C[v],X?"flex w-full":"inline-flex",ce??""].filter(Boolean).join(" "),style:{...L(pe,A),...de},children:[W?e(t.Label,{className:[y[v],"font-medium",Y?"text-(--neba-disabled-fg)":"text-(--neba-fg)"].join(" "),children:W}):null,a(n.Root,{id:se,name:ae,items:$e,multiple:he,value:Ie,onValueChange:e=>{!function(e){void 0===T&&ge(e),E?.(he?e:e[0]??null)}((null===e?[]:Array.isArray(e)?e:[e]).map(e=>e.value))},onInputValueChange:e=>{ye(e),F?.(e)},open:le,defaultOpen:ne,onOpenChange:e=>te?.(e),autoHighlight:!0,itemToStringLabel:e=>e.label,itemToStringValue:e=>String(e.value),isItemEqualToValue:(e,a)=>e.value===a.value,limit:G,disabled:Y,readOnly:Z,required:ee,children:[a(n.InputGroup,{className:Oe,children:[U?e("span",{className:"flex h-[1lh] shrink-0 items-center text-(--neba-muted-fg)",children:U}):null,he?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:v,color:pe,density:"compact",disabled:Y,endIcon:Z||Y?null:e(n.ChipRemove,{"aria-label":re(a.label),className:d,children:e(s,{})})}),children:a.label},String(a.value))),_e(t.length>0)]})})}):_e(!1),B&&!Z?e(n.Clear,{"aria-label":ie,className:_,children:e(s,{})}):null,e(n.Trigger,{"aria-label":"string"==typeof W?void 0:"Open",className:_,children:e(n.Icon,{className:["flex items-center","[transition:rotate_var(--neba-duration)_var(--neba-ease)]","data-[popup-open]:rotate-180"].join(" "),children:e(o,{})})})]}),e(n.Portal,{children:e(n.Positioner,{className:"neba-portal z-50 [outline:none]",sideOffset:6,children:a(n.Popup,{className:`${O} ${w[v]} ${m[v]}`,style:L(pe,3),children:[e(n.Empty,{className:"px-2 py-1.5 text-(--neba-muted-fg) empty:hidden",children:D}),e(n.List,{children:t=>e(n.Item,{value:t,disabled:t.disabled,className:V,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(c,{})}),e("span",{className:"truncate",children:P?P(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(r,{})}),e("span",{className:"truncate",children:t.label})]})},`${t.custom?"custom:":""}${String(t.value)}`)})]})})})]}),J?e(t.Description,{className:`${y[v]} text-(--neba-muted-fg)`,children:J}):null,ue?e(t.Error,{match:!0,className:`${y[v]} text-(--n-accent)`,children:K}):null]})}
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]})}
@@ -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
- /** Accessible name of the × button. */
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;
@@ -1 +1 @@
1
- import{jsx as e,jsxs as a}from"react/jsx-runtime";import{Dialog as l}from"@base-ui/react/dialog";import{boxPaddingXClasses as n,boxPaddingYClasses as i}from"../box/Box";import{CloseIcon as o}from"../../internal/icons";import{hasContent as r,metaTextClasses as t,radiusClasses as s,sheetBodyClasses as d,sheetHeaderGapClasses as c,sheetSectionGapClasses as m,sheetTitleClasses as f,surfaceClasses as u,surfaceSlots as p}from"../../internal/styles";const x={xs:"max-w-80",sm:"max-w-96",md:"max-w-lg",lg:"max-w-2xl",xl:"max-w-4xl"},b=[u,"relative flex w-full flex-col overflow-hidden","border text-(--neba-fg) bg-(--n-panel-press)","[border-color:var(--n-line)]","[box-shadow:var(--neba-shadow-3),var(--neba-plate-glass)]","[outline:none]","[transition:opacity_var(--neba-duration)_var(--neba-ease)]","data-[starting-style]:opacity-0 data-[ending-style]:opacity-0"].join(" "),h=["fixed inset-0 z-50 bg-(--neba-scrim)","[backdrop-filter:blur(2px)]","[transition:opacity_var(--neba-duration)_var(--neba-ease)]","data-[starting-style]:opacity-0 data-[ending-style]:opacity-0"].join(" "),g="border-t [border-color:var(--n-line)]";export const DialogClose=l.Close;export function Dialog({size:u="md",color:v="primary",density:y="default",open:w,defaultOpen:j,onOpenChange:$,trigger:_,title:N,description:k,actions:C,dividers:z=!1,showClose:B=!0,closeLabel:D="Close",width:O,fullWidth:P=!0,fullScreen:T=!1,modal:W=!0,dismissible:L=!0,className:R,style:S,children:V}){const q=n[y][u],A=i[y][u],E=z?`${q} ${A}`:q,F=r(N)||r(k),G=r(C);return a(l.Root,{open:w,defaultOpen:j,modal:W,disablePointerDismissal:!L,onOpenChange:(e,a)=>{L||e||"escape-key"!==a.reason?$?.(e):a.cancel()},children:[_?e(l.Trigger,{render:_}):null,a(l.Portal,{children:[e(l.Backdrop,{className:`neba-portal ${h}`}),e(l.Viewport,{className:["neba-portal fixed inset-0 z-50 flex justify-center",T?"items-stretch":"items-center p-4"].join(" "),children:a(l.Popup,{className:[b,d[u],T?"h-full max-w-none rounded-none":`max-h-full ${s[u]} ${void 0===O?x[u]:""}`,T||P?"":"w-auto",z?"":`${A} ${m[u]}`,R??""].filter(Boolean).join(" "),style:{...p(v,3),...void 0===O?null:{maxWidth:"number"==typeof O?`${O}px`:O},...S},children:[F||B?a("div",{className:`flex shrink-0 items-start gap-3 ${E}`,children:[a("div",{className:`flex min-w-0 flex-1 flex-col ${c[u]}`,children:[r(N)?e(l.Title,{className:`font-semibold ${f[u]} m-0`,children:N}):null,r(k)?e(l.Description,{className:`m-0 text-(--neba-muted-fg) ${t[u]}`,children:k}):null]}),B?e(l.Close,{"aria-label":D,className:["flex size-[1.6em] shrink-0 cursor-pointer items-center justify-center","rounded-full text-(--neba-muted-fg)","[&_svg]:size-[1.1em] [&_svg]:shrink-0","[transition:background-color_var(--neba-duration)_var(--neba-ease),color_var(--neba-duration)_var(--neba-ease)]","hover:bg-(--n-soft) hover:text-(--neba-fg)","focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:outline-offset-2"].join(" "),children:e(o,{})}):null]}):null,r(V)?e("div",{className:["min-h-0 flex-1 overflow-y-auto overscroll-contain",E,z&&(F||B)?g:"",z?"":"py-1 -my-1"].filter(Boolean).join(" "),children:V}):null,G?e("div",{className:["flex shrink-0 flex-wrap items-center justify-end gap-2",E,z?g:""].filter(Boolean).join(" "),children:C}):null]})})]})]})}
1
+ import{jsx as e,jsxs as a}from"react/jsx-runtime";import{Dialog as n}from"@base-ui/react/dialog";import{boxPaddingXClasses as l,boxPaddingYClasses as i}from"../box/Box";import{useMessages as o}from"../../internal/i18n";import{CloseIcon as r}from"../../internal/icons";import{hasContent as t,metaTextClasses as s,radiusClasses as c,sheetBodyClasses as d,sheetHeaderGapClasses as m,sheetSectionGapClasses as f,sheetTitleClasses as p,surfaceClasses as u,surfaceSlots as x}from"../../internal/styles";const b={xs:"max-w-80",sm:"max-w-96",md:"max-w-lg",lg:"max-w-2xl",xl:"max-w-4xl"},h=[u,"relative flex w-full flex-col overflow-hidden","border text-(--neba-fg) bg-(--n-panel-press)","[border-color:var(--n-line)]","[box-shadow:var(--neba-shadow-3),var(--neba-plate-glass)]","[outline:none]","[transition:opacity_var(--neba-duration)_var(--neba-ease)]","data-[starting-style]:opacity-0 data-[ending-style]:opacity-0"].join(" "),g=["fixed inset-0 z-50 bg-(--neba-scrim)","[backdrop-filter:blur(2px)]","[transition:opacity_var(--neba-duration)_var(--neba-ease)]","data-[starting-style]:opacity-0 data-[ending-style]:opacity-0"].join(" "),v="border-t [border-color:var(--n-line)]";export const DialogClose=n.Close;export function Dialog({size:u="md",color:y="primary",density:w="default",open:j,defaultOpen:$,onOpenChange:_,trigger:N,title:k,description:C,actions:z,dividers:B=!1,showClose:D=!0,locale:O,closeLabel:P,width:T,fullWidth:W=!0,fullScreen:L=!1,modal:R=!0,dismissible:S=!0,className:V,style:q,children:A,...E}){const F=o(O),G=l[w][u],H=i[w][u],I=B?`${G} ${H}`:G,J=t(k)||t(C),K=t(z);return a(n.Root,{open:j,defaultOpen:$,modal:R,disablePointerDismissal:!S,onOpenChange:(e,a)=>{S||e||"escape-key"!==a.reason?_?.(e):a.cancel()},children:[N?e(n.Trigger,{render:N}):null,a(n.Portal,{children:[e(n.Backdrop,{className:`neba-portal ${g}`}),e(n.Viewport,{className:["neba-portal fixed inset-0 z-50 flex justify-center",L?"items-stretch":"items-center p-4"].join(" "),children:a(n.Popup,{className:[h,d[u],L?"h-full max-w-none rounded-none":`max-h-full ${c[u]} ${void 0===T?b[u]:""}`,L||W?"":"w-auto",B?"":`${H} ${f[u]}`,V??""].filter(Boolean).join(" "),style:{...x(y,3),...void 0===T?null:{maxWidth:"number"==typeof T?`${T}px`:T},...q},...E,children:[J||D?a("div",{className:`flex shrink-0 items-start gap-3 ${I}`,children:[a("div",{className:`flex min-w-0 flex-1 flex-col ${m[u]}`,children:[t(k)?e(n.Title,{className:`font-semibold ${p[u]} m-0`,children:k}):null,t(C)?e(n.Description,{className:`m-0 text-(--neba-muted-fg) ${s[u]}`,children:C}):null]}),D?e(n.Close,{"aria-label":P??F.action.close,className:["flex size-[1.6em] shrink-0 cursor-pointer items-center justify-center","rounded-full text-(--neba-muted-fg)","[&_svg]:size-[1.1em] [&_svg]:shrink-0","[transition:background-color_var(--neba-duration)_var(--neba-ease),color_var(--neba-duration)_var(--neba-ease)]","hover:bg-(--n-soft) hover:text-(--neba-fg)","focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:outline-offset-2"].join(" "),children:e(r,{})}):null]}):null,t(A)?e("div",{className:["min-h-0 flex-1 overflow-y-auto overscroll-contain",I,B&&(J||D)?v:"",B?"":"py-1 -my-1"].filter(Boolean).join(" "),children:A}):null,K?e("div",{className:["flex shrink-0 flex-wrap items-center justify-end gap-2",I,B?v:""].filter(Boolean).join(" "),children:z}):null]})})]})]})}
@@ -24,7 +24,7 @@ export type NebaDrawerMode = 'overlay' | 'inline';
24
24
  * an `overlay` drawer floats and carries a shadow at level 3, an `inline` one is
25
25
  * part of the layout and carries none, and neither is a decision worth offering.
26
26
  */
27
- export interface DrawerProps extends Pick<NebaStyleProps, 'size' | 'color' | 'density'> {
27
+ export interface DrawerProps extends Pick<NebaStyleProps, 'size' | 'color' | 'density'>, Omit<React.ComponentPropsWithoutRef<'div'>, 'color' | 'title' | 'children'> {
28
28
  /**
29
29
  * Which edge the panel is attached to. Physical rather than logical, the way
30
30
  * `NebaSide` is everywhere: a drawer along the top of the window is along the
@@ -76,7 +76,15 @@ export interface DrawerProps extends Pick<NebaStyleProps, 'size' | 'color' | 'de
76
76
  * one-way door.
77
77
  */
78
78
  showClose?: boolean;
79
- /** Accessible name of the × button. */
79
+ /**
80
+ * Which language the × is named in — a BCP 47 tag such as `ko`, `pt-BR` or
81
+ * `zh-Hant`. Unsupported tags fall back to English.
82
+ *
83
+ * `closeLabel` writes the word out instead; this is for the far more common
84
+ * case where the page already knows its own language.
85
+ */
86
+ locale?: string;
87
+ /** Accessible name of the × button. Defaults to the `locale`'s word for it. */
80
88
  closeLabel?: string;
81
89
  /**
82
90
  * How far the panel reaches in from its edge: a **width** for `left` and
@@ -109,8 +117,6 @@ export interface DrawerProps extends Pick<NebaStyleProps, 'size' | 'color' | 'de
109
117
  dismissible?: boolean;
110
118
  /** The body. */
111
119
  children?: React.ReactNode;
112
- className?: string;
113
- style?: React.CSSProperties;
114
120
  }
115
121
  export type DrawerCloseProps = React.ComponentPropsWithoutRef<typeof BaseUIDialog.Close>;
116
122
  /**
@@ -142,4 +148,4 @@ export declare const DrawerClose: React.ForwardRefExoticComponent<Omit<import("@
142
148
  * scroll lock, the `aria-labelledby` / `aria-describedby` wiring, restoring
143
149
  * focus to the trigger, and the inert page behind.
144
150
  */
145
- export declare function Drawer({ side, mode, size, color, density, open, defaultOpen, onOpenChange, trigger, title, description, actions, dividers, showClose, closeLabel, extent, rounded, modal, dismissible, className, style, children }: DrawerProps): React.JSX.Element | null;
151
+ export declare function Drawer({ side, mode, size, color, density, open, defaultOpen, onOpenChange, trigger, title, description, actions, dividers, showClose, locale, closeLabel, extent, rounded, modal, dismissible, className, style, children, ...props }: DrawerProps): React.JSX.Element | null;
@@ -1 +1 @@
1
- import{jsx as e,jsxs as r,Fragment as a}from"react/jsx-runtime";import{Dialog as l}from"@base-ui/react/dialog";import{boxPaddingXClasses as n,boxPaddingYClasses as o}from"../box/Box";import{CloseIcon as s}from"../../internal/icons";import{hasContent as i,metaTextClasses as d,sheetBodyClasses as t,sheetHeaderGapClasses as u,sheetSectionGapClasses as b,sheetTitleClasses as m,surfaceClasses as c,surfaceSlots as f}from"../../internal/styles";const x={xs:"w-56",sm:"w-64",md:"w-80",lg:"w-96",xl:"w-[28rem]"},p={left:{xs:"rounded-r-(--neba-radius-xs)",sm:"rounded-r-(--neba-radius-sm)",md:"rounded-r-(--neba-radius-md)",lg:"rounded-r-(--neba-radius-lg)",xl:"rounded-r-(--neba-radius-xl)"},right:{xs:"rounded-l-(--neba-radius-xs)",sm:"rounded-l-(--neba-radius-sm)",md:"rounded-l-(--neba-radius-md)",lg:"rounded-l-(--neba-radius-lg)",xl:"rounded-l-(--neba-radius-xl)"},top:{xs:"rounded-b-(--neba-radius-xs)",sm:"rounded-b-(--neba-radius-sm)",md:"rounded-b-(--neba-radius-md)",lg:"rounded-b-(--neba-radius-lg)",xl:"rounded-b-(--neba-radius-xl)"},bottom:{xs:"rounded-t-(--neba-radius-xs)",sm:"rounded-t-(--neba-radius-sm)",md:"rounded-t-(--neba-radius-md)",lg:"rounded-t-(--neba-radius-lg)",xl:"rounded-t-(--neba-radius-xl)"}},g={left:"border-r",right:"border-l",top:"border-b",bottom:"border-t"},h={left:"flex-row justify-start",right:"flex-row justify-end",top:"flex-col justify-start",bottom:"flex-col justify-end"},v=[c,"relative flex flex-col overflow-hidden","text-(--neba-fg) bg-(--n-panel-press)","[border-color:var(--n-line)]","[outline:none]"].join(" "),y=["[transition:opacity_var(--neba-duration)_var(--neba-ease)]","data-[starting-style]:opacity-0 data-[ending-style]:opacity-0"].join(" "),w=["fixed inset-0 z-50 bg-(--neba-scrim)","[backdrop-filter:blur(2px)]",y].join(" "),j="border-t [border-color:var(--n-line)]",N=["flex size-[1.6em] shrink-0 cursor-pointer items-center justify-center","rounded-full text-(--neba-muted-fg)","[&_svg]:size-[1.1em] [&_svg]:shrink-0","[transition:background-color_var(--neba-duration)_var(--neba-ease),color_var(--neba-duration)_var(--neba-ease)]","hover:bg-(--n-soft) hover:text-(--neba-fg)","focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:outline-offset-2"].join(" ");export const DrawerClose=l.Close;export function Drawer({side:c="left",mode:$="overlay",size:_="md",color:k="primary",density:C="default",open:z,defaultOpen:B,onOpenChange:D,trigger:O,title:P,description:T,actions:F,dividers:L=!1,showClose:R,closeLabel:V="Close",extent:q,rounded:A=!0,modal:E=!0,dismissible:G=!0,className:H,style:I,children:J}){const K="overlay"===$,M="left"===c||"right"===c,Q=R??K,S=n[C][_],U=o[C][_],W=L?`${S} ${U}`:S,X=i(P)||i(T),Y=i(F),Z=void 0===q?null:{[M?"width":"height"]:"number"==typeof q?`${q}px`:q},ee=[v,t[_],g[c],A?p[c][_]:"",K?"[box-shadow:var(--neba-shadow-3),var(--neba-plate-glass)]":"[box-shadow:var(--neba-plate-glass)]",K?y:"",M?`h-full max-w-full ${void 0===q?x[_]:""}`:"w-full "+(void 0===q?"max-h-[85%]":""),L?"":`${U} ${b[_]}`,H??""].filter(Boolean).join(" "),re=K?l.Title:"h2",ae=K?l.Description:"p",le=r(a,{children:[X||Q?r("div",{className:`flex shrink-0 items-start gap-3 ${W}`,children:[r("div",{className:`flex min-w-0 flex-1 flex-col ${u[_]}`,children:[i(P)?e(re,{className:`m-0 font-semibold ${m[_]}`,children:P}):null,i(T)?e(ae,{className:`m-0 text-(--neba-muted-fg) ${d[_]}`,children:T}):null]}),Q?K?e(l.Close,{"aria-label":V,className:N,children:e(s,{})}):e("button",{type:"button","aria-label":V,className:N,onClick:()=>D?.(!1),children:e(s,{})}):null]}):null,i(J)?e("div",{className:["min-h-0 flex-1 overflow-y-auto overscroll-contain",W,L&&(X||Q)?j:"",L?"":"py-1 -my-1"].filter(Boolean).join(" "),children:J}):null,Y?e("div",{className:["flex shrink-0 flex-wrap items-center justify-end gap-2",W,L?j:""].filter(Boolean).join(" "),children:F}):null]});return K?r(l.Root,{open:z,defaultOpen:B,modal:E,disablePointerDismissal:!G,onOpenChange:(e,r)=>{G||e||"escape-key"!==r.reason?D?.(e):r.cancel()},children:[O?e(l.Trigger,{render:O}):null,r(l.Portal,{children:[e(l.Backdrop,{className:`neba-portal ${w}`}),e(l.Viewport,{className:`neba-portal fixed inset-0 z-50 flex ${h[c]}`,children:e(l.Popup,{className:ee,style:{...f(k,3),...Z,...I},children:le})})]})]}):z??B??1?e("div",{className:ee,style:{...f(k,0),...Z,...I},children:le}):null}
1
+ import{jsx as e,jsxs as r,Fragment as a}from"react/jsx-runtime";import{Dialog as n}from"@base-ui/react/dialog";import{boxPaddingXClasses as l,boxPaddingYClasses as o}from"../box/Box";import{useMessages as s}from"../../internal/i18n";import{CloseIcon as i}from"../../internal/icons";import{hasContent as d,metaTextClasses as t,sheetBodyClasses as u,sheetHeaderGapClasses as b,sheetSectionGapClasses as m,sheetTitleClasses as c,surfaceClasses as f,surfaceSlots as x}from"../../internal/styles";const p={xs:"w-56",sm:"w-64",md:"w-80",lg:"w-96",xl:"w-[28rem]"},g={left:{xs:"rounded-r-(--neba-radius-xs)",sm:"rounded-r-(--neba-radius-sm)",md:"rounded-r-(--neba-radius-md)",lg:"rounded-r-(--neba-radius-lg)",xl:"rounded-r-(--neba-radius-xl)"},right:{xs:"rounded-l-(--neba-radius-xs)",sm:"rounded-l-(--neba-radius-sm)",md:"rounded-l-(--neba-radius-md)",lg:"rounded-l-(--neba-radius-lg)",xl:"rounded-l-(--neba-radius-xl)"},top:{xs:"rounded-b-(--neba-radius-xs)",sm:"rounded-b-(--neba-radius-sm)",md:"rounded-b-(--neba-radius-md)",lg:"rounded-b-(--neba-radius-lg)",xl:"rounded-b-(--neba-radius-xl)"},bottom:{xs:"rounded-t-(--neba-radius-xs)",sm:"rounded-t-(--neba-radius-sm)",md:"rounded-t-(--neba-radius-md)",lg:"rounded-t-(--neba-radius-lg)",xl:"rounded-t-(--neba-radius-xl)"}},h={left:"border-r",right:"border-l",top:"border-b",bottom:"border-t"},v={left:"flex-row justify-start",right:"flex-row justify-end",top:"flex-col justify-start",bottom:"flex-col justify-end"},y=[f,"relative flex flex-col overflow-hidden","text-(--neba-fg) bg-(--n-panel-press)","[border-color:var(--n-line)]","[outline:none]"].join(" "),w=["[transition:opacity_var(--neba-duration)_var(--neba-ease)]","data-[starting-style]:opacity-0 data-[ending-style]:opacity-0"].join(" "),j=["fixed inset-0 z-50 bg-(--neba-scrim)","[backdrop-filter:blur(2px)]",w].join(" "),N="border-t [border-color:var(--n-line)]",$=["flex size-[1.6em] shrink-0 cursor-pointer items-center justify-center","rounded-full text-(--neba-muted-fg)","[&_svg]:size-[1.1em] [&_svg]:shrink-0","[transition:background-color_var(--neba-duration)_var(--neba-ease),color_var(--neba-duration)_var(--neba-ease)]","hover:bg-(--n-soft) hover:text-(--neba-fg)","focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:outline-offset-2"].join(" ");export const DrawerClose=n.Close;export function Drawer({side:f="left",mode:_="overlay",size:k="md",color:C="primary",density:z="default",open:B,defaultOpen:D,onOpenChange:O,trigger:P,title:T,description:F,actions:L,dividers:R=!1,showClose:V,locale:q,closeLabel:A,extent:E,rounded:G=!0,modal:H=!0,dismissible:I=!0,className:J,style:K,children:M,...Q}){const S=s(q),U="overlay"===_,W="left"===f||"right"===f,X=V??U,Y=l[z][k],Z=o[z][k],ee=R?`${Y} ${Z}`:Y,re=d(T)||d(F),ae=d(L),ne=void 0===E?null:{[W?"width":"height"]:"number"==typeof E?`${E}px`:E},le=[y,u[k],h[f],G?g[f][k]:"",U?"[box-shadow:var(--neba-shadow-3),var(--neba-plate-glass)]":"[box-shadow:var(--neba-plate-glass)]",U?w:"",W?`h-full max-w-full ${void 0===E?p[k]:""}`:"w-full "+(void 0===E?"max-h-[85%]":""),R?"":`${Z} ${m[k]}`,J??""].filter(Boolean).join(" "),oe=U?n.Title:"h2",se=U?n.Description:"p",ie=r(a,{children:[re||X?r("div",{className:`flex shrink-0 items-start gap-3 ${ee}`,children:[r("div",{className:`flex min-w-0 flex-1 flex-col ${b[k]}`,children:[d(T)?e(oe,{className:`m-0 font-semibold ${c[k]}`,children:T}):null,d(F)?e(se,{className:`m-0 text-(--neba-muted-fg) ${t[k]}`,children:F}):null]}),X?U?e(n.Close,{"aria-label":A??S.action.close,className:$,children:e(i,{})}):e("button",{type:"button","aria-label":A??S.action.close,className:$,onClick:()=>O?.(!1),children:e(i,{})}):null]}):null,d(M)?e("div",{className:["min-h-0 flex-1 overflow-y-auto overscroll-contain",ee,R&&(re||X)?N:"",R?"":"py-1 -my-1"].filter(Boolean).join(" "),children:M}):null,ae?e("div",{className:["flex shrink-0 flex-wrap items-center justify-end gap-2",ee,R?N:""].filter(Boolean).join(" "),children:L}):null]});return U?r(n.Root,{open:B,defaultOpen:D,modal:H,disablePointerDismissal:!I,onOpenChange:(e,r)=>{I||e||"escape-key"!==r.reason?O?.(e):r.cancel()},children:[P?e(n.Trigger,{render:P}):null,r(n.Portal,{children:[e(n.Backdrop,{className:`neba-portal ${j}`}),e(n.Viewport,{className:`neba-portal fixed inset-0 z-50 flex ${v[f]}`,children:e(n.Popup,{className:le,style:{...x(C,3),...ne,...K},...Q,children:ie})})]})]}):B??D??1?e("div",{className:le,style:{...x(C,0),...ne,...K},children:ie}):null}
@@ -6,7 +6,7 @@ export interface FileRejection {
6
6
  file: File;
7
7
  reason: FileRejectionReason;
8
8
  }
9
- export interface FilePickerProps extends NebaStyleProps {
9
+ export interface FilePickerProps extends NebaStyleProps, Omit<React.ComponentPropsWithoutRef<'div'>, 'color' | 'defaultValue' | 'title' | 'children'> {
10
10
  /**
11
11
  * Drop shadow depth. `0` (the default) is flat.
12
12
  * @default 0
@@ -69,8 +69,6 @@ export interface FilePickerProps extends NebaStyleProps {
69
69
  /** Identifies the field when a form is submitted. */
70
70
  name?: string;
71
71
  id?: string;
72
- className?: string;
73
- style?: React.CSSProperties;
74
72
  }
75
73
  /**
76
74
  * `1.4 MB`, in the units a person reading a file list expects.
@@ -1 +1 @@
1
- import{jsx as e,jsxs as r}from"react/jsx-runtime";import*as n from"react";import{CloseIcon as t}from"../../internal/icons";import{controlTextLeadingClasses as a,disabledClasses as l,gapClasses as o,hasContent as i,iconClasses as s,metaTextClasses as c,radiusClasses as d,readOnlyFilterClasses as u,sheetTitleClasses as f,stackGapClasses as p,surfaceClasses as m,surfaceSlots as h,transitionClasses as b}from"../../internal/styles";const v={default:{xs:"p-4",sm:"p-5",md:"p-6",lg:"p-8",xl:"p-10"},compact:{xs:"p-2",sm:"p-3",md:"p-4",lg:"p-5",xl:"p-6"}},x={solid:[m,"border-2 border-dashed text-(--neba-fg) bg-(--n-panel-hover)","[border-color:var(--n-line)]","[box-shadow:var(--n-elev),var(--neba-plate-glass)]"].join(" "),outline:[m,"border-2 border-dashed text-(--neba-fg) bg-(--n-panel)","[border-color:var(--n-line)]","[box-shadow:var(--n-elev),var(--neba-plate-glass)]"].join(" "),text:"border-2 border-dashed text-(--neba-fg) bg-transparent [border-color:var(--n-line)]"},g={solid:"hover:bg-(--n-panel-press) hover:[border-color:var(--n-line-hover)]",outline:"hover:bg-(--n-panel-hover) hover:[border-color:var(--n-line-hover)]",text:"hover:bg-(--n-soft) hover:[border-color:var(--n-line-hover)]"};function y(){return r("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:[e("path",{d:"M8 10.5V2.75m0 0L5.25 5.5M8 2.75 10.75 5.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"}),e("path",{d:"M2.75 9.75v1.75a1.75 1.75 0 0 0 1.75 1.75h7a1.75 1.75 0 0 0 1.75-1.75V9.75",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]})}export function formatFileSize(e){if(e<1e3)return`${e} B`;const r=["kB","MB","GB","TB"];let n=e/1e3,t=0;for(;n>=1e3&&t<r.length-1;)n/=1e3,t+=1;return`${n<10?n.toFixed(1):Math.round(n)} ${r[t]}`}function k(e,r){const n=e.name.toLowerCase(),t=e.type.toLowerCase();return r.split(",").map(e=>e.trim().toLowerCase()).filter(Boolean).some(e=>e.startsWith(".")?n.endsWith(e):e.endsWith("/*")?t.startsWith(`${e.slice(0,-1)}`):t===e)}export const FilePicker=n.forwardRef(function({variant:m="outline",size:N="md",color:$="primary",density:j="default",elevation:w=0,accept:z,multiple:C=!1,maxSize:_,maxFiles:L,value:B,defaultValue:D,onFilesChange:I,onReject:F,label:M,description:W,error:S,invalid:R,title:T,hint:V,icon:E,showList:O=!0,removeLabel:q=e=>`Remove ${e}`,fullWidth:A=!0,disabled:P=!1,readOnly:G=!1,required:H=!1,name:Y,id:J,className:K,style:Q},U){const X=n.useRef(null);n.useImperativeHandle(U,()=>X.current);const[Z,ee]=n.useState(()=>[...D??[]]),re=B?[...B]:Z,ne=n.useRef(0),[te,ae]=n.useState(!1),le=i(S),oe=R??le,ie=oe?"danger":$,se=P||G,ce=n.useId(),de=n.useCallback(e=>{B||ee(e),I?.(e)},[I,B]),ue=n.useCallback(e=>{const r=[],n=[],t=C?L??Number.POSITIVE_INFINITY:1,a=C?re.length:0;for(const l of e)z&&!k(l,z)?n.push({file:l,reason:"type"}):void 0!==_&&l.size>_?n.push({file:l,reason:"size"}):a+r.length>=t?n.push({file:l,reason:"count"}):r.push(l);return{kept:r,rejections:n}},[z,re.length,L,_,C]),fe=n.useCallback(e=>{const{kept:r,rejections:n}=ue(e);n.length>0&&F?.(n),r.length>0&&de(C?[...re,...r]:r)},[ue,de,re,C,F]),pe=["flex w-full flex-col items-center justify-center text-center","cursor-pointer select-none",v[j][N],d[N],o[N],b,s,"focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:outline-offset-2",P?`${l[m]} border-2 border-dashed`:G?`${x[m]} ${u} cursor-default`:x[m],se?"":g[m],te&&!se?"bg-(--n-soft-press) [border-color:var(--n-ring)]":""].filter(Boolean).join(" ");return r("div",{className:["flex-col align-top",p[N],A?"flex w-full":"inline-flex",K??""].filter(Boolean).join(" "),style:{...h(ie,w),...Q},children:[i(M)?e("span",{className:[c[N],"font-medium",P?"text-(--neba-disabled-fg)":"text-(--neba-fg)"].join(" "),children:M}):null,r("div",{className:"flex w-full flex-col",onDragEnter:e=>{se||(e.preventDefault(),ne.current+=1,ae(!0))},onDragOver:e=>{se||(e.preventDefault(),e.dataTransfer.dropEffect="copy")},onDragLeave:()=>{se||(ne.current=Math.max(0,ne.current-1),0===ne.current&&ae(!1))},onDrop:e=>{se||(e.preventDefault(),ne.current=0,ae(!1),fe(Array.from(e.dataTransfer.files)))},children:[r("button",{type:"button",id:J,disabled:P,"aria-describedby":i(W)||le?ce:void 0,"aria-invalid":oe||void 0,className:pe,onClick:()=>{se||X.current&&(X.current.value="",X.current.click())},children:[void 0===E?e("span",{className:"flex items-center text-(--n-accent) [&_svg]:size-[1.8em]",children:e(y,{})}):i(E)?e("span",{className:"flex items-center text-(--n-accent) [&_svg]:size-[1.8em]",children:E}):null,e("span",{className:`font-medium ${f[N]}`,children:T??"Drop files here, or click to browse"}),i(V)?e("span",{className:`text-(--neba-muted-fg) ${c[N]}`,children:V}):null]}),e("input",{ref:X,type:"file",name:Y,accept:z,multiple:C,required:H&&0===re.length,disabled:se,tabIndex:-1,"aria-hidden":"true",className:"absolute size-px overflow-hidden opacity-0 [clip-path:inset(50%)]",onChange:e=>fe(Array.from(e.target.files??[]))})]}),O&&re.length>0?e("ul",{role:"list",className:`flex w-full flex-col ${p[N]} m-0 list-none p-0`,children:re.map((n,l)=>r("li",{className:["flex w-full items-center gap-2 px-2 py-1.5",d.xs,a[N],"bg-(--n-soft) text-(--neba-fg)"].join(" "),children:[e("span",{className:"min-w-0 flex-1 truncate",children:n.name}),e("span",{className:`shrink-0 text-(--neba-muted-fg) tabular-nums ${c[N]}`,children:formatFileSize(n.size)}),se?null:e("button",{type:"button","aria-label":q(n.name),className:["inline-flex shrink-0 cursor-pointer items-center justify-center rounded-full","size-[1.3em] text-(--neba-muted-fg) opacity-70","[transition:opacity_var(--neba-duration)_var(--neba-ease),color_var(--neba-duration)_var(--neba-ease)]","[&_svg]:size-[0.9em]","hover:text-(--neba-fg) hover:opacity-100 focus-visible:opacity-100","focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:outline-offset-1"].join(" "),onClick:()=>de(re.filter((e,r)=>r!==l)),children:e(t,{})})]},`${n.name}-${n.size}-${n.lastModified}-${l}`))}):null,i(W)&&!le?e("span",{id:ce,className:`${c[N]} text-(--neba-muted-fg)`,children:W}):null,le?e("span",{id:ce,className:`${c[N]} text-(--n-accent)`,children:S}):null]})});
1
+ import{jsx as e,jsxs as r}from"react/jsx-runtime";import*as n from"react";import{CloseIcon as t}from"../../internal/icons";import{controlTextLeadingClasses as a,disabledClasses as l,gapClasses as o,hasContent as i,iconClasses as s,metaTextClasses as c,radiusClasses as d,readOnlyFilterClasses as u,sheetTitleClasses as f,stackGapClasses as p,surfaceClasses as m,surfaceSlots as h,transitionClasses as b}from"../../internal/styles";const v={default:{xs:"p-4",sm:"p-5",md:"p-6",lg:"p-8",xl:"p-10"},compact:{xs:"p-2",sm:"p-3",md:"p-4",lg:"p-5",xl:"p-6"}},x={solid:[m,"border-2 border-dashed text-(--neba-fg) bg-(--n-panel-hover)","[border-color:var(--n-line)]","[box-shadow:var(--n-elev),var(--neba-plate-glass)]"].join(" "),outline:[m,"border-2 border-dashed text-(--neba-fg) bg-(--n-panel)","[border-color:var(--n-line)]","[box-shadow:var(--n-elev),var(--neba-plate-glass)]"].join(" "),text:"border-2 border-dashed text-(--neba-fg) bg-transparent [border-color:var(--n-line)]"},g={solid:"hover:bg-(--n-panel-press) hover:[border-color:var(--n-line-hover)]",outline:"hover:bg-(--n-panel-hover) hover:[border-color:var(--n-line-hover)]",text:"hover:bg-(--n-soft) hover:[border-color:var(--n-line-hover)]"};function y(){return r("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:[e("path",{d:"M8 10.5V2.75m0 0L5.25 5.5M8 2.75 10.75 5.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"}),e("path",{d:"M2.75 9.75v1.75a1.75 1.75 0 0 0 1.75 1.75h7a1.75 1.75 0 0 0 1.75-1.75V9.75",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]})}export function formatFileSize(e){if(e<1e3)return`${e} B`;const r=["kB","MB","GB","TB"];let n=e/1e3,t=0;for(;n>=1e3&&t<r.length-1;)n/=1e3,t+=1;return`${n<10?n.toFixed(1):Math.round(n)} ${r[t]}`}function k(e,r){const n=e.name.toLowerCase(),t=e.type.toLowerCase();return r.split(",").map(e=>e.trim().toLowerCase()).filter(Boolean).some(e=>e.startsWith(".")?n.endsWith(e):e.endsWith("/*")?t.startsWith(`${e.slice(0,-1)}`):t===e)}export const FilePicker=n.forwardRef(function({variant:m="outline",size:N="md",color:$="primary",density:j="default",elevation:w=0,accept:z,multiple:C=!1,maxSize:_,maxFiles:L,value:B,defaultValue:D,onFilesChange:I,onReject:M,label:F,description:W,error:S,invalid:R,title:T,hint:V,icon:E,showList:O=!0,removeLabel:q=e=>`Remove ${e}`,fullWidth:A=!0,disabled:P=!1,readOnly:G=!1,required:H=!1,name:Y,id:J,className:K,style:Q,...U},X){const Z=n.useRef(null);n.useImperativeHandle(X,()=>Z.current);const[ee,re]=n.useState(()=>[...D??[]]),ne=n.useMemo(()=>B?[...B]:ee,[B,ee]),te=n.useRef(0),[ae,le]=n.useState(!1),oe=i(S),ie=R??oe,se=ie?"danger":$,ce=P||G,de=n.useId(),ue=n.useCallback(e=>{B||re(e),I?.(e)},[I,B]),fe=n.useCallback(e=>{const r=[],n=[],t=C?L??Number.POSITIVE_INFINITY:1,a=C?ne.length:0;for(const l of e)z&&!k(l,z)?n.push({file:l,reason:"type"}):void 0!==_&&l.size>_?n.push({file:l,reason:"size"}):a+r.length>=t?n.push({file:l,reason:"count"}):r.push(l);return{kept:r,rejections:n}},[z,ne.length,L,_,C]),pe=n.useCallback(e=>{const{kept:r,rejections:n}=fe(e);n.length>0&&M?.(n),r.length>0&&ue(C?[...ne,...r]:r)},[fe,ue,ne,C,M]),me=["flex w-full flex-col items-center justify-center text-center","cursor-pointer select-none",v[j][N],d[N],o[N],b,s,"focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:outline-offset-2",P?`${l[m]} border-2 border-dashed`:G?`${x[m]} ${u} cursor-default`:x[m],ce?"":g[m],ae&&!ce?"bg-(--n-soft-press) [border-color:var(--n-ring)]":""].filter(Boolean).join(" ");return r("div",{className:["flex-col align-top",p[N],A?"flex w-full":"inline-flex",K??""].filter(Boolean).join(" "),style:{...h(se,w),...Q},...U,children:[i(F)?e("span",{className:[c[N],"font-medium",P?"text-(--neba-disabled-fg)":"text-(--neba-fg)"].join(" "),children:F}):null,r("div",{className:"flex w-full flex-col",onDragEnter:e=>{ce||(e.preventDefault(),te.current+=1,le(!0))},onDragOver:e=>{ce||(e.preventDefault(),e.dataTransfer.dropEffect="copy")},onDragLeave:()=>{ce||(te.current=Math.max(0,te.current-1),0===te.current&&le(!1))},onDrop:e=>{ce||(e.preventDefault(),te.current=0,le(!1),pe(Array.from(e.dataTransfer.files)))},children:[r("button",{type:"button",id:J,disabled:P,"aria-describedby":i(W)||oe?de:void 0,"aria-invalid":ie||void 0,className:me,onClick:()=>{ce||Z.current&&(Z.current.value="",Z.current.click())},children:[void 0===E?e("span",{className:"flex items-center text-(--n-accent) [&_svg]:size-[1.8em]",children:e(y,{})}):i(E)?e("span",{className:"flex items-center text-(--n-accent) [&_svg]:size-[1.8em]",children:E}):null,e("span",{className:`font-medium ${f[N]}`,children:T??"Drop files here, or click to browse"}),i(V)?e("span",{className:`text-(--neba-muted-fg) ${c[N]}`,children:V}):null]}),e("input",{ref:Z,type:"file",name:Y,accept:z,multiple:C,required:H&&0===ne.length,disabled:ce,tabIndex:-1,"aria-hidden":"true",className:"absolute size-px overflow-hidden opacity-0 [clip-path:inset(50%)]",onChange:e=>pe(Array.from(e.target.files??[]))})]}),O&&ne.length>0?e("ul",{role:"list",className:`flex w-full flex-col ${p[N]} m-0 list-none p-0`,children:ne.map((n,l)=>r("li",{className:["flex w-full items-center gap-2 px-2 py-1.5",d.xs,a[N],"bg-(--n-soft) text-(--neba-fg)"].join(" "),children:[e("span",{className:"min-w-0 flex-1 truncate",children:n.name}),e("span",{className:`shrink-0 text-(--neba-muted-fg) tabular-nums ${c[N]}`,children:formatFileSize(n.size)}),ce?null:e("button",{type:"button","aria-label":q(n.name),className:["inline-flex shrink-0 cursor-pointer items-center justify-center rounded-full","size-[1.3em] text-(--neba-muted-fg) opacity-70","[transition:opacity_var(--neba-duration)_var(--neba-ease),color_var(--neba-duration)_var(--neba-ease)]","[&_svg]:size-[0.9em]","hover:text-(--neba-fg) hover:opacity-100 focus-visible:opacity-100","focus-visible:[outline:2px_solid_var(--n-ring)] focus-visible:outline-offset-1"].join(" "),onClick:()=>ue(ne.filter((e,r)=>r!==l)),children:e(t,{})})]},`${n.name}-${n.size}-${n.lastModified}-${l}`))}):null,i(W)&&!oe?e("span",{id:de,className:`${c[N]} text-(--neba-muted-fg)`,children:W}):null,oe?e("span",{id:de,className:`${c[N]} text-(--n-accent)`,children:S}):null]})});
@@ -0,0 +1,146 @@
1
+ import * as React from 'react';
2
+ import type { NebaCorner, NebaElevation, NebaPosition, NebaStyleProps } from '../../types';
3
+ /**
4
+ * Where a floating button sits, with one value the shared vocabulary does not
5
+ * have.
6
+ *
7
+ * `absolute` is not a second spelling of anything in `NebaPosition` — it is the
8
+ * fourth CSS value, and it is the one that makes a floating button belong to a
9
+ * *region* rather than to the window: a FAB in a card, in a map, on the screen
10
+ * of a Mockup. Without it, the only way to pin one inside a box is a wrapper
11
+ * with a `position` of its own.
12
+ */
13
+ export type FloatingActionButtonPosition = NebaPosition | 'absolute';
14
+ /**
15
+ * Which way the actions fan out from the button.
16
+ *
17
+ * Physical rather than logical, for the reason `NebaSide` gives: above is above
18
+ * in every writing direction. The horizontal axis is deliberately not offered —
19
+ * a dial that fans sideways out of a corner fans into the edge of the screen.
20
+ */
21
+ export type FloatingActionButtonDirection = 'top' | 'bottom';
22
+ export interface FloatingActionButtonProps extends NebaStyleProps, Omit<React.ComponentPropsWithoutRef<'div'>, 'color' | 'onClick'> {
23
+ /** The glyph on the button. @default a plus */
24
+ icon?: React.ReactNode;
25
+ /**
26
+ * What the button does, in words.
27
+ *
28
+ * Required, and the one prop here that is: a button whose whole label is a
29
+ * drawing has no accessible name at all. With `extended` it is also the word
30
+ * written on the button, so the two never say different things.
31
+ */
32
+ label: string;
33
+ /**
34
+ * Writes `label` beside the glyph, which turns the disc into a stadium — the
35
+ * extended floating button, for the one action a screen is about.
36
+ * @default false
37
+ */
38
+ extended?: boolean;
39
+ /**
40
+ * The glyph while the dial is open. Defaults to a × when the button has
41
+ * actions and to nothing at all when it does not; pass the same node as
42
+ * `icon` to keep the glyph unchanged.
43
+ */
44
+ openIcon?: React.ReactNode;
45
+ /**
46
+ * Drop shadow depth. `2` here, against the `0` everything else defaults to,
47
+ * for the reason Pill's is `2`: this button is defined by not being part of
48
+ * the page. Every other control rests on the page and earns its separation
49
+ * from the acrylic edge; this one hovers over whatever is underneath it.
50
+ * @default 2
51
+ */
52
+ elevation?: NebaElevation;
53
+ /**
54
+ * How it sits in the page. `fixed` — the default — pins it to a corner of the
55
+ * window; `absolute` pins it to a corner of the nearest positioned ancestor;
56
+ * `static` puts it back in the flow, which is what a floating button inside a
57
+ * Toolbar is.
58
+ * @default 'fixed'
59
+ */
60
+ position?: FloatingActionButtonPosition;
61
+ /** Which corner it is pinned to. @default 'bottom-end' */
62
+ corner?: NebaCorner;
63
+ /**
64
+ * How far in from both edges, as a CSS length or a number of pixels.
65
+ * @default 16
66
+ */
67
+ offset?: number | string;
68
+ /**
69
+ * Which way the actions fan out. Taken from `corner` when it is left out — up
70
+ * from the bottom of the screen, down from the top — which is right often
71
+ * enough that it is rarely written down.
72
+ */
73
+ direction?: FloatingActionButtonDirection;
74
+ /** Whether the dial is open. Use with `onOpenChange` for a controlled dial. */
75
+ open?: boolean;
76
+ /** Where an uncontrolled dial starts. @default false */
77
+ defaultOpen?: boolean;
78
+ onOpenChange?: (open: boolean) => void;
79
+ /**
80
+ * Opens the dial when a mouse comes to rest on the button. Touch and pen are
81
+ * excluded: there is no hovering with a finger, and a dial that opened on the
82
+ * first half of a tap would swallow the second.
83
+ * @default true
84
+ */
85
+ openOnHover?: boolean;
86
+ /**
87
+ * Closes the dial when one of the actions is pressed.
88
+ * @default true
89
+ */
90
+ closeOnAction?: boolean;
91
+ /**
92
+ * Draws each action's name on a lozenge beside it. Turned off, the names are
93
+ * still read out — they are what `label` is on a FloatingAction.
94
+ * @default true
95
+ */
96
+ showLabels?: boolean;
97
+ /** Unavailable. The button and every action stop answering. */
98
+ disabled?: boolean;
99
+ /**
100
+ * Fires when the button itself is pressed. It still fires when the button has
101
+ * actions, where the press also opens and closes the dial.
102
+ */
103
+ onClick?: React.MouseEventHandler<HTMLButtonElement>;
104
+ /** The FloatingActions, if there are any. */
105
+ children?: React.ReactNode;
106
+ }
107
+ export interface FloatingActionProps extends Omit<React.ComponentPropsWithoutRef<'button'>, 'color'> {
108
+ /** The glyph. */
109
+ icon?: React.ReactNode;
110
+ /** What the action does, in words. Drawn beside it, and always read out. */
111
+ label: string;
112
+ /** Unavailable, but still part of the dial. */
113
+ disabled?: boolean;
114
+ }
115
+ /**
116
+ * The one action a screen is about, floating over it — and, when it is given
117
+ * children, the small set of actions that fan out of it.
118
+ *
119
+ * The button itself is a [Button], unchanged: the variants, the elevation
120
+ * ladder, the pointer light and the press behaviour are the ones every other
121
+ * control has, because two components drawing the same surface from two copies
122
+ * of the same table are two components that will eventually disagree. What is
123
+ * added here is where it sits and what comes out of it.
124
+ *
125
+ * The dial is deliberately not a menu. `role="menu"` is a promise about keyboard
126
+ * behaviour — one tab stop for the set, arrow keys within it, typeahead — and a
127
+ * fan of buttons that claims it without implementing it is worse for a keyboard
128
+ * reader than one that never claimed anything; what a genuine menu wants is
129
+ * [Menu], which is one. What is claimed instead is `aria-expanded` and
130
+ * `aria-controls`, and the actions are ordinary buttons in the tab order right
131
+ * after the one that revealed them.
132
+ *
133
+ * Nothing is transformed on the way in or out. The actions are in the document
134
+ * or they are not, and the glyph swaps rather than spinning — the house rule
135
+ * against moving a control holds hardest on the control that is on top of
136
+ * everything else.
137
+ */
138
+ export declare const FloatingActionButton: React.ForwardRefExoticComponent<FloatingActionButtonProps & React.RefAttributes<HTMLDivElement>>;
139
+ /**
140
+ * One action in the dial.
141
+ *
142
+ * It has no `size`, no `color` and no `variant` of its own: all three belong to
143
+ * the button it came out of, which is the only place they can be set once and
144
+ * mean the same thing for every action.
145
+ */
146
+ export declare const FloatingAction: React.ForwardRefExoticComponent<FloatingActionProps & React.RefAttributes<HTMLButtonElement>>;
@@ -0,0 +1 @@
1
+ import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as o from"react";import{Button as n}from"../button/Button";import{CloseIcon as s,PlusIcon as a}from"../../internal/icons";import{cx as r,hasContent as i,metaTextClasses as l,radiusClasses as c,surfaceClasses as d}from"../../internal/styles";const f=o.createContext({variant:"solid",size:"md",color:"primary",density:"default",elevation:1,showLabels:!0,reversed:!0,close:()=>{}}),p={xs:"xs",sm:"xs",md:"sm",lg:"md",xl:"lg"},m={static:"",absolute:"absolute z-30",sticky:"sticky z-30",fixed:"fixed z-40"},u={"top-start":"top-(--n-fab-offset) start-(--n-fab-offset)","top-end":"top-(--n-fab-offset) end-(--n-fab-offset)","bottom-start":"bottom-(--n-fab-offset) start-(--n-fab-offset)","bottom-end":"bottom-(--n-fab-offset) end-(--n-fab-offset)"},b=r("pointer-events-none max-w-40 truncate select-none","px-2 py-0.5 text-(--neba-fg) bg-(--n-panel)",d,c.xs,"[box-shadow:var(--neba-shadow-1),var(--neba-plate-glass)]");export const FloatingActionButton=o.forwardRef(function({variant:i="solid",size:l="lg",color:c="primary",density:d="default",elevation:b=2,icon:v,label:x,extended:y=!1,openIcon:h,position:g="fixed",corner:w="bottom-end",offset:z=16,direction:C,open:k,defaultOpen:L=!1,onOpenChange:N,openOnHover:E=!0,closeOnAction:P=!0,showLabels:R=!0,disabled:A=!1,className:I,style:O,children:j,onClick:B,onKeyDown:D,onPointerEnter:F,onPointerLeave:K,...T},W){const H=o.useId(),M=o.useRef(null),S=o.useRef(null),[$,q]=o.useState(L),G=void 0!==k,J=o.Children.toArray(j).length>0,Q=(G?k:$)&&J&&!A,U=o.useCallback(e=>{G||q(e),N?.(e)},[G,N]),V=o.useCallback(()=>U(!1),[U]);o.useEffect(()=>{if(!Q)return;const e=e=>{const t=S.current;t&&e.target instanceof Node&&!t.contains(e.target)&&V()};return document.addEventListener("pointerdown",e),()=>document.removeEventListener("pointerdown",e)},[Q,V]);const X=C??(w.startsWith("bottom")?"top":"bottom"),Y=w.endsWith("end"),Z=o.useMemo(()=>({variant:i,size:p[l],color:c,density:d,elevation:b,showLabels:R,reversed:Y,close:P?V:()=>{}}),[i,l,c,d,b,R,Y,P,V]),_=Q&&!1!==h?h??e(s,{}):v??e(a,{});return t("div",{ref:e=>{S.current=e,"function"==typeof W?W(e):W&&(W.current=e)},className:r("flex w-fit","top"===X?"flex-col-reverse":"flex-col",Y?"items-end":"items-start","xs"===l||"sm"===l?"gap-1.5":"gap-2",m[g],"static"===g?"":u[w],I),style:{"--n-fab-offset":"number"==typeof z?`${z}px`:z,...O},onKeyDown:e=>{"Escape"===e.key&&Q&&(e.stopPropagation(),V(),M.current?.focus()),D?.(e)},onPointerEnter:e=>{E&&J&&!A&&"mouse"===e.pointerType&&U(!0),F?.(e)},onPointerLeave:e=>{E&&"mouse"===e.pointerType&&V(),K?.(e)},...T,children:[e(n,{ref:M,variant:i,size:l,color:c,density:d,elevation:b,disabled:A,"aria-label":x,"aria-expanded":J?Q:void 0,"aria-controls":J&&Q?H:void 0,startIcon:_,style:{borderRadius:"9999px"},onClick:e=>{J&&U(!Q),B?.(e)},children:y?x:void 0}),Q?e("div",{id:H,className:r("flex","top"===X?"flex-col-reverse":"flex-col",Y?"items-end":"items-start","xs"===l||"sm"===l?"gap-1.5":"gap-2"),children:e(f.Provider,{value:Z,children:j})}):null]})});export const FloatingAction=o.forwardRef(function({icon:s,label:a,disabled:c=!1,className:d,onClick:p,...m},u){const v=o.useContext(f);return t("div",{className:r("flex items-center gap-2",v.reversed?"flex-row-reverse":"flex-row",d),children:[e(n,{ref:u,variant:v.variant,size:v.size,color:v.color,density:v.density,elevation:v.elevation,disabled:c,"aria-label":a,startIcon:s,style:{borderRadius:"9999px"},onClick:e=>{p?.(e),v.close()},...m}),v.showLabels&&i(a)?e("span",{"aria-hidden":"true",className:r(b,l[v.size]),children:a}):null]})});
@@ -0,0 +1 @@
1
+ export * from './FloatingActionButton';
@@ -0,0 +1 @@
1
+ export*from"./FloatingActionButton";