@nexub/react 1.6.0 → 1.8.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 (122) hide show
  1. package/dist/{chunk-C6JRJ6JW.js → chunk-22BGPRJZ.js} +1 -1
  2. package/dist/{chunk-NGQKBDHA.js → chunk-322WR6EU.js} +1 -1
  3. package/dist/{chunk-GSG2W6DP.js → chunk-3LTB6TGN.js} +1 -1
  4. package/dist/{chunk-743Y5MY3.js → chunk-3MSIO7KM.js} +40 -6
  5. package/dist/chunk-4B4XWDAH.js +1 -0
  6. package/dist/{chunk-MEUJBGY5.js → chunk-4MEV2WHD.js} +27 -6
  7. package/dist/{chunk-FLZD7HQY.js → chunk-5FWJXSXT.js} +1 -1
  8. package/dist/{chunk-VAFBGFKY.js → chunk-5GN2GFW3.js} +1 -1
  9. package/dist/{chunk-LESI7J7B.js → chunk-5NKIGEDZ.js} +1 -0
  10. package/dist/{chunk-7SXR4PGO.js → chunk-5W3AOOYS.js} +1 -1
  11. package/dist/{chunk-5KI4YHA3.js → chunk-6U5WQERX.js} +17 -18
  12. package/dist/{chunk-NZT4TTNV.js → chunk-7BAIEYUW.js} +79 -58
  13. package/dist/{chunk-NQPGELMP.js → chunk-A4QLUIFN.js} +1 -1
  14. package/dist/{chunk-PGDXFBKT.js → chunk-BEOHZKPQ.js} +1 -1
  15. package/dist/{chunk-PPCGUIAB.js → chunk-BIAYWCDE.js} +1 -1
  16. package/dist/{chunk-YNU6VRD5.js → chunk-BSKEBC2Q.js} +1 -1
  17. package/dist/chunk-BU5QD2FS.js +148 -0
  18. package/dist/{chunk-GRKCUQG4.js → chunk-DFCHCYNT.js} +4 -3
  19. package/dist/{chunk-PMWYLYM3.js → chunk-ENB7X3W4.js} +3 -3
  20. package/dist/{chunk-NSVXGOR3.js → chunk-ESMIBOF5.js} +1 -1
  21. package/dist/{chunk-HXV5UA7K.js → chunk-ETWFHIAE.js} +1 -1
  22. package/dist/{chunk-JHVYI5GK.js → chunk-F7ZA2VA2.js} +1 -1
  23. package/dist/{chunk-WXRQ42DR.js → chunk-FT2S7N64.js} +2 -2
  24. package/dist/{chunk-BNFGVFZ3.js → chunk-G4RLUGE3.js} +2 -2
  25. package/dist/{chunk-SZ2WPWXJ.js → chunk-GG5HDX7J.js} +1 -1
  26. package/dist/{chunk-O74XEHLA.js → chunk-GSA7NBEG.js} +11 -3
  27. package/dist/{chunk-IGLOYOCH.js → chunk-HSM7RXUF.js} +46 -11
  28. package/dist/{chunk-FIDUY6SS.js → chunk-IDIS7Z6H.js} +2 -2
  29. package/dist/{chunk-TRA6A5C5.js → chunk-JVOSMXD5.js} +2 -2
  30. package/dist/{chunk-3FPJIXG7.js → chunk-KRHD7VI6.js} +1 -1
  31. package/dist/{chunk-DGQJRTO6.js → chunk-L4BSKMLK.js} +1 -1
  32. package/dist/{chunk-7VJABRKB.js → chunk-NORCPKRD.js} +1 -1
  33. package/dist/{chunk-CQWYZPPJ.js → chunk-NYORXEPS.js} +1 -1
  34. package/dist/{chunk-3MT23LNM.js → chunk-O6J6HXVT.js} +3 -3
  35. package/dist/{chunk-UTJJ5HFX.js → chunk-OS4NOWEI.js} +53 -51
  36. package/dist/{chunk-O626NJEM.js → chunk-OTZBGMYH.js} +2 -2
  37. package/dist/{chunk-RSU2UHN4.js → chunk-PC7YGDNL.js} +2 -2
  38. package/dist/{chunk-PREMZMLU.js → chunk-PGD246WD.js} +1 -1
  39. package/dist/{chunk-2Y4WLNEZ.js → chunk-QUYOV2ZJ.js} +3 -1
  40. package/dist/{chunk-VMT7Y3AT.js → chunk-R6VLSYXK.js} +2 -2
  41. package/dist/{chunk-7Q4T7CB6.js → chunk-RSBJBQPG.js} +1 -1
  42. package/dist/{chunk-CBDJRPMD.js → chunk-RVWQROFK.js} +1 -1
  43. package/dist/{chunk-2I7FIU6R.js → chunk-SKIJVVBU.js} +1 -1
  44. package/dist/{chunk-SYZADSLI.js → chunk-SZNSQR2B.js} +1 -1
  45. package/dist/{chunk-ZTLALVWA.js → chunk-TSN6HYVY.js} +2 -2
  46. package/dist/{chunk-SAUA52EJ.js → chunk-UAQRQNOB.js} +2 -2
  47. package/dist/chunk-UCNA2ICU.js +28 -0
  48. package/dist/{chunk-S7GH2BJP.js → chunk-UV5O2BMW.js} +2 -2
  49. package/dist/{chunk-XDU27NRX.js → chunk-UVWQPDOV.js} +1 -1
  50. package/dist/{chunk-7B4VF2ZU.js → chunk-V6CMWCJH.js} +2 -2
  51. package/dist/{chunk-VD4RFTNV.js → chunk-VF6RWEKX.js} +1 -1
  52. package/dist/{chunk-CV5ZKED7.js → chunk-W2P2WOAN.js} +1 -1
  53. package/dist/{chunk-5VW6RUKZ.js → chunk-WECNLNIA.js} +2 -2
  54. package/dist/{chunk-KE4YVG5Q.js → chunk-X3B2MTX6.js} +1 -1
  55. package/dist/{chunk-HSPGJSFJ.js → chunk-XHLSYHAV.js} +2 -2
  56. package/dist/{chunk-RUR57JZQ.js → chunk-ZGZQZG6S.js} +1 -1
  57. package/dist/{chunk-WVBGQCYC.js → chunk-ZLW7IBXK.js} +1 -1
  58. package/dist/{chunk-74RUJ5KZ.js → chunk-ZRBLASQE.js} +1 -1
  59. package/dist/{chunk-Q3ESHXKU.js → chunk-ZTI4MK3L.js} +1 -1
  60. package/dist/{chunk-7XWJCFWI.js → chunk-ZUGZRXME.js} +1 -1
  61. package/dist/components/Alert/index.js +2 -2
  62. package/dist/components/AlertDialog/index.js +4 -4
  63. package/dist/components/Amount/index.js +3 -3
  64. package/dist/components/Autocomplete/index.js +2 -2
  65. package/dist/components/Avatar/index.js +1 -1
  66. package/dist/components/AvatarGroup/index.js +3 -3
  67. package/dist/components/Banner/index.js +2 -2
  68. package/dist/components/Breadcrumb/index.js +2 -2
  69. package/dist/components/Button/index.js +2 -2
  70. package/dist/components/Chip/index.js +2 -2
  71. package/dist/components/Citation/index.js +4 -4
  72. package/dist/components/CommandPalette/index.js +3 -3
  73. package/dist/components/ContextMenu/index.js +2 -2
  74. package/dist/components/DataTable/index.js +4 -2
  75. package/dist/components/DatePicker/index.js +4 -4
  76. package/dist/components/DateRangePicker/index.js +5 -5
  77. package/dist/components/Dialog/index.js +2 -2
  78. package/dist/components/Drawer/index.js +2 -2
  79. package/dist/components/DropdownMenu/index.js +2 -2
  80. package/dist/components/ErrorState/index.js +2 -2
  81. package/dist/components/EyebrowChip/index.js +3 -3
  82. package/dist/components/FileUpload/index.js +2 -2
  83. package/dist/components/FilterChip/index.js +3 -3
  84. package/dist/components/FormField/index.js +5 -5
  85. package/dist/components/Heading/index.js +3 -3
  86. package/dist/components/HelperText/index.js +3 -3
  87. package/dist/components/HoverCard/index.js +2 -2
  88. package/dist/components/IconButton/index.js +2 -2
  89. package/dist/components/Input/index.js +2 -2
  90. package/dist/components/Kbd/index.js +1 -1
  91. package/dist/components/KeyboardShortcut/index.js +2 -2
  92. package/dist/components/Label/index.js +3 -3
  93. package/dist/components/Menubar/index.js +2 -2
  94. package/dist/components/MessageBubble/index.js +4 -4
  95. package/dist/components/MoneyInput/index.js +4 -4
  96. package/dist/components/NavigationMenu/index.js +2 -2
  97. package/dist/components/NavigationRail/index.js +2 -2
  98. package/dist/components/NexubProvider/index.js +1 -1
  99. package/dist/components/NumberInput/index.js +4 -4
  100. package/dist/components/NumberTicker/index.js +2 -2
  101. package/dist/components/PageHeader/index.js +1 -1
  102. package/dist/components/Pagination/index.js +3 -3
  103. package/dist/components/PasswordInput/index.js +4 -4
  104. package/dist/components/Popover/index.js +2 -2
  105. package/dist/components/PromptInput/index.js +4 -4
  106. package/dist/components/Rating/index.js +2 -2
  107. package/dist/components/ScrollArea/index.js +1 -1
  108. package/dist/components/SearchInput/index.js +4 -4
  109. package/dist/components/Select/index.js +3 -3
  110. package/dist/components/Sidebar/index.js +2 -2
  111. package/dist/components/Spinner/index.js +2 -2
  112. package/dist/components/SplitButton/index.js +5 -5
  113. package/dist/components/Table/index.js +2 -1
  114. package/dist/components/Textarea/index.js +2 -2
  115. package/dist/components/ThinkingIndicator/index.js +2 -2
  116. package/dist/components/Toast/index.js +2 -2
  117. package/dist/components/TopNav/index.js +2 -2
  118. package/dist/index.d.ts +90 -10
  119. package/dist/index.js +65 -64
  120. package/package.json +6 -6
  121. package/dist/chunk-MTK3GHDQ.js +0 -25
  122. package/dist/chunk-OYCK6BRG.js +0 -89
