neba 0.0.1 → 1.1.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 (224) hide show
  1. package/README.md +177 -2
  2. package/dist/components/accordion/Accordion.d.ts +97 -0
  3. package/dist/components/accordion/Accordion.js +1 -0
  4. package/dist/components/accordion/index.d.ts +2 -0
  5. package/dist/components/accordion/index.js +1 -0
  6. package/dist/components/alert/Alert.d.ts +47 -0
  7. package/dist/components/alert/Alert.js +1 -0
  8. package/dist/components/alert/index.d.ts +2 -0
  9. package/dist/components/alert/index.js +1 -0
  10. package/dist/components/badge/Badge.d.ts +80 -0
  11. package/dist/components/badge/Badge.js +1 -0
  12. package/dist/components/badge/index.d.ts +2 -0
  13. package/dist/components/badge/index.js +1 -0
  14. package/dist/components/blockquote/Blockquote.d.ts +65 -0
  15. package/dist/components/blockquote/Blockquote.js +1 -0
  16. package/dist/components/blockquote/index.d.ts +2 -0
  17. package/dist/components/blockquote/index.js +1 -0
  18. package/dist/components/box/Box.d.ts +50 -0
  19. package/dist/components/box/Box.js +1 -0
  20. package/dist/components/box/index.d.ts +2 -0
  21. package/dist/components/box/index.js +1 -0
  22. package/dist/components/button/Button.d.ts +25 -3
  23. package/dist/components/button/Button.js +1 -1
  24. package/dist/components/button/index.d.ts +1 -0
  25. package/dist/components/button-group/ButtonGroup.d.ts +31 -0
  26. package/dist/components/button-group/ButtonGroup.js +1 -0
  27. package/dist/components/button-group/index.d.ts +2 -0
  28. package/dist/components/button-group/index.js +1 -0
  29. package/dist/components/card/Card.d.ts +45 -0
  30. package/dist/components/card/Card.js +1 -0
  31. package/dist/components/card/index.d.ts +2 -0
  32. package/dist/components/card/index.js +1 -0
  33. package/dist/components/carousel/Carousel.d.ts +74 -0
  34. package/dist/components/carousel/Carousel.js +1 -0
  35. package/dist/components/carousel/index.d.ts +2 -0
  36. package/dist/components/carousel/index.js +1 -0
  37. package/dist/components/checkbox/Checkbox.d.ts +39 -0
  38. package/dist/components/checkbox/Checkbox.js +1 -0
  39. package/dist/components/checkbox/index.d.ts +2 -0
  40. package/dist/components/checkbox/index.js +1 -0
  41. package/dist/components/chip/Chip.d.ts +50 -0
  42. package/dist/components/chip/Chip.js +1 -0
  43. package/dist/components/chip/index.d.ts +2 -0
  44. package/dist/components/chip/index.js +1 -0
  45. package/dist/components/combobox/Combobox.d.ts +131 -0
  46. package/dist/components/combobox/Combobox.js +1 -0
  47. package/dist/components/combobox/index.d.ts +2 -0
  48. package/dist/components/combobox/index.js +1 -0
  49. package/dist/components/container/Container.d.ts +55 -0
  50. package/dist/components/container/Container.js +1 -0
  51. package/dist/components/container/index.d.ts +2 -0
  52. package/dist/components/container/index.js +1 -0
  53. package/dist/components/date-picker/DatePicker.d.ts +75 -0
  54. package/dist/components/date-picker/DatePicker.js +1 -0
  55. package/dist/components/date-picker/index.d.ts +2 -0
  56. package/dist/components/date-picker/index.js +1 -0
  57. package/dist/components/date-range-picker/DateRangePicker.d.ts +81 -0
  58. package/dist/components/date-range-picker/DateRangePicker.js +1 -0
  59. package/dist/components/date-range-picker/index.d.ts +2 -0
  60. package/dist/components/date-range-picker/index.js +1 -0
  61. package/dist/components/date-time-picker/DateTimePicker.d.ts +68 -0
  62. package/dist/components/date-time-picker/DateTimePicker.js +1 -0
  63. package/dist/components/date-time-picker/index.d.ts +2 -0
  64. package/dist/components/date-time-picker/index.js +1 -0
  65. package/dist/components/dialog/Dialog.d.ts +111 -0
  66. package/dist/components/dialog/Dialog.js +1 -0
  67. package/dist/components/dialog/index.d.ts +2 -0
  68. package/dist/components/dialog/index.js +1 -0
  69. package/dist/components/divider/Divider.d.ts +67 -0
  70. package/dist/components/divider/Divider.js +1 -0
  71. package/dist/components/divider/index.d.ts +2 -0
  72. package/dist/components/divider/index.js +1 -0
  73. package/dist/components/file-picker/FilePicker.d.ts +103 -0
  74. package/dist/components/file-picker/FilePicker.js +1 -0
  75. package/dist/components/file-picker/index.d.ts +2 -0
  76. package/dist/components/file-picker/index.js +1 -0
  77. package/dist/components/grid/Grid.d.ts +50 -0
  78. package/dist/components/grid/Grid.js +1 -0
  79. package/dist/components/grid/index.d.ts +2 -0
  80. package/dist/components/grid/index.js +1 -0
  81. package/dist/components/grid-container/GridContainer.d.ts +79 -0
  82. package/dist/components/grid-container/GridContainer.js +1 -0
  83. package/dist/components/grid-container/index.d.ts +2 -0
  84. package/dist/components/grid-container/index.js +1 -0
  85. package/dist/components/highlight/Highlight.d.ts +84 -0
  86. package/dist/components/highlight/Highlight.js +1 -0
  87. package/dist/components/highlight/index.d.ts +2 -0
  88. package/dist/components/highlight/index.js +1 -0
  89. package/dist/components/icon/Icon.d.ts +58 -0
  90. package/dist/components/icon/Icon.js +1 -0
  91. package/dist/components/icon/index.d.ts +2 -0
  92. package/dist/components/icon/index.js +1 -0
  93. package/dist/components/icon-button/IconButton.d.ts +39 -0
  94. package/dist/components/icon-button/IconButton.js +1 -0
  95. package/dist/components/icon-button/index.d.ts +2 -0
  96. package/dist/components/icon-button/index.js +1 -0
  97. package/dist/components/list/List.d.ts +81 -0
  98. package/dist/components/list/List.js +1 -0
  99. package/dist/components/list/index.d.ts +2 -0
  100. package/dist/components/list/index.js +1 -0
  101. package/dist/components/menu/Menu.d.ts +216 -0
  102. package/dist/components/menu/Menu.js +1 -0
  103. package/dist/components/menu/index.d.ts +2 -0
  104. package/dist/components/menu/index.js +1 -0
  105. package/dist/components/number-field/NumberField.d.ts +113 -0
  106. package/dist/components/number-field/NumberField.js +1 -0
  107. package/dist/components/number-field/index.d.ts +2 -0
  108. package/dist/components/number-field/index.js +1 -0
  109. package/dist/components/overlay/Overlay.d.ts +85 -0
  110. package/dist/components/overlay/Overlay.js +1 -0
  111. package/dist/components/overlay/index.d.ts +2 -0
  112. package/dist/components/overlay/index.js +1 -0
  113. package/dist/components/pagination/Pagination.d.ts +65 -0
  114. package/dist/components/pagination/Pagination.js +1 -0
  115. package/dist/components/pagination/index.d.ts +2 -0
  116. package/dist/components/pagination/index.js +1 -0
  117. package/dist/components/pill/Pill.d.ts +80 -0
  118. package/dist/components/pill/Pill.js +1 -0
  119. package/dist/components/pill/index.d.ts +2 -0
  120. package/dist/components/pill/index.js +1 -0
  121. package/dist/components/progress-box/ProgressBox.d.ts +33 -0
  122. package/dist/components/progress-box/ProgressBox.js +1 -0
  123. package/dist/components/progress-box/index.d.ts +2 -0
  124. package/dist/components/progress-box/index.js +1 -0
  125. package/dist/components/progress-circular/ProgressCircular.d.ts +19 -0
  126. package/dist/components/progress-circular/ProgressCircular.js +1 -0
  127. package/dist/components/progress-circular/index.d.ts +2 -0
  128. package/dist/components/progress-circular/index.js +1 -0
  129. package/dist/components/progress-linear/ProgressLinear.d.ts +20 -0
  130. package/dist/components/progress-linear/ProgressLinear.js +1 -0
  131. package/dist/components/progress-linear/index.d.ts +2 -0
  132. package/dist/components/progress-linear/index.js +1 -0
  133. package/dist/components/radio-group/RadioGroup.d.ts +51 -0
  134. package/dist/components/radio-group/RadioGroup.js +1 -0
  135. package/dist/components/radio-group/index.d.ts +2 -0
  136. package/dist/components/radio-group/index.js +1 -0
  137. package/dist/components/segmented-button/SegmentedButton.d.ts +77 -0
  138. package/dist/components/segmented-button/SegmentedButton.js +1 -0
  139. package/dist/components/segmented-button/index.d.ts +2 -0
  140. package/dist/components/segmented-button/index.js +1 -0
  141. package/dist/components/select/Select.d.ts +76 -0
  142. package/dist/components/select/Select.js +1 -0
  143. package/dist/components/select/index.d.ts +2 -0
  144. package/dist/components/select/index.js +1 -0
  145. package/dist/components/shortcut/Shortcut.d.ts +60 -0
  146. package/dist/components/shortcut/Shortcut.js +1 -0
  147. package/dist/components/shortcut/index.d.ts +2 -0
  148. package/dist/components/shortcut/index.js +1 -0
  149. package/dist/components/slider/Slider.d.ts +38 -0
  150. package/dist/components/slider/Slider.js +1 -0
  151. package/dist/components/slider/index.d.ts +2 -0
  152. package/dist/components/slider/index.js +1 -0
  153. package/dist/components/statistic/Statistic.d.ts +91 -0
  154. package/dist/components/statistic/Statistic.js +1 -0
  155. package/dist/components/statistic/index.d.ts +2 -0
  156. package/dist/components/statistic/index.js +1 -0
  157. package/dist/components/switch/Switch.d.ts +39 -0
  158. package/dist/components/switch/Switch.js +1 -0
  159. package/dist/components/switch/index.d.ts +2 -0
  160. package/dist/components/switch/index.js +1 -0
  161. package/dist/components/table/Table.d.ts +80 -0
  162. package/dist/components/table/Table.js +1 -0
  163. package/dist/components/table/index.d.ts +2 -0
  164. package/dist/components/table/index.js +1 -0
  165. package/dist/components/tabs/Tabs.d.ts +92 -0
  166. package/dist/components/tabs/Tabs.js +1 -0
  167. package/dist/components/tabs/index.d.ts +2 -0
  168. package/dist/components/tabs/index.js +1 -0
  169. package/dist/components/text-field/TextField.d.ts +63 -0
  170. package/dist/components/text-field/TextField.js +1 -0
  171. package/dist/components/text-field/index.d.ts +2 -0
  172. package/dist/components/text-field/index.js +1 -0
  173. package/dist/components/time-picker/TimePicker.d.ts +76 -0
  174. package/dist/components/time-picker/TimePicker.js +1 -0
  175. package/dist/components/time-picker/index.d.ts +2 -0
  176. package/dist/components/time-picker/index.js +1 -0
  177. package/dist/components/timeline/Timeline.d.ts +98 -0
  178. package/dist/components/timeline/Timeline.js +1 -0
  179. package/dist/components/timeline/index.d.ts +2 -0
  180. package/dist/components/timeline/index.js +1 -0
  181. package/dist/components/toast/Toast.d.ts +116 -0
  182. package/dist/components/toast/Toast.js +1 -0
  183. package/dist/components/toast/index.d.ts +2 -0
  184. package/dist/components/toast/index.js +1 -0
  185. package/dist/components/toolbar/Toolbar.d.ts +67 -0
  186. package/dist/components/toolbar/Toolbar.js +1 -0
  187. package/dist/components/toolbar/index.d.ts +2 -0
  188. package/dist/components/toolbar/index.js +1 -0
  189. package/dist/components/tooltip/Tooltip.d.ts +81 -0
  190. package/dist/components/tooltip/Tooltip.js +1 -0
  191. package/dist/components/tooltip/index.d.ts +2 -0
  192. package/dist/components/tooltip/index.js +1 -0
  193. package/dist/components/typography/Typography.d.ts +62 -0
  194. package/dist/components/typography/Typography.js +1 -0
  195. package/dist/components/typography/index.d.ts +2 -0
  196. package/dist/components/typography/index.js +1 -0
  197. package/dist/index.d.ts +50 -1
  198. package/dist/index.js +1 -1
  199. package/dist/internal/button-group.d.ts +25 -0
  200. package/dist/internal/button-group.js +1 -0
  201. package/dist/internal/calendar.d.ts +149 -0
  202. package/dist/internal/calendar.js +1 -0
  203. package/dist/internal/date.d.ts +170 -0
  204. package/dist/internal/date.js +1 -0
  205. package/dist/internal/grid.d.ts +69 -0
  206. package/dist/internal/grid.js +1 -0
  207. package/dist/internal/icons.d.ts +79 -0
  208. package/dist/internal/icons.js +1 -0
  209. package/dist/internal/menu.d.ts +20 -0
  210. package/dist/internal/menu.js +1 -0
  211. package/dist/internal/picker.d.ts +111 -0
  212. package/dist/internal/picker.js +1 -0
  213. package/dist/internal/progress.d.ts +122 -0
  214. package/dist/internal/progress.js +1 -0
  215. package/dist/internal/sizer.d.ts +33 -0
  216. package/dist/internal/sizer.js +1 -0
  217. package/dist/internal/styles.d.ts +257 -0
  218. package/dist/internal/styles.js +1 -0
  219. package/dist/styles.css +2 -0
  220. package/dist/tailwind.css +892 -0
  221. package/dist/types.d.ts +142 -0
  222. package/dist/types.js +8 -0
  223. package/package.json +90 -21
  224. package/pnpm-workspace.yaml +0 -2