@@ -0,0 +1,148 @@
1
+ 'use client';
2
+ import {
3
+ cn
4
+ } from "./chunk-Q7G5WGYV.js";
5
+
6
+ // src/components/Table/Table.tsx
7
+ import * as React from "react";
8
+ import { jsx } from "react/jsx-runtime";
9
+ var CaptionIdContext = React.createContext(void 0);
10
+ var Root = React.forwardRef(
11
+ ({ className, scrollLabel, ...props }, ref) => {
12
+ const wrapperRef = React.useRef(null);
13
+ const tableRef = React.useRef(null);
14
+ const captionId = React.useId();
15
+ const [overflow, setOverflow] = React.useState(null);
16
+ React.useEffect(() => {
17
+ const wrapper = wrapperRef.current;
18
+ if (!wrapper) return;
19
+ const measure = () => {
20
+ if (wrapper.scrollWidth > wrapper.clientWidth) {
21
+ const id = tableRef.current?.caption?.id || null;
22
+ setOverflow((prev) => prev && prev.captionId === id ? prev : { captionId: id });
23
+ } else {
24
+ setOverflow(null);
25
+ }
26
+ };
27
+ measure();
28
+ if (typeof ResizeObserver === "undefined") return;
29
+ const ro = new ResizeObserver(measure);
30
+ ro.observe(wrapper);
31
+ if (tableRef.current) ro.observe(tableRef.current);
32
+ return () => ro.disconnect();
33
+ }, []);
34
+ const setRefs = (el) => {
35
+ tableRef.current = el;
36
+ if (typeof ref === "function") ref(el);
37
+ else if (ref) ref.current = el;
38
+ };
39
+ const label = scrollLabel ?? props["aria-label"];
40
+ const labelledBy = label ? void 0 : props["aria-labelledby"] ?? overflow?.captionId ?? void 0;
41
+ const named = Boolean(label || labelledBy);
42
+ return /* @__PURE__ */ jsx(CaptionIdContext.Provider, { value: captionId, children: /* @__PURE__ */ jsx(
43
+ "div",
44
+ {
45
+ ref: wrapperRef,
46
+ className: "relative w-full overflow-auto",
47
+ ...overflow ? {
48
+ tabIndex: 0,
49
+ ...named ? { role: "region", "aria-label": label, "aria-labelledby": labelledBy } : {}
50
+ } : {},
51
+ children: /* @__PURE__ */ jsx(
52
+ "table",
53
+ {
54
+ ref: setRefs,
55
+ className: cn("w-full caption-bottom text-sm tabular-nums", className),
56
+ ...props
57
+ }
58
+ )
59
+ }
60
+ ) });
61
+ }
62
+ );
63
+ Root.displayName = "Table.Root";
64
+ var Header = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("thead", { ref, className: cn("[&_tr]:border-b", className), ...props }));
65
+ Header.displayName = "Table.Header";
66
+ var Body = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("tbody", { ref, className: cn("[&_tr:last-child]:border-0", className), ...props }));
67
+ Body.displayName = "Table.Body";
68
+ var TableFooter = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
69
+ "tfoot",
70
+ {
71
+ ref,
72
+ className: cn(
73
+ "border-t bg-[var(--color-surface-container-low)] font-medium [&>tr]:last:border-b-0",
74
+ className
75
+ ),
76
+ ...props
77
+ }
78
+ ));
79
+ TableFooter.displayName = "Table.Footer";
80
+ var Row = React.forwardRef(
81
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
82
+ "tr",
83
+ {
84
+ ref,
85
+ className: cn(
86
+ "border-b border-[var(--color-outline-variant)] transition-colors hover:bg-[color-mix(in_srgb,var(--color-surface-container-low)_50%,transparent)] data-[state=selected]:bg-[var(--color-surface-container-low)]",
87
+ className
88
+ ),
89
+ ...props
90
+ }
91
+ )
92
+ );
93
+ Row.displayName = "Table.Row";
94
+ var Head = React.forwardRef(
95
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
96
+ "th",
97
+ {
98
+ ref,
99
+ className: cn(
100
+ "h-10 px-4 text-start align-middle font-medium text-[var(--color-on-surface-muted)] [&:has([role=checkbox])]:pe-0 [&>[role=checkbox]]:translate-y-[2px]",
101
+ className
102
+ ),
103
+ ...props
104
+ }
105
+ )
106
+ );
107
+ Head.displayName = "Table.Head";
108
+ var Cell = React.forwardRef(
109
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
110
+ "td",
111
+ {
112
+ ref,
113
+ className: cn(
114
+ "p-4 align-middle [&:has([role=checkbox])]:pe-0 [&>[role=checkbox]]:translate-y-[2px]",
115
+ className
116
+ ),
117
+ ...props
118
+ }
119
+ )
120
+ );
121
+ Cell.displayName = "Table.Cell";
122
+ var Caption = React.forwardRef(({ className, id, ...props }, ref) => {
123
+ const contextId = React.useContext(CaptionIdContext);
124
+ return /* @__PURE__ */ jsx(
125
+ "caption",
126
+ {
127
+ ref,
128
+ id: id ?? contextId,
129
+ className: cn("mt-4 text-sm text-[var(--color-on-surface-muted)]", className),
130
+ ...props
131
+ }
132
+ );
133
+ });
134
+ Caption.displayName = "Table.Caption";
135
+ var Table = {
136
+ Root,
137
+ Header,
138
+ Body,
139
+ Footer: TableFooter,
140
+ Row,
141
+ Head,
142
+ Cell,
143
+ Caption
144
+ };
145
+
146
+ export {
147
+ Table
148
+ };
@@ -1,13 +1,13 @@
1
1
  'use client';
2
2
  import {
3
3
  DropdownMenu
4
- } from "./chunk-NQPGELMP.js";
4
+ } from "./chunk-A4QLUIFN.js";
5
5
  import {
6
6
  ButtonGroup
7
7
  } from "./chunk-WHTLXQB6.js";
8
8
  import {
9
9
  Button
10
- } from "./chunk-C6JRJ6JW.js";
10
+ } from "./chunk-22BGPRJZ.js";
11
11
  import {
12
12
  cn
13
13
  } from "./chunk-Q7G5WGYV.js";
@@ -19,6 +19,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
19
19
  var SplitButton = React.forwardRef(
20
20
  ({ menuLabel, menu, align = "end", variant, size, tone, disabled, loading, className, ...props }, ref) => {
21
21
  const shared = { variant, size, tone };
22
+ const busy = loading || props.status === "loading";
22
23
  return /* @__PURE__ */ jsxs(ButtonGroup, { attached: true, className, children: [
23
24
  /* @__PURE__ */ jsx(Button, { ref, ...shared, disabled, ...loading ? { loading: true } : {}, ...props }),
24
25
  /* @__PURE__ */ jsxs(DropdownMenu.Root, { modal: false, children: [
@@ -26,7 +27,7 @@ var SplitButton = React.forwardRef(
26
27
  Button,
27
28
  {
28
29
  ...shared,
29
- disabled: disabled || loading,
30
+ disabled: disabled || busy,
30
31
  "aria-label": menuLabel,
31
32
  className: cn(
32
33
  "px-3",
@@ -1,13 +1,13 @@
1
1
  'use client';
2
2
  import {
3
3
  inputWrapperVariants
4
- } from "./chunk-JHVYI5GK.js";
4
+ } from "./chunk-F7ZA2VA2.js";
5
5
  import {
6
6
  disabledText
7
- } from "./chunk-7SXR4PGO.js";
7
+ } from "./chunk-5W3AOOYS.js";
8
8
  import {
9
9
  useNexubMessages
10
- } from "./chunk-743Y5MY3.js";
10
+ } from "./chunk-3MSIO7KM.js";
11
11
  import {
12
12
  cn
13
13
  } from "./chunk-Q7G5WGYV.js";
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
  import {
3
3
  useNexubMessages
4
- } from "./chunk-743Y5MY3.js";
4
+ } from "./chunk-3MSIO7KM.js";
5
5
  import {
6
6
  cn
7
7
  } from "./chunk-Q7G5WGYV.js";
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
  import {
3
3
  useNexubMessages
4
- } from "./chunk-743Y5MY3.js";
4
+ } from "./chunk-3MSIO7KM.js";
5
5
  import {
6
6
  cn
7
7
  } from "./chunk-Q7G5WGYV.js";
@@ -4,7 +4,7 @@ import {
4
4
  fieldDisabledWithin,
5
5
  fieldFocusWithin,
6
6
  fieldInvalid
7
- } from "./chunk-7SXR4PGO.js";
7
+ } from "./chunk-5W3AOOYS.js";
8
8
  import {
9
9
  cn
10
10
  } from "./chunk-Q7G5WGYV.js";
@@ -1,10 +1,10 @@
1
1
  'use client';
2
2
  import {
3
3
  avatarVariants
4
- } from "./chunk-2Y4WLNEZ.js";
4
+ } from "./chunk-QUYOV2ZJ.js";
5
5
  import {
6
6
  useNexubMessages
7
- } from "./chunk-743Y5MY3.js";
7
+ } from "./chunk-3MSIO7KM.js";
8
8
  import {
9
9
  cn
10
10
  } from "./chunk-Q7G5WGYV.js";
@@ -1,10 +1,10 @@
1
1
  'use client';
2
2
  import {
3
3
  HelperText
4
- } from "./chunk-WVBGQCYC.js";
4
+ } from "./chunk-ZLW7IBXK.js";
5
5
  import {
6
6
  Label
7
- } from "./chunk-PREMZMLU.js";
7
+ } from "./chunk-PGD246WD.js";
8
8
  import {
9
9
  FormError
10
10
  } from "./chunk-QVTVDL6Y.js";
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-FJUVYRNT.js";
5
5
  import {
6
6
  useNexubMessages
7
- } from "./chunk-743Y5MY3.js";
7
+ } from "./chunk-3MSIO7KM.js";
8
8
 