@@ -0,0 +1,75 @@
1
+ import * as React from 'react';
2
+ import { type PickerLabels } from '../../internal/calendar';
3
+ import { type PickerShellProps } from '../../internal/picker';
4
+ import type { NebaWeekday } from '../../types';
5
+ /**
6
+ * What the four pickers agree on, so a caller who has learned one has learned
7
+ * the others. Spelled out here rather than in `internal/` because these are the
8
+ * props a reader of the docs is actually looking at.
9
+ */
10
+ export interface DatePickerProps extends PickerShellProps {
11
+ /** The chosen day. Use with `onValueChange` for a controlled picker. */
12
+ value?: Date | null;
13
+ /** The day the picker starts on, for an uncontrolled one. */
14
+ defaultValue?: Date | null;
15
+ onValueChange?: (value: Date | null) => void;
16
+ /** Whether the calendar is open. Use with `onOpenChange` to control it. */
17
+ open?: boolean;
18
+ defaultOpen?: boolean;
19
+ onOpenChange?: (open: boolean) => void;
20
+ /** Which month the calendar opens on when there is no value. @default this one */
21
+ defaultMonth?: Date;
22
+ /** The earliest day that may be chosen. Day-granular — the time is ignored. */
23
+ minDate?: Date | null;
24
+ /** The latest day that may be chosen. */
25
+ maxDate?: Date | null;
26
+ /**
27
+ * Blocks individual days that are inside the range but still not available —
28
+ * weekends, holidays, a room that is already booked.
29
+ */
30
+ shouldDisableDate?: (date: Date) => boolean;
31
+ /**
32
+ * BCP 47 tag deciding the month and weekday names, the order of the header's
33
+ * two buttons, and how the trigger writes the date. Defaults to the browser's.
34
+ */
35
+ locale?: string;
36
+ /** Which day the week starts on. Defaults to whatever the locale says. */
37
+ weekStartsOn?: NebaWeekday;
38
+ /**
39
+ * How the trigger writes the chosen date. Passed straight to `Intl`, so
40
+ * `{ dateStyle: 'full' }` and `{ year: '2-digit', month: 'narrow' }` both work.
41
+ * @default { dateStyle: 'medium' }
42
+ */
43
+ format?: Intl.DateTimeFormatOptions;
44
+ /** Shown in the trigger while nothing is chosen. */
45
+ placeholder?: React.ReactNode;
46
+ /** Offers the × that empties the control. @default false */
47
+ clearable?: boolean;
48
+ /** Offers the shortcut to today in the footer. @default true */
49
+ showTodayButton?: boolean;
50
+ /** Closes the popup as soon as a day is chosen. @default true */
51
+ closeOnSelect?: boolean;
52
+ /** The strings a screen reader hears. Every one has an English default. */
53
+ labels?: Partial<PickerLabels>;
54
+ /** Identifies the field when a form is submitted, as `YYYY-MM-DD`. */
55
+ name?: string;
56
+ }
57
+ /**
58
+ * One day, chosen from a calendar.
59
+ *
60
+ * The trigger is a TextField's shell wearing a calendar glyph, on purpose and
61
+ * for the reason Select's is: a form where the date field is a different height,
62
+ * radius or colour from the fields around it is a form that looks assembled.
63
+ *
64
+ * What the calendar is actually for is the header. A picker that only steps a
65
+ * month at a time puts a birthday thirty years back a hundred and eighty clicks
66
+ * away, so the month name and the year are each a button that opens a grid of
67
+ * its own — twelve months, then twelve years at a time. Any month of the year on
68
+ * screen is two clicks; any year at all is three.
69
+ *
70
+ * There is no typing into the trigger. Parsing a date out of free text is
71
+ * locale-dependent in a way that cannot be done honestly without a date library,
72
+ * and a field that understands `27/7/26` in one browser and not in the next is
73
+ * worse than one that never claimed to.
74
+ */
75
+ export declare const DatePicker: React.ForwardRefExoticComponent<DatePickerProps & React.RefAttributes<HTMLButtonElement>>;
@@ -0,0 +1 @@
1
+ import{jsx as e,jsxs as a}from"react/jsx-runtime";import*as t from"react";import{Button as l}from"../button/Button";import{Calendar as o,usePickerLabels as n}from"../../internal/calendar";import{CalendarIcon as r}from"../../internal/icons";import{PickerFooter as i,PickerShell as s}from"../../internal/picker";import{displaySamples as c,formatDate as d,isDayOutside as m,isValidDate as u,localeWeekStart as p,mergeDateAndTime as f,startOfDay as h,startOfMonth as b,toISODate as y,today as x,withPlaceholder as v}from"../../internal/date";import{cx as D}from"../../internal/styles";export const DatePicker=t.forwardRef(function({value:O,defaultValue:S,onValueChange:g,open:C,defaultOpen:k,onOpenChange:z,defaultMonth:w,minDate:j,maxDate:M,shouldDisableDate:V,locale:B,weekStartsOn:I,format:R={dateStyle:"medium"},placeholder:E,clearable:F=!1,showTodayButton:N=!0,closeOnSelect:P=!0,labels:T,name:q,size:A="md",color:G="primary",readOnly:H=!1,disabled:J=!1,startIcon:K,...L},Q){const U=n(T),W=I??p(B),[X,Y]=t.useState(S??null),Z=void 0!==O?O:X,[$,_]=t.useState(k??!1),ee=C??$,[ae,te]=t.useState(()=>b(u(Z)?Z:w??x()));t.useEffect(()=>{ee&&te(b(u(Z)?Z:w??x()))},[ee]);const le=e=>{e&&(H||J)||(void 0===C&&_(e),z?.(e))},oe=e=>{void 0===O&&Y(e),g?.(e)},ne=e=>{const a=u(Z)?f(e,Z):h(e);oe(a),te(b(a)),P&&le(!1)},re=x(),ie=m(re,j,M)||(V?.(re)??!1),se=N||F,ce=t.useMemo(()=>v(c(B,R),E),[B,R,E]);return e(s,{...L,size:A,color:G,readOnly:H,disabled:J,triggerRef:Q,startIcon:K??e(r,{}),display:u(Z)?d(Z,B,R):E??"",samples:ce,empty:!u(Z),clearable:F,onClear:()=>oe(null),open:ee,onOpenChange:le,labels:U,hiddenValues:q?[{name:q,value:u(Z)?y(Z):""}]:void 0,children:a("div",{className:D("flex flex-col",se&&"gap-1.5"),children:[e(o,{size:A,color:G,locale:B,weekStartsOn:W,month:ae,onMonthChange:te,selected:[Z],onSelect:ne,minDate:j,maxDate:M,shouldDisableDate:V,labels:U,autoFocus:!0}),se?a(i,{size:A,children:[F?e(l,{variant:"text",size:A,color:G,density:"compact",onClick:()=>{oe(null),le(!1)},children:U.clear}):null,N?e(l,{variant:"text",size:A,color:G,density:"compact",disabled:ie,onClick:()=>ne(re),children:U.today}):null]}):null]})})});
@@ -0,0 +1,2 @@
1
+ export { DatePicker } from './DatePicker';
2
+ export type { DatePickerProps } from './DatePicker';
@@ -0,0 +1 @@
1
+ export{DatePicker}from"./DatePicker";
@@ -0,0 +1,81 @@
1
+ import * as React from 'react';
2
+ import { type PickerLabels } from '../../internal/calendar';
3
+ import { type PickerShellProps } from '../../internal/picker';
4
+ import type { NebaWeekday } from '../../types';
5
+ /**
6
+ * Two ends, either of which may be missing.
7
+ *
8
+ * An object rather than a `[Date, Date]` tuple, and rather than two props. A
9
+ * range is one value — it is chosen in one gesture, cleared in one gesture and
10
+ * validated as a whole — and the two names are what stop a caller writing the
11
+ * end into the start. Half a range is a real state: it is what the picker holds
12
+ * between the first click and the second.
13
+ */
14
+ export interface DateRange {
15
+ start: Date | null;
16
+ end: Date | null;
17
+ }
18
+ /** A named range offered as a shortcut beside the calendars. */
19
+ export interface DateRangePreset {
20
+ label: React.ReactNode;
21
+ /**
22
+ * The range it stands for. A function when it depends on today, which is
23
+ * almost always — "the last 7 days" computed at render time is a range that
24
+ * would be wrong for anyone who left the tab open overnight.
25
+ */
26
+ value: DateRange | (() => DateRange);
27
+ }
28
+ export interface DateRangePickerProps extends PickerShellProps {
29
+ /** The chosen range. Use with `onValueChange` for a controlled picker. */
30
+ value?: DateRange | null;
31
+ defaultValue?: DateRange | null;
32
+ /** Always called with an object. A cleared range is `{ start: null, end: null }`. */
33
+ onValueChange?: (value: DateRange) => void;
34
+ open?: boolean;
35
+ defaultOpen?: boolean;
36
+ onOpenChange?: (open: boolean) => void;
37
+ /** Which month the left calendar opens on when there is no value. */
38
+ defaultMonth?: Date;
39
+ minDate?: Date | null;
40
+ maxDate?: Date | null;
41
+ shouldDisableDate?: (date: Date) => boolean;
42
+ locale?: string;
43
+ weekStartsOn?: NebaWeekday;
44
+ /** @default { dateStyle: 'medium' } */
45
+ format?: Intl.DateTimeFormatOptions;
46
+ /**
47
+ * How many months are on screen at once. Two is the default because a range
48
+ * that crosses a month boundary is the ordinary case, not the exception.
49
+ * @default 2
50
+ */
51
+ monthCount?: 1 | 2;
52
+ /** Shown in each half of the trigger while that end is unchosen. */
53
+ startPlaceholder?: React.ReactNode;
54
+ endPlaceholder?: React.ReactNode;
55
+ /** Shortcuts listed beside the calendars — "Last 7 days", "This month". */
56
+ presets?: readonly DateRangePreset[];
57
+ clearable?: boolean;
58
+ /** Closes the popup once both ends are chosen. @default true */
59
+ closeOnSelect?: boolean;
60
+ labels?: Partial<PickerLabels>;
61
+ /**
62
+ * Identifies the field when a form is submitted. Two hidden inputs of the same
63
+ * name, so the two ends arrive as `FormData.getAll(name)`.
64
+ */
65
+ name?: string;
66
+ }
67
+ /**
68
+ * A span between two days.
69
+ *
70
+ * Two months side by side, because a range that crosses a month boundary is the
71
+ * ordinary case and a one-month picker makes it a two-step navigation problem.
72
+ * The two panels are one calendar in two halves: the left one has no forward
73
+ * stepper, the right one has no back stepper, and either header's month and year
74
+ * buttons move both.
75
+ *
76
+ * The band between the ends is drawn as the pointer moves, before the second
77
+ * click lands. That preview is the whole affordance — without it the first click
78
+ * has no visible consequence and the control looks broken for the second or so
79
+ * between the two.
80
+ */
81
+ export declare const DateRangePicker: React.ForwardRefExoticComponent<DateRangePickerProps & React.RefAttributes<HTMLButtonElement>>;
@@ -0,0 +1 @@
1
+ import{jsx as e,jsxs as l}from"react/jsx-runtime";import*as n from"react";import{Button as a}from"../button/Button";import{Calendar as t,usePickerLabels as r}from"../../internal/calendar";import{ArrowRightIcon as s,CalendarIcon as o}from"../../internal/icons";import{PickerFooter as i,PickerShell as c}from"../../internal/picker";import{WidthSizer as u}from"../../internal/sizer";import{addMonths as d,compareDay as m,displaySamples as h,formatDate as p,isValidDate as f,localeWeekStart as x,startOfDay as v,startOfMonth as g,toISODate as b,today as w,withPlaceholder as y}from"../../internal/date";import{cx as N,gapClasses as S,metaTextClasses as C}from"../../internal/styles";const D={start:null,end:null};export const DateRangePicker=n.forwardRef(function({value:O,defaultValue:k,onValueChange:z,open:P,defaultOpen:j,onOpenChange:B,defaultMonth:M,minDate:R,maxDate:V,shouldDisableDate:E,locale:I,weekStartsOn:F,format:q={dateStyle:"medium"},monthCount:A=2,startPlaceholder:G,endPlaceholder:H,presets:J,clearable:K=!1,closeOnSelect:L=!0,labels:Q,name:T,size:U="md",color:W="primary",readOnly:X=!1,disabled:Y=!1,startIcon:Z,...$},_){const ee=r(Q),le=F??x(I),[ne,ae]=n.useState(k??D),te=void 0!==O?O??D:ne,re=f(te.start)?te.start:null,se=f(te.end)?te.end:null,[oe,ie]=n.useState(j??!1),ce=P??oe,[ue,de]=n.useState(null),[me,he]=n.useState(null),[pe,fe]=n.useState(()=>g(re??M??w()));n.useEffect(()=>{ce?fe(g(re??M??w())):(de(null),he(null))},[ce]);const xe=e=>{e&&(X||Y)||(void 0===P&&ie(e),B?.(e))},ve=e=>{void 0===O&&ae(e),z?.(e)},ge=ue??re,be=null!==ue?me:se,we=(l,n)=>f(l)?p(l,I,q):e("span",{className:"text-(--neba-muted-fg)",children:n??""}),ye=d(pe,1),Ne=2===A,Se=h(I,q),Ce=null!==ue?ee.end:null===re?ee.start:null,De={size:U,color:W,locale:I,weekStartsOn:le,selected:[re,se,ue],rangeStart:ge,rangeEnd:be,onSelect:e=>{const l=v(e);if(null===ue)return de(l),he(l),void ve({start:l,end:null});const[n,a]=m(l,ue)<0?[l,ue]:[ue,l];de(null),he(null),ve({start:n,end:a}),L&&xe(!1)},onPreviewChange:e=>{null!==ue&&he(e??ue)},minDate:R,maxDate:V,shouldDisableDate:E,showOutsideDays:!1,labels:ee};return e(c,{...$,size:U,color:W,readOnly:X,disabled:Y,triggerRef:_,startIcon:Z??e(o,{}),display:l("span",{className:"flex min-w-0 items-center gap-1.5",children:[l("span",{className:"flex min-w-0 flex-col",children:[e("span",{className:"truncate",children:we(re,G)}),e(u,{samples:y(Se,G)})]}),e("span",{"aria-hidden":"true",className:"flex shrink-0 items-center text-(--neba-muted-fg) rtl:rotate-180",children:e(s,{})}),l("span",{className:"flex min-w-0 flex-col",children:[e("span",{className:"truncate",children:we(se,H)}),e(u,{samples:y(Se,H)})]})]}),empty:null===re&&null===se,clearable:K,onClear:()=>ve(D),open:ce,onOpenChange:xe,labels:ee,hiddenValues:T?[{name:T,value:re?b(re):""},{name:T,value:se?b(se):""}]:void 0,children:l("div",{className:"flex flex-col gap-1.5",children:[l("div",{className:N("flex items-stretch",S[U]),children:[J&&J.length>0?e("div",{className:N("flex max-h-[calc(var(--n-cell,2rem)*8)] flex-col overflow-y-auto border-e pe-1.5","[border-color:var(--n-line)]"),children:J.map((l,n)=>e(a,{variant:"text",size:U,color:W,density:"compact",className:"justify-start whitespace-nowrap",onClick:()=>(e=>{const l="function"==typeof e.value?e.value():e.value;de(null),he(null),ve(l),f(l.start)&&fe(g(l.start)),L&&xe(!1)})(l),children:l.label},n))}):null,e(t,{...De,month:pe,onMonthChange:fe,showNextButton:!Ne,autoFocus:!0}),Ne?e(t,{...De,month:ye,onMonthChange:e=>fe(d(e,-1)),showPreviousButton:!1}):null]}),K||null!==Ce?l(i,{size:U,children:[null!==Ce?e("span",{className:N("me-auto text-(--neba-muted-fg)",C[U]),children:Ce}):null,K?e(a,{variant:"text",size:U,color:W,density:"compact",onClick:()=>{de(null),he(null),ve(D),xe(!1)},children:ee.clear}):null]}):null]})})});
@@ -0,0 +1,2 @@
1
+ export { DateRangePicker } from './DateRangePicker';
2
+ export type { DateRange, DateRangePickerProps, DateRangePreset } from './DateRangePicker';
@@ -0,0 +1 @@
1
+ export{DateRangePicker}from"./DateRangePicker";
@@ -0,0 +1,68 @@
1
+ import * as React from 'react';
2
+ import { type PickerLabels } from '../../internal/calendar';
3
+ import { type PickerShellProps } from '../../internal/picker';
4
+ import { type TimeUnit } from '../../internal/date';
5
+ import type { NebaWeekday } from '../../types';
6
+ export interface DateTimePickerProps extends PickerShellProps {
7
+ /** The chosen moment. Use with `onValueChange` for a controlled picker. */
8
+ value?: Date | null;
9
+ defaultValue?: Date | null;
10
+ onValueChange?: (value: Date | null) => void;
11
+ open?: boolean;
12
+ defaultOpen?: boolean;
13
+ onOpenChange?: (open: boolean) => void;
14
+ /** Which month the calendar opens on when there is no value. */
15
+ defaultMonth?: Date;
16
+ /**
17
+ * The earliest moment that may be chosen. Unlike DatePicker's, this one is
18
+ * read at full precision: the day it falls on stays available and the clock
19
+ * columns block the hours before it.
20
+ */
21
+ minDate?: Date | null;
22
+ /** The latest moment that may be chosen, likewise at full precision. */
23
+ maxDate?: Date | null;
24
+ shouldDisableDate?: (date: Date) => boolean;
25
+ shouldDisableTime?: (value: Date, unit: TimeUnit) => boolean;
26
+ locale?: string;
27
+ weekStartsOn?: NebaWeekday;
28
+ /**
29
+ * How the trigger writes the chosen moment. Passed straight to `Intl`.
30
+ * @default { dateStyle: 'medium', timeStyle: 'short' }
31
+ */
32
+ format?: Intl.DateTimeFormatOptions;
33
+ /** A 12-hour dial with an AM/PM column. Defaults to whatever the locale does. */
34
+ hour12?: boolean;
35
+ showSeconds?: boolean;
36
+ hourStep?: number;
37
+ minuteStep?: number;
38
+ secondStep?: number;
39
+ placeholder?: React.ReactNode;
40
+ clearable?: boolean;
41
+ /** Offers the shortcut to this moment in the footer. @default true */
42
+ showNowButton?: boolean;
43
+ /**
44
+ * Closes the popup as soon as a day is chosen. `false` here and `true` on
45
+ * DatePicker, because a moment is a day *and* a time and closing on the first
46
+ * of the two would leave the second one unanswered.
47
+ * @default false
48
+ */
49
+ closeOnSelect?: boolean;
50
+ labels?: Partial<PickerLabels>;
51
+ /** Identifies the field when a form is submitted, as `YYYY-MM-DDTHH:MM`. */
52
+ name?: string;
53
+ }
54
+ /**
55
+ * A day and a time, in one popup.
56
+ *
57
+ * Not a DatePicker that grew a clock and not a TimePicker that grew a calendar:
58
+ * the two panels sit side by side at exactly the same height — seven rows of
59
+ * cells each, which is why the calendar's grid and the clock's columns share the
60
+ * `--n-cell` ladder — so the popup is one rectangle rather than two of different
61
+ * sizes pushed together.
62
+ *
63
+ * The bounds do more work here than anywhere else. `minDate` is read at full
64
+ * precision, so a minimum of 09:30 on the 27th leaves the 27th selectable in the
65
+ * calendar and greys out the morning in the clock. That is the behaviour a
66
+ * "not before now" rule needs, and it is the one a day-granular check cannot give.
67
+ */
68
+ export declare const DateTimePicker: React.ForwardRefExoticComponent<DateTimePickerProps & React.RefAttributes<HTMLButtonElement>>;
@@ -0,0 +1 @@
1
+ import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as l from"react";import{Button as o}from"../button/Button";import{Calendar as n,TimeGrid as a,usePickerLabels as s}from"../../internal/calendar";import{CalendarIcon as i}from"../../internal/icons";import{PickerDivider as r,PickerFooter as c,PickerShell as d}from"../../internal/picker";import{displaySamples as m,formatDate as u,isDayOutside as h,isHour12 as p,isValidDate as f,localeWeekStart as S,mergeDateAndTime as b,startOfDay as y,startOfMonth as D,timeUnitSpan as g,toISODateTime as v,today as x,withPlaceholder as C,withTime as w}from"../../internal/date";import{cx as k,gapClasses as z}from"../../internal/styles";export const DateTimePicker=l.forwardRef(function({value:O,defaultValue:T,onValueChange:j,open:N,defaultOpen:V,onOpenChange:B,defaultMonth:I,minDate:M,maxDate:R,shouldDisableDate:E,shouldDisableTime:F,locale:P,weekStartsOn:q,format:A={dateStyle:"medium",timeStyle:"short"},hour12:G,showSeconds:H=!1,hourStep:J=1,minuteStep:K=1,secondStep:L=1,placeholder:Q,clearable:U=!1,showNowButton:W=!0,closeOnSelect:X=!1,labels:Y,name:Z,size:$="md",color:_="primary",density:ee="default",readOnly:te=!1,disabled:le=!1,startIcon:oe,...ne},ae){const se=s(Y),ie=q??S(P),re=G??p(P),[ce,de]=l.useState(T??null),me=void 0!==O?O:ce,[ue,he]=l.useState(V??!1),pe=N??ue,[fe,Se]=l.useState(()=>D(f(me)?me:I??x()));l.useEffect(()=>{pe&&Se(D(f(me)?me:I??x()))},[pe]);const be=e=>{e&&(te||le)||(void 0===N&&he(e),B?.(e))},ye=e=>{void 0===O&&de(e),j?.(e)},De=l.useCallback((e,t)=>{const[l,o]=g(t,e),n=y(e).getTime();return!!(f(M)&&n+1e3*o<M.getTime())||(!!(f(R)&&n+1e3*l>R.getTime())||(F?.(e,t)??!1))},[M,R,F]),ge=new Date,ve=w(ge,{seconds:H?ge.getSeconds():0}),xe=h(ve,M,R)||(E?.(ve)??!1)||De(ve,"second"),Ce=C(m(P,A),Q);return e(d,{...ne,size:$,color:_,density:ee,readOnly:te,disabled:le,triggerRef:ae,startIcon:oe??e(i,{}),display:f(me)?u(me,P,A):Q??"",samples:Ce,empty:!f(me),clearable:U,onClear:()=>ye(null),open:pe,onOpenChange:be,labels:se,hiddenValues:Z?[{name:Z,value:f(me)?v(me,H):""}]:void 0,children:t("div",{className:"flex flex-col gap-1.5",children:[t("div",{className:k("flex items-stretch",z[$]),children:[e(n,{size:$,color:_,locale:P,weekStartsOn:ie,month:fe,onMonthChange:Se,selected:[me],onSelect:e=>{const t=f(me)?b(e,me):y(e);ye(t),Se(D(t)),X&&be(!1)},minDate:M,maxDate:R,shouldDisableDate:E,labels:se,autoFocus:!0}),e(r,{}),e(a,{size:$,density:ee,locale:P,value:f(me)?me:null,referenceDate:f(me)?me:x(),onChange:ye,hour12:re,showSeconds:H,hourStep:J,minuteStep:K,secondStep:L,shouldDisableTime:De,labels:se})]}),t(c,{size:$,children:[U?e(o,{variant:"text",size:$,color:_,density:"compact",onClick:()=>{ye(null),be(!1)},children:se.clear}):null,W?e(o,{variant:"text",size:$,color:_,density:"compact",disabled:xe,onClick:()=>{ye(ve),Se(D(ve))},children:se.now}):null,e(o,{variant:"solid",size:$,color:_,density:"compact",onClick:()=>be(!1),children:se.done})]})]})})});
@@ -0,0 +1,2 @@
1
+ export { DateTimePicker } from './DateTimePicker';
2
+ export type { DateTimePickerProps } from './DateTimePicker';
@@ -0,0 +1 @@
1
+ export{DateTimePicker}from"./DateTimePicker";
@@ -0,0 +1,111 @@
1
+ import * as React from 'react';
2
+ import { Dialog as BaseUIDialog } from '@base-ui/react/dialog';
3
+ import type { NebaStyleProps } from '../../types';
4
+ /**
5
+ * A dialog takes `size`, `color` and `density` and stops there.
6
+ *
7
+ * There is no `variant`: the three weights answer "how much does this surface
8
+ * assert itself against the page around it", and a modal has already taken the
9
+ * page. There is no `elevation` either — see `popupClasses`.
10
+ */
11
+ export interface DialogProps extends Pick<NebaStyleProps, 'size' | 'color' | 'density'> {
12
+ /** The dialog is shown. Use with `onOpenChange` for a controlled dialog. */
13
+ open?: boolean;
14
+ /** Whether the dialog starts open, for an uncontrolled one. */
15
+ defaultOpen?: boolean;
16
+ onOpenChange?: (open: boolean) => void;
17
+ /**
18
+ * The element that opens the dialog, wired up by Base UI. Optional — a
19
+ * controlled dialog opened from somewhere else in the app needs no trigger at
20
+ * all, and passing one here is only a convenience for the common case.
21
+ */
22
+ trigger?: React.ReactElement;
23
+ /** The heading. Rendered as the `<h2>` that names the dialog. */
24
+ title?: React.ReactNode;
25
+ /** A line under the title, and the dialog's accessible description. */
26
+ description?: React.ReactNode;
27
+ /**
28
+ * The bottom row. Laid out end-aligned, so a pair of buttons needs no wrapper
29
+ * of its own — and `DialogClose` is what makes one of them dismiss.
30
+ */
31
+ actions?: React.ReactNode;
32
+ /**
33
+ * Draws a hairline between the header, the body and the actions instead of
34
+ * separating them with space. Worth turning on the moment the body scrolls:
35
+ * the lines are what say the header stayed put.
36
+ * @default false
37
+ */
38
+ dividers?: boolean;
39
+ /**
40
+ * Shows the × in the corner.
41
+ *
42
+ * On by default, unlike most booleans in the library. A modal dialog takes the
43
+ * page away until it is answered, and the visible way out should not have to
44
+ * be remembered.
45
+ * @default true
46
+ */
47
+ showClose?: boolean;
48
+ /** Accessible name of the × button. */
49
+ closeLabel?: string;
50
+ /**
51
+ * A hard cap on the sheet's width, overriding the one `size` implies. Numbers
52
+ * are pixels. For the dialog whose content decides its width — a wide table,
53
+ * a narrow confirmation — rather than for tuning the scale, which is `size`.
54
+ */
55
+ width?: number | string;
56
+ /**
57
+ * The sheet takes the full width its `size` allows.
58
+ *
59
+ * On by default, which is the other way round from every other component.
60
+ * Elsewhere `fullWidth` means "fill the container"; a dialog's container is
61
+ * the viewport, and a dialog that shrank to fit two words would be a tooltip.
62
+ * @default true
63
+ */
64
+ fullWidth?: boolean;
65
+ /** Fills the viewport edge to edge. For a mobile-sized screen, or an editor. */
66
+ fullScreen?: boolean;
67
+ /**
68
+ * Whether the page behind is taken away. `'trap-focus'` keeps the page
69
+ * scrollable and clickable while still holding focus inside.
70
+ * @default true
71
+ */
72
+ modal?: boolean | 'trap-focus';
73
+ /**
74
+ * Whether pressing Escape or clicking outside closes the dialog. Turn it off
75
+ * for the dialog that has to be answered — and then give it actions that
76
+ * answer it, because there will be no other way out.
77
+ * @default true
78
+ */
79
+ dismissible?: boolean;
80
+ /** The body. */
81
+ children?: React.ReactNode;
82
+ className?: string;
83
+ style?: React.CSSProperties;
84
+ }
85
+ export type DialogCloseProps = React.ComponentPropsWithoutRef<typeof BaseUIDialog.Close>;
86
+ /**
87
+ * Closes the dialog it is inside.
88
+ *
89
+ * Exported because an uncontrolled dialog has no `setOpen` for its Cancel
90
+ * button to call, and the alternative — making every dialog controlled — is a
91
+ * piece of state per dialog that exists only to answer a button.
92
+ *
93
+ * `render` is Base UI's own escape hatch, so a real Neba button dismisses:
94
+ * `<DialogClose render={<Button variant="text">Cancel</Button>} />`.
95
+ */
96
+ export declare const DialogClose: React.ForwardRefExoticComponent<Omit<import("@base-ui/react").AlertDialogCloseProps, "ref"> & React.RefAttributes<HTMLButtonElement>>;
97
+ /**
98
+ * A sheet that takes the page away until it is answered.
99
+ *
100
+ * The sections are props rather than compound sub-components, exactly as they
101
+ * are on Card: the arrangement of a dialog is fixed — heading, description,
102
+ * body, actions — and what a caller wants to decide is what goes in each slot.
103
+ * Base UI owns everything hard about it: the focus trap, the scroll lock, the
104
+ * `aria-labelledby` / `aria-describedby` wiring, restoring focus to the trigger,
105
+ * and the inert page behind.
106
+ *
107
+ * What is left here is the surface, the width ladder and the scroll behaviour —
108
+ * the header and the actions stay put while only the body scrolls, which is why
109
+ * `dividers` matters more here than on a Card.
110
+ */
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;
@@ -0,0 +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]})})]})]})}
@@ -0,0 +1,2 @@
1
+ export { Dialog, DialogClose } from './Dialog';
2
+ export type { DialogCloseProps, DialogProps } from './Dialog';
@@ -0,0 +1 @@
1
+ export{Dialog,DialogClose}from"./Dialog";
@@ -0,0 +1,67 @@
1
+ import * as React from 'react';
2
+ import type { NebaAlign, NebaColor, NebaOrientation, NebaSize } from '../../types';
3
+ /** Where the label sits along a labelled divider. Ignored without a label. */
4
+ export type DividerTextAlign = NebaAlign;
5
+ export interface DividerProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'color' | 'children'> {
6
+ /**
7
+ * Which way the line runs. A vertical divider has no height of its own — it
8
+ * stretches to its flex parent, the way a rule between two toolbar groups
9
+ * should.
10
+ * @default 'horizontal'
11
+ */
12
+ orientation?: NebaOrientation;
13
+ /**
14
+ * Semantic colour role. Only the hairline is coloured, and only faintly: this
15
+ * is the same `--n-line` a Card scores its sections with, so a standalone
16
+ * divider and a card's internal one are the same line.
17
+ * @default 'primary'
18
+ */
19
+ color?: NebaColor;
20
+ /** Type scale of the label. Nothing else on a divider has a size. */
21
+ size?: NebaSize;
22
+ /**
23
+ * How far the rule runs — the width of a horizontal divider, the height of a
24
+ * vertical one. A number is pixels; a string is any CSS length, so `'50%'`
25
+ * and `'12rem'` both work.
26
+ *
27
+ * `length` rather than `width`, because a divider is the one component whose
28
+ * long axis turns with `orientation`: a `width` that meant height half the
29
+ * time would be a worse name than a longer one.
30
+ *
31
+ * Left out, a horizontal divider is the full width of its container and a
32
+ * vertical one stretches to the height of the flex row it is in — which is
33
+ * what a rule between two things should do by default.
34
+ */
35
+ length?: number | string;
36
+ /**
37
+ * How thick the rule is. A number is pixels; a string is any CSS length.
38
+ * @default 1
39
+ */
40
+ thickness?: number | string;
41
+ /** A label set into the line — "OR" between two sign-in options. */
42
+ children?: React.ReactNode;
43
+ /**
44
+ * Where the label sits. `center` splits the line in half; `start` and `end`
45
+ * leave a short stub on the near side so the label still reads as set *into*
46
+ * the rule rather than floating above it.
47
+ * @default 'center'
48
+ */
49
+ textAlign?: DividerTextAlign;
50
+ }
51
+ /**
52
+ * A rule between two things.
53
+ *
54
+ * With no children it is Base UI's `Separator` and nothing else — a real
55
+ * `role="separator"` with the right `aria-orientation`. With children the line
56
+ * breaks around the label.
57
+ *
58
+ * `separator` is not a name-from-content role, so the visible label does *not*
59
+ * become the accessible name on its own: a screen reader would announce a bare
60
+ * "separator" and the word "OR" would be read as loose text somewhere nearby.
61
+ * A string label is therefore copied into `aria-label`. Anything richer is left
62
+ * alone — only the caller knows which part of it is the name.
63
+ *
64
+ * There is no `variant` and no `elevation`: a divider is not a surface. It has
65
+ * no acrylic, catches no light and casts no shadow.
66
+ */
67
+ export declare const Divider: React.ForwardRefExoticComponent<DividerProps & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1 @@
1
+ import{jsx as e,jsxs as r}from"react/jsx-runtime";import*as t from"react";import{Separator as n}from"@base-ui/react/separator";import{metaTextClasses as l}from"../../internal/styles";const i="[border-color:var(--n-line)]";function a(e){return"number"==typeof e?`${e}px`:e}const o={horizontal:{start:["w-4 shrink-0","flex-1"],center:["flex-1","flex-1"],end:["flex-1","w-4 shrink-0"]},vertical:{start:["h-4 shrink-0","flex-1"],center:["flex-1","flex-1"],end:["flex-1","h-4 shrink-0"]}},s={xs:"gap-1.5",sm:"gap-2",md:"gap-3",lg:"gap-3.5",xl:"gap-4"};export const Divider=t.forwardRef(function({orientation:t="horizontal",color:c="primary",size:d="md",length:f,thickness:h,textAlign:m="center",className:p,style:u,children:x,...w},b){const v="vertical"===t,g=null!=x&&!1!==x&&""!==x,$={"--n-line":`var(--neba-${c}-line)`,"--n-rule":a(h)??"1px"},y=a(f),j={...$,...void 0===y?null:v?{height:y}:{width:y},...u};if(!g)return e(n,{ref:b,orientation:t,className:[v?"w-0 border-l [border-left-width:var(--n-rule)] "+(void 0===y?"self-stretch":""):"h-0 w-full border-t [border-top-width:var(--n-rule)]",i,p??""].filter(Boolean).join(" "),style:j,...w});const[k,N]=o[t][m],z=v?"w-0 border-l [border-left-width:var(--n-rule)]":"h-0 border-t [border-top-width:var(--n-rule)]";return r(n,{ref:b,orientation:t,"aria-label":"string"==typeof x?x:void 0,className:["flex items-center",v?"w-auto flex-col "+(void 0===y?"self-stretch":""):"w-full",s[d],p??""].filter(Boolean).join(" "),style:j,...w,children:[e("span",{"aria-hidden":"true",className:`${z} ${k} ${i}`}),e("span",{className:["shrink-0 whitespace-nowrap text-(--neba-muted-fg)",l[d],v?"[writing-mode:vertical-rl]":""].filter(Boolean).join(" "),children:x}),e("span",{"aria-hidden":"true",className:`${z} ${N} ${i}`})]})});
@@ -0,0 +1,2 @@
1
+ export { Divider } from './Divider';
2
+ export type { DividerProps, DividerTextAlign } from './Divider';
@@ -0,0 +1 @@
1
+ export{Divider}from"./Divider";
@@ -0,0 +1,103 @@
1
+ import * as React from 'react';
2
+ import type { NebaElevation, NebaStyleProps } from '../../types';
3
+ /** Why a file was turned away. One reason per file, in the order they are checked. */
4
+ export type FileRejectionReason = 'type' | 'size' | 'count';
5
+ export interface FileRejection {
6
+ file: File;
7
+ reason: FileRejectionReason;
8
+ }
9
+ export interface FilePickerProps extends NebaStyleProps {
10
+ /**
11
+ * Drop shadow depth. `0` (the default) is flat.
12
+ * @default 0
13
+ */
14
+ elevation?: NebaElevation;
15
+ /**
16
+ * Which files the browser's own picker offers, in the `accept` grammar —
17
+ * `'image/*,.pdf'`. Dropped files are checked against it too, which the
18
+ * attribute alone does not do.
19
+ */
20
+ accept?: string;
21
+ /** Whether more than one file may be chosen. @default false */
22
+ multiple?: boolean;
23
+ /** The largest a single file may be, in bytes. */
24
+ maxSize?: number;
25
+ /**
26
+ * How many files may be held at once. Implies `multiple`, and is checked
27
+ * against what is already chosen rather than against one drop.
28
+ */
29
+ maxFiles?: number;
30
+ /** The chosen files. Use with `onFilesChange` for a controlled picker. */
31
+ value?: readonly File[];
32
+ /** The initially chosen files, for an uncontrolled one. */
33
+ defaultValue?: readonly File[];
34
+ onFilesChange?: (files: File[]) => void;
35
+ /**
36
+ * Called with everything that was turned away, and why. Without it a rejected
37
+ * file disappears silently, which is the single worst thing a dropzone does.
38
+ */
39
+ onReject?: (rejections: FileRejection[]) => void;
40
+ /** Label above the box. */
41
+ label?: React.ReactNode;
42
+ /** Helper text below the box. */
43
+ description?: React.ReactNode;
44
+ /** Error message below. Its presence also turns the picker invalid. */
45
+ error?: React.ReactNode;
46
+ /** Forces the invalid state without a message. Defaults to `!!error`. */
47
+ invalid?: boolean;
48
+ /** The line inside the box. Defaults to an English sentence. */
49
+ title?: React.ReactNode;
50
+ /** The line under it — what is accepted, how big, how many. */
51
+ hint?: React.ReactNode;
52
+ /** The glyph above the title. Pass `null` for a box with no picture in it. */
53
+ icon?: React.ReactNode;
54
+ /**
55
+ * Lists the chosen files under the box, each with a way to remove it.
56
+ * @default true
57
+ */
58
+ showList?: boolean;
59
+ /** Accessible name of a file's remove button. Receives the file's name. */
60
+ removeLabel?: (name: string) => string;
61
+ /** Stretches to the width of the container. @default true */
62
+ fullWidth?: boolean;
63
+ /** Unavailable. */
64
+ disabled?: boolean;
65
+ /** The files are shown but cannot be added to or removed. */
66
+ readOnly?: boolean;
67
+ /** Whether a file must be chosen before the form is submitted. */
68
+ required?: boolean;
69
+ /** Identifies the field when a form is submitted. */
70
+ name?: string;
71
+ id?: string;
72
+ className?: string;
73
+ style?: React.CSSProperties;
74
+ }
75
+ /**
76
+ * `1.4 MB`, in the units a person reading a file list expects.
77
+ *
78
+ * Base 1000 rather than 1024, and `MB` rather than `MiB`: it is the number every
79
+ * operating system's file browser shows, and a picker that disagrees with the
80
+ * Finder about how big the file is has picked a fight it cannot win.
81
+ */
82
+ export declare function formatFileSize(bytes: number): string;
83
+ /**
84
+ * A box you drop files on, or click to open the file dialog.
85
+ *
86
+ * There is no Base UI primitive under this, and the fallback the library allows
87
+ * — plain React and DOM — is the right one: a dropzone is a `<div>` listening
88
+ * for four drag events and an `<input type="file">` it clicks for you. There is
89
+ * no popup to position, no focus to trap and no roving anything.
90
+ *
91
+ * What that leaves is the part every hand-rolled dropzone gets wrong. The drag
92
+ * counter is one of them: `dragenter` and `dragleave` both fire as the pointer
93
+ * crosses a *child* of the zone, so a zone that toggles a boolean flickers the
94
+ * whole time a file is being dragged across its own contents. Counting them is
95
+ * the fix. The other is `accept`, which the browser enforces on its own dialog
96
+ * and never on a drop, so a dropzone that only sets the attribute accepts
97
+ * anything the moment a file arrives by drag.
98
+ *
99
+ * The shell is a `<div>` and the pressable area inside it is a real `<button>`,
100
+ * with the file list outside that button — the same shape Chip and ListItem
101
+ * use, because the remove buttons cannot be nested inside the browse button.
102
+ */
103
+ export declare const FilePicker: React.ForwardRefExoticComponent<FilePickerProps & React.RefAttributes<HTMLInputElement>>;
@@ -0,0 +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]})});
@@ -0,0 +1,2 @@
1
+ export { FilePicker, formatFileSize } from './FilePicker';
2
+ export type { FilePickerProps, FileRejection, FileRejectionReason } from './FilePicker';
@@ -0,0 +1 @@
1
+ export{FilePicker,formatFileSize}from"./FilePicker";