9
9
  // src/components/Autocomplete/Autocomplete.tsx
10
10
  import * as React from "react";
@@ -3,8 +3,9 @@ import {
3
3
  useIsomorphicLayoutEffect
4
4
  } from "./chunk-NHUQLIHL.js";
5
5
  import {
6
+ useLocale,
6
7
  useNexubMessages
7
- } from "./chunk-743Y5MY3.js";
8
+ } from "./chunk-3MSIO7KM.js";
8
9
  import {
9
10
  cn
10
11
  } from "./chunk-Q7G5WGYV.js";
@@ -13,7 +14,11 @@ import {
13
14
  import * as React from "react";
14
15
  import * as RadixToast from "@radix-ui/react-toast";
15
16
  import { jsx } from "react/jsx-runtime";
16
- var Provider2 = RadixToast.Provider;
17
+ function Provider2({ swipeDirection, ...props }) {
18
+ const { dir } = useLocale();
19
+ return /* @__PURE__ */ jsx(RadixToast.Provider, { swipeDirection: swipeDirection ?? (dir === "rtl" ? "left" : "right"), ...props });
20
+ }
21
+ Provider2.displayName = "Toast.Provider";
17
22
  var Viewport2 = React.forwardRef(
18
23
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
19
24
  RadixToast.Viewport,
@@ -37,6 +42,8 @@ var Root2 = React.forwardRef(
37
42
  // Snackbar: the inverse surface stands out from any page, light or dark.
38
43
  "group pointer-events-auto relative flex w-full items-center justify-between gap-3 overflow-hidden rounded-shape-container bg-[var(--color-inverse-surface)] py-3 ps-4 pe-2 text-[var(--color-inverse-on-surface)] shadow-elevation-2",
39
44
  "duration-spatial-default ease-spatial-default data-[state=closed]:duration-effects-fast",
45
+ // Follow the finger (Radix's signed swipe offsets), snap back on cancel, leave from where it was let go.
46
+ "data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none",
40
47
  // Enter/exit slide from the right edge, where the viewport sits.
41
48
  "nx-motion [--nx-x:calc(100%+1rem)] rtl:[--nx-x:calc(-100%-1rem)]",
42
49
  className
@@ -169,6 +176,7 @@ var GAP = 8;
169
176
  function Toaster({ expand = false, visibleToasts = 3 }) {
170
177
  const toasts = useToastStore();
171
178
  const messages = useNexubMessages();
179
+ const { dir } = useLocale();
172
180
  const [closed, setClosed] = React2.useState(() => /* @__PURE__ */ new Set());
173
181
  const [hovered, setHovered] = React2.useState(false);
174
182
  const [focused, setFocused] = React2.useState(false);
@@ -237,7 +245,7 @@ function Toaster({ expand = false, visibleToasts = 3 }) {
237
245
  setFocused(false);
238
246
  }
239
247
  }, [order.length]);
240
- return /* @__PURE__ */ jsxs(RadixToast2.Provider, { swipeDirection: "right", children: [
248
+ return /* @__PURE__ */ jsxs(RadixToast2.Provider, { swipeDirection: dir === "rtl" ? "left" : "right", children: [
241
249
  toasts.map((t) => {
242
250
  const i = order.indexOf(t.id);
243
251
  const action = t.action ?? (t.undo && { label: t.undo.label ?? messages.undo, onClick: t.undo.onUndo });
@@ -1,15 +1,16 @@
1
1
  'use client';
2
2
  import {
3
3
  floatingSurface
4
- } from "./chunk-FLZD7HQY.js";
4
+ } from "./chunk-5FWJXSXT.js";
5
5
  import {
6
6
  field,
7
7
  fieldFocusVisible
8
- } from "./chunk-7SXR4PGO.js";
8
+ } from "./chunk-5W3AOOYS.js";
9
9
  import {
10
10
  useIntlLocale,
11
+ useLocale,
11
12
  useNexubMessages
12
- } from "./chunk-743Y5MY3.js";
13
+ } from "./chunk-3MSIO7KM.js";
13
14
  import {
14
15
  cn
15
16
  } from "./chunk-Q7G5WGYV.js";
@@ -21,9 +22,44 @@ import { DayPicker } from "react-day-picker";
21
22
  import { format } from "date-fns";
22
23
  import { CalendarDays, ChevronLeft, ChevronRight } from "@nexub/icons";
23
24
  import { jsx, jsxs } from "react/jsx-runtime";
24
- function formatDate(date, locale) {
25
+ function formatDate(date, locale, dateLocale) {
26
+ if (dateLocale) return format(date, "PP", { locale: dateLocale });
25
27
  return locale ? new Intl.DateTimeFormat(locale, { dateStyle: "medium" }).format(date) : format(date, "PP");
26
28
  }
29
+ function CalendarChevron({ orientation, ...rest }) {
30
+ const { dir } = useLocale();
31
+ const flip = dir === "rtl";
32
+ if (orientation === "left" || orientation === "right") {
33
+ const Icon = orientation === "left" !== flip ? ChevronLeft : ChevronRight;
34
+ return /* @__PURE__ */ jsx(Icon, { size: "xs", "aria-hidden": "true" });
35
+ }
36
+ return /* @__PURE__ */ jsx(ChevronRight, { size: "xs", "aria-hidden": "true", ...rest });
37
+ }
38
+ function useCalendarLocale(localeProp) {
39
+ const { dir, dateLocale } = useLocale();
40
+ const messages = useNexubMessages();
41
+ const intlLocale = useIntlLocale();
42
+ const locale = localeProp ?? dateLocale;
43
+ const labels = React.useMemo(() => {
44
+ const day = (date, modifiers, withSelected) => {
45
+ let label = format(date, "PPPP", locale ? { locale } : void 0);
46
+ if (modifiers?.today) label = messages.todayDate(label);
47
+ if (withSelected && modifiers?.selected) label = messages.selectedDate(label);
48
+ return label;
49
+ };
50
+ return {
51
+ labelPrevious: () => messages.previousMonth,
52
+ labelNext: () => messages.nextMonth,
53
+ labelNav: () => messages.calendarNavigation,
54
+ labelDayButton: (date, modifiers) => day(date, modifiers, true),
55
+ labelGridcell: (date, modifiers) => day(date, modifiers, false)
56
+ };
57
+ }, [messages, locale]);
58
+ return {
59
+ dayPickerProps: { locale, dir, labels, components: { Chevron: CalendarChevron } },
60
+ format: (date) => formatDate(date, intlLocale, locale)
61
+ };
62
+ }
27
63
  var calendarClassNames = {
28
64
  months: "flex flex-col sm:flex-row gap-4",
29
65
  month: "flex flex-col gap-4",
@@ -60,13 +96,14 @@ var DatePicker = React.forwardRef(
60
96
  maxDate,
61
97
  className,
62
98
  id,
63
- "aria-label": ariaLabel
99
+ "aria-label": ariaLabel,
100
+ locale: localeProp
64
101
  }, ref) {
65
102
  const [open, setOpen] = React.useState(false);
66
103
  const messages = useNexubMessages();
67
104
  const placeholder = placeholderProp ?? messages.pickDate;
68
- const locale = useIntlLocale();
69
- const display = value ? formatDate(value, locale) : placeholder;
105
+ const calendar = useCalendarLocale(localeProp);
106
+ const display = value ? calendar.format(value) : placeholder;
70
107
  return /* @__PURE__ */ jsxs(RadixPopover.Root, { open, onOpenChange: setOpen, children: [
71
108
  /* @__PURE__ */ jsx(RadixPopover.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
72
109
  "button",
@@ -116,9 +153,7 @@ var DatePicker = React.forwardRef(
116
153
  showOutsideDays: true,
117
154
  className: "relative p-3",
118
155
  classNames: calendarClassNames,
119
- components: {
120
- Chevron: ({ orientation, ...rest }) => orientation === "left" ? /* @__PURE__ */ jsx(ChevronLeft, { size: "xs", "aria-hidden": "true" }) : orientation === "right" ? /* @__PURE__ */ jsx(ChevronRight, { size: "xs", "aria-hidden": "true" }) : /* @__PURE__ */ jsx(ChevronRight, { size: "xs", "aria-hidden": "true", ...rest })
121
- }
156
+ ...calendar.dayPickerProps
122
157
  }
123
158
  )
124
159
  }
@@ -129,6 +164,6 @@ var DatePicker = React.forwardRef(
129
164
  DatePicker.displayName = "DatePicker";
130
165
 
131
166
  export {
132
- formatDate,
167
+ useCalendarLocale,
133
168
  DatePicker
134
169
  };
@@ -5,10 +5,10 @@ import {
5
5
  import {
6
6
  overlaySurface,
7
7
  scrim
8
- } from "./chunk-FLZD7HQY.js";
8
+ } from "./chunk-5FWJXSXT.js";
9
9
  import {
10
10
  useNexubMessages
11
- } from "./chunk-743Y5MY3.js";
11
+ } from "./chunk-3MSIO7KM.js";
12
12
  import {
13
13
  cn
14
14
  } from "./chunk-Q7G5WGYV.js";
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  disabledText,
4
4
  pressable
5
- } from "./chunk-7SXR4PGO.js";
5
+ } from "./chunk-5W3AOOYS.js";
6
6
  import {
7
7
  useNexubMessages
8
- } from "./chunk-743Y5MY3.js";
8
+ } from "./chunk-3MSIO7KM.js";
9
9
  import {
10
10
  cn
11
11
  } from "./chunk-Q7G5WGYV.js";
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-DEIBF3P7.js";
5
5
  import {
6
6
  useNexubMessages
7
- } from "./chunk-743Y5MY3.js";
7
+ } from "./chunk-3MSIO7KM.js";
8
8
  import {
9
9
  cn
10
10
  } from "./chunk-Q7G5WGYV.js";
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
  import {
3
3
  useNexubMessages
4
- } from "./chunk-743Y5MY3.js";
4
+ } from "./chunk-3MSIO7KM.js";
5
5
  import {
6
6
  cn
7
7
  } from "./chunk-Q7G5WGYV.js";
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
  import {
3
3
  floatingSurface
4
- } from "./chunk-FLZD7HQY.js";
4
+ } from "./chunk-5FWJXSXT.js";
5
5
  import {
6
6
  glassSurfaceClass
7
7
  } from "./chunk-DEIBF3P7.js";
@@ -3,7 +3,7 @@ import {
3
3
  disabledContainer,
4
4
  disabledText,
5
5
  pressable
6
- } from "./chunk-7SXR4PGO.js";
6
+ } from "./chunk-5W3AOOYS.js";
7
7
  import {
8
8
  cn
9
9
  } from "./chunk-Q7G5WGYV.js";
@@ -7,17 +7,17 @@ import {
7
7
  } from "./chunk-JLUCMNVS.js";
8
8
  import {
9
9
  IconButton
10
- } from "./chunk-CQWYZPPJ.js";
10
+ } from "./chunk-NYORXEPS.js";
11
11
  import {
12
12
  fieldDisabledWithin,
13
13
  fieldFocusWithin
14
- } from "./chunk-7SXR4PGO.js";
14
+ } from "./chunk-5W3AOOYS.js";
15
15
  import {
16
16
  glassSurfaceClass
17
17
  } from "./chunk-DEIBF3P7.js";
18
18
  import {
19
19
  useNexubMessages
20
- } from "./chunk-743Y5MY3.js";
20
+ } from "./chunk-3MSIO7KM.js";
21
21
  import {
22
22
  cn
23
23
  } from "./chunk-Q7G5WGYV.js";
@@ -1,7 +1,8 @@
1
1
  'use client';
2
2
  import {
3
+ useLocale,
3
4
  useNexubMessages
4
- } from "./chunk-743Y5MY3.js";
5
+ } from "./chunk-3MSIO7KM.js";
5
6
  import {
6
7
  cn
7
8
  } from "./chunk-Q7G5WGYV.js";
@@ -10,6 +11,10 @@ import {
10
11
  import * as React from "react";
11
12
  import { Upload, X } from "@nexub/icons";
12
13
  import { jsx, jsxs } from "react/jsx-runtime";
14
+ function formatFileSize(bytes, locale) {
15
+ const [value, unit] = bytes < 1024 ? [bytes, "byte"] : bytes < 1024 * 1024 ? [bytes / 1024, "kilobyte"] : [bytes / (1024 * 1024), "megabyte"];
16
+ return new Intl.NumberFormat(locale, { style: "unit", unit, unitDisplay: "short", maximumFractionDigits: 1 }).format(value);
17
+ }
13
18
  var FileUploadContext = React.createContext(null);
14
19
  function useFileUpload() {
15
20
  const ctx = React.useContext(FileUploadContext);
@@ -59,53 +64,52 @@ var Dropzone = React.forwardRef(
59
64
  const dropped = Array.from(e.dataTransfer.files);
60
65
  addFiles(dropped);
61
66
  }
62
- return /* @__PURE__ */ jsxs(
63
- "div",
64
- {
65
- ref,
66
- role: "button",
67
- tabIndex: 0,
68
- "aria-label": messages.uploadFiles,
69
- onClick: () => inputRef.current?.click(),
70
- onKeyDown: (e) => {
71
- if (e.key === "Enter" || e.key === " ") inputRef.current?.click();
72
- },
73
- onDragOver: (e) => {
74
- e.preventDefault();
75
- setIsDragging(true);
76
- },
77
- onDragLeave: () => setIsDragging(false),
78
- onDrop: handleDrop,
79
- className: cn(
80
- // Hover/press = the state layer; focus = the global ring.
81
- "nx-state-layer flex cursor-pointer flex-col items-center justify-center gap-2 rounded-shape-container border-2 border-dashed p-8 text-center text-[var(--color-on-surface)] transition-colors",
82
- isDragging ? "border-[var(--color-primary)] bg-[color-mix(in_srgb,var(--color-primary)_8%,transparent)]" : "border-[var(--color-outline)] hover:border-[var(--color-primary)]",
83
- className
84
- ),
85
- ...props,
86
- children: [
87
- /* @__PURE__ */ jsx(Upload, { size: "lg", className: "text-[var(--color-on-surface-muted)]", "aria-hidden": "true" }),
88
- children ?? /* @__PURE__ */ jsxs("p", { className: "text-sm text-[var(--color-on-surface-muted)]", children: [
89
- /* @__PURE__ */ jsx("span", { className: "font-semibold text-[var(--color-primary)]", children: messages.clickToUpload }),
90
- " ",
91
- messages.orDragAndDrop
92
- ] }),
93
- /* @__PURE__ */ jsx(
94
- "input",
95
- {
96
- ref: inputRef,
97
- type: "file",
98
- className: "sr-only",
99
- multiple: true,
100
- accept: accept?.join(","),
101
- onChange: (e) => {
102
- if (e.target.files) addFiles(Array.from(e.target.files));
103
- e.target.value = "";
67
+ return (
68
+ // A <label> around the native file input: click, Enter and Space open the
69
+ // picker natively, the visible text is the accessible name, and the
70
+ // focus ring follows the input's keyboard focus onto the drop zone.
71
+ /* @__PURE__ */ jsx(
72
+ "div",
73
+ {
74
+ ref,
75
+ onDragOver: (e) => {
76
+ e.preventDefault();
77
+ setIsDragging(true);
78
+ },
79
+ onDragLeave: () => setIsDragging(false),
80
+ onDrop: handleDrop,
81
+ className: cn(
82
+ // Hover/press = the state layer.
83
+ "nx-state-layer rounded-shape-container border-2 border-dashed text-center text-[var(--color-on-surface)] transition-colors",
84
+ "has-[input:focus-visible]:outline has-[input:focus-visible]:outline-[3px] has-[input:focus-visible]:outline-offset-2 has-[input:focus-visible]:outline-[var(--color-primary)]",
85
+ isDragging ? "border-[var(--color-primary)] bg-[color-mix(in_srgb,var(--color-primary)_8%,transparent)]" : "border-[var(--color-outline)] hover:border-[var(--color-primary)]",
86
+ className
87
+ ),
88
+ ...props,
89
+ children: /* @__PURE__ */ jsxs("label", { className: "flex cursor-pointer flex-col items-center justify-center gap-2 p-8", children: [
90
+ /* @__PURE__ */ jsx(Upload, { size: "lg", className: "text-[var(--color-on-surface-muted)]", "aria-hidden": "true" }),
91
+ children ?? /* @__PURE__ */ jsxs("span", { className: "text-sm text-[var(--color-on-surface-muted)]", children: [
92
+ /* @__PURE__ */ jsx("span", { className: "font-semibold text-[var(--color-primary)]", children: messages.clickToUpload }),
93
+ " ",
94
+ messages.orDragAndDrop
95
+ ] }),
96
+ /* @__PURE__ */ jsx(
97
+ "input",
98
+ {
99
+ ref: inputRef,
100
+ type: "file",
101
+ className: "sr-only",
102
+ multiple: true,
103
+ accept: accept?.join(","),
104
+ onChange: (e) => {
105
+ if (e.target.files) addFiles(Array.from(e.target.files));
106
+ e.target.value = "";
107
+ }
104
108
  }
105
- }
106
- )
107
- ]
108
- }
109
+ )
110
+ ] })
111
+ }
112
+ )
109
113
  );
110
114
  }
111
115
  );
@@ -121,6 +125,7 @@ List.displayName = "FileUpload.List";
121
125
  var Item = React.forwardRef(({ className, index, ...props }, ref) => {
122
126
  const { files, removeFile } = useFileUpload();
123
127
  const messages = useNexubMessages();
128
+ const { locale } = useLocale();
124
129
  const file = files[index];
125
130
  if (!file) return null;
126
131
  return /* @__PURE__ */ jsxs(
@@ -135,10 +140,7 @@ var Item = React.forwardRef(({ className, index, ...props }, ref) => {
135
140
  children: [
136
141
  /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
137
142
  /* @__PURE__ */ jsx("p", { className: "truncate text-sm font-medium text-[var(--color-on-surface)]", children: file.name }),
138
- /* @__PURE__ */ jsxs("p", { className: "text-xs text-[var(--color-on-surface-muted)]", children: [
139
- (file.size / 1024).toFixed(1),
140
- " KB"
141
- ] })
143
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-[var(--color-on-surface-muted)]", children: formatFileSize(file.size, locale) })
142
144
  ] }),
143
145
  /* @__PURE__ */ jsx(
144
146
  "button",
@@ -1,10 +1,10 @@
1
1
  'use client';
2
2
  import {
3
3
  Input
4
- } from "./chunk-JHVYI5GK.js";
4
+ } from "./chunk-F7ZA2VA2.js";
5
5
  import {
6
6
  useNexubMessages
7
- } from "./chunk-743Y5MY3.js";
7
+ } from "./chunk-3MSIO7KM.js";
8
8
  import {
9
9
  cn
10
10
  } from "./chunk-Q7G5WGYV.js";