@nexub/react 1.6.0 → 1.7.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 (67) hide show
  1. package/dist/{chunk-743Y5MY3.js → chunk-24ZFAXB2.js} +11 -5
  2. package/dist/{chunk-HSPGJSFJ.js → chunk-37L5ERUJ.js} +1 -1
  3. package/dist/{chunk-GSG2W6DP.js → chunk-3LTB6TGN.js} +1 -1
  4. package/dist/{chunk-PMWYLYM3.js → chunk-4HQFOIZW.js} +1 -1
  5. package/dist/{chunk-DGQJRTO6.js → chunk-4NFUBFYK.js} +1 -1
  6. package/dist/{chunk-PPCGUIAB.js → chunk-4UBVU53C.js} +1 -1
  7. package/dist/{chunk-NSVXGOR3.js → chunk-643EYCLL.js} +1 -1
  8. package/dist/{chunk-MEUJBGY5.js → chunk-AGYGWU6C.js} +1 -1
  9. package/dist/{chunk-CBDJRPMD.js → chunk-B254JXS7.js} +1 -1
  10. package/dist/{chunk-3FPJIXG7.js → chunk-BSL62LBX.js} +1 -1
  11. package/dist/{chunk-5VW6RUKZ.js → chunk-GG54WBLA.js} +1 -1
  12. package/dist/{chunk-7B4VF2ZU.js → chunk-GWDEKW7P.js} +1 -1
  13. package/dist/{chunk-O626NJEM.js → chunk-J65MK3N4.js} +1 -1
  14. package/dist/{chunk-TRA6A5C5.js → chunk-JSBNYRO4.js} +1 -1
  15. package/dist/{chunk-WXRQ42DR.js → chunk-KRCLK5O4.js} +2 -2
  16. package/dist/{chunk-3MT23LNM.js → chunk-MLT7SA3T.js} +1 -1
  17. package/dist/{chunk-IGLOYOCH.js → chunk-MYP5ZTC3.js} +44 -9
  18. package/dist/{chunk-UTJJ5HFX.js → chunk-NAJKIBU2.js} +53 -51
  19. package/dist/{chunk-S7GH2BJP.js → chunk-NERAWEIQ.js} +1 -1
  20. package/dist/{chunk-VAFBGFKY.js → chunk-NYWD5SI4.js} +1 -1
  21. package/dist/{chunk-5KI4YHA3.js → chunk-NZR4UGUZ.js} +15 -16
  22. package/dist/{chunk-Q3ESHXKU.js → chunk-QUNH4BFR.js} +1 -1
  23. package/dist/{chunk-2Y4WLNEZ.js → chunk-QUYOV2ZJ.js} +3 -1
  24. package/dist/{chunk-O74XEHLA.js → chunk-RM7MTOT5.js} +11 -3
  25. package/dist/{chunk-SAUA52EJ.js → chunk-TAVVXXGO.js} +1 -1
  26. package/dist/{chunk-74RUJ5KZ.js → chunk-TZ6KJIR4.js} +1 -1
  27. package/dist/{chunk-FIDUY6SS.js → chunk-U2ZYPPRG.js} +1 -1
  28. package/dist/{chunk-7Q4T7CB6.js → chunk-UTLKZPKJ.js} +1 -1
  29. package/dist/{chunk-RSU2UHN4.js → chunk-W3KO3JNZ.js} +2 -2
  30. package/dist/{chunk-SZ2WPWXJ.js → chunk-X4BQHXLB.js} +1 -1
  31. package/dist/{chunk-HXV5UA7K.js → chunk-ZMJ54TG6.js} +1 -1
  32. package/dist/components/Alert/index.js +2 -2
  33. package/dist/components/Amount/index.js +3 -3
  34. package/dist/components/Autocomplete/index.js +2 -2
  35. package/dist/components/Avatar/index.js +1 -1
  36. package/dist/components/AvatarGroup/index.js +3 -3
  37. package/dist/components/Banner/index.js +2 -2
  38. package/dist/components/Breadcrumb/index.js +2 -2
  39. package/dist/components/Chip/index.js +2 -2
  40. package/dist/components/Citation/index.js +2 -2
  41. package/dist/components/CommandPalette/index.js +2 -2
  42. package/dist/components/DatePicker/index.js +2 -2
  43. package/dist/components/DateRangePicker/index.js +3 -3
  44. package/dist/components/FileUpload/index.js +2 -2
  45. package/dist/components/FilterChip/index.js +2 -2
  46. package/dist/components/FormField/index.js +2 -2
  47. package/dist/components/MessageBubble/index.js +2 -2
  48. package/dist/components/MoneyInput/index.js +2 -2
  49. package/dist/components/NavigationRail/index.js +2 -2
  50. package/dist/components/NexubProvider/index.js +1 -1
  51. package/dist/components/NumberInput/index.js +2 -2
  52. package/dist/components/NumberTicker/index.js +2 -2
  53. package/dist/components/Pagination/index.js +2 -2
  54. package/dist/components/PasswordInput/index.js +2 -2
  55. package/dist/components/PromptInput/index.js +2 -2
  56. package/dist/components/Rating/index.js +2 -2
  57. package/dist/components/ScrollArea/index.js +1 -1
  58. package/dist/components/SearchInput/index.js +2 -2
  59. package/dist/components/Sidebar/index.js +2 -2
  60. package/dist/components/Spinner/index.js +2 -2
  61. package/dist/components/ThinkingIndicator/index.js +2 -2
  62. package/dist/components/Toast/index.js +2 -2
  63. package/dist/components/TopNav/index.js +2 -2
  64. package/dist/index.d.ts +37 -6
  65. package/dist/index.js +69 -69
  66. package/package.json +5 -5
  67. package/dist/{chunk-BNFGVFZ3.js → chunk-RATKKN3F.js} +3 -3
@@ -35,6 +35,11 @@ var defaultMessages = {
35
35
  noResults: "No results found.",
36
36
  pickDate: "Pick a date",
37
37
  pickDateRange: "Pick a date range",
38
+ previousMonth: "Go to previous month",
39
+ nextMonth: "Go to next month",
40
+ calendarNavigation: "Calendar navigation",
41
+ todayDate: (date) => `Today, ${date}`,
42
+ selectedDate: (label) => `${label}, selected`,
38
43
  commandPalette: "Command palette",
39
44
  notifications: "Notifications ({hotkey})",
40
45
  undo: "Undo",
@@ -60,17 +65,18 @@ var defaultMessages = {
60
65
  var NexubContext = React.createContext({
61
66
  locale: void 0,
62
67
  dir: "ltr",
68
+ dateLocale: void 0,
63
69
  messages: defaultMessages
64
70
  });
65
71
  var RTL_LANGUAGES = /* @__PURE__ */ new Set(["ar", "he", "fa", "ur"]);
66
72
  function directionOf(locale) {
67
73
  return RTL_LANGUAGES.has(locale.toLowerCase().split(/[-_]/)[0]) ? "rtl" : "ltr";
68
74
  }
69
- function NexubProvider({ locale = "en", dir, messages, children }) {
75
+ function NexubProvider({ locale = "en", dir, dateLocale, messages, children }) {
70
76
  const resolvedDir = dir ?? directionOf(locale);
71
77
  const value = React.useMemo(
72
- () => ({ locale, dir: resolvedDir, messages: { ...defaultMessages, ...messages } }),
73
- [locale, resolvedDir, messages]
78
+ () => ({ locale, dir: resolvedDir, dateLocale, messages: { ...defaultMessages, ...messages } }),
79
+ [locale, resolvedDir, dateLocale, messages]
74
80
  );
75
81
  return /* @__PURE__ */ jsx(NexubContext.Provider, { value, children: /* @__PURE__ */ jsx(DirectionProvider, { dir: resolvedDir, children }) });
76
82
  }
@@ -78,8 +84,8 @@ function useNexubMessages() {
78
84
  return React.useContext(NexubContext).messages;
79
85
  }
80
86
  function useLocale() {
81
- const { locale = "en", dir } = React.useContext(NexubContext);
82
- return { locale, dir };
87
+ const { locale = "en", dir, dateLocale } = React.useContext(NexubContext);
88
+ return { locale, dir, dateLocale };
83
89
  }
84
90
  function useIntlLocale(explicit) {
85
91
  const ctx = React.useContext(NexubContext).locale;
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-7SXR4PGO.js";
5
5
  import {
6
6
  useNexubMessages
7
- } from "./chunk-743Y5MY3.js";
7
+ } from "./chunk-24ZFAXB2.js";
8
8
  import {
9
9
  cn
10
10
  } from "./chunk-Q7G5WGYV.js";
@@ -9,7 +9,7 @@ import * as RadixScrollArea from "@radix-ui/react-scroll-area";
9
9
  import { jsx, jsxs } from "react/jsx-runtime";
10
10
  var ScrollArea = React.forwardRef(
11
11
  ({ className, children, orientation = "vertical", ...props }, ref) => /* @__PURE__ */ jsxs(RadixScrollArea.Root, { ref, className: cn("relative overflow-hidden", className), ...props, children: [
12
- /* @__PURE__ */ jsx(RadixScrollArea.Viewport, { className: "h-full w-full rounded-[inherit]", children }),
12
+ /* @__PURE__ */ jsx(RadixScrollArea.Viewport, { tabIndex: 0, className: "h-full w-full rounded-[inherit]", children }),
13
13
  (orientation === "vertical" || orientation === "both") && /* @__PURE__ */ jsx(
14
14
  RadixScrollArea.Scrollbar,
15
15
  {
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-7SXR4PGO.js";
8
8
  import {
9
9
  useNexubMessages
10
- } from "./chunk-743Y5MY3.js";
10
+ } from "./chunk-24ZFAXB2.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-24ZFAXB2.js";
5
5
  import {
6
6
  cn
7
7
  } from "./chunk-Q7G5WGYV.js";
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-JLUCMNVS.js";
5
5
  import {
6
6
  useNexubMessages
7
- } from "./chunk-743Y5MY3.js";
7
+ } from "./chunk-24ZFAXB2.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-24ZFAXB2.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
  useIntlLocale
4
- } from "./chunk-743Y5MY3.js";
4
+ } from "./chunk-24ZFAXB2.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-24ZFAXB2.js";
5
5
  import {
6
6
  cn
7
7
  } 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-24ZFAXB2.js";
8
8
  import {
9
9
  cn
10
10
  } from "./chunk-Q7G5WGYV.js";
@@ -11,7 +11,7 @@ import {
11
11
  } from "./chunk-CQWYZPPJ.js";
12
12
  import {
13
13
  useNexubMessages
14
- } from "./chunk-743Y5MY3.js";
14
+ } from "./chunk-24ZFAXB2.js";
15
15
  import {
16
16
  cn
17
17
  } from "./chunk-Q7G5WGYV.js";
@@ -13,7 +13,7 @@ import {
13
13
  } from "./chunk-CIQHFMF6.js";
14
14
  import {
15
15
  useIntlLocale
16
- } from "./chunk-743Y5MY3.js";
16
+ } from "./chunk-24ZFAXB2.js";
17
17
  import {
18
18
  cn
19
19
  } from "./chunk-Q7G5WGYV.js";
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-JHVYI5GK.js";
5
5
  import {
6
6
  useNexubMessages
7
- } from "./chunk-743Y5MY3.js";
7
+ } from "./chunk-24ZFAXB2.js";
8
8
  import {
9
9
  cn
10
10
  } from "./chunk-Q7G5WGYV.js";
@@ -5,7 +5,7 @@ import {
5
5
  } from "./chunk-7SXR4PGO.js";
6
6
  import {
7
7
  useNexubMessages
8
- } from "./chunk-743Y5MY3.js";
8
+ } from "./chunk-24ZFAXB2.js";
9
9
  import {
10
10
  cn
11
11
  } 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-24ZFAXB2.js";
8
8
  import {
9
9
  cn
10
10
  } from "./chunk-Q7G5WGYV.js";
@@ -17,7 +17,7 @@ import {
17
17
  } from "./chunk-DEIBF3P7.js";
18
18
  import {
19
19
  useNexubMessages
20
- } from "./chunk-743Y5MY3.js";
20
+ } from "./chunk-24ZFAXB2.js";
21
21
  import {
22
22
  cn
23
23
  } from "./chunk-Q7G5WGYV.js";
@@ -8,8 +8,9 @@ import {
8
8
  } from "./chunk-7SXR4PGO.js";
9
9
  import {
10
10
  useIntlLocale,
11
+ useLocale,
11
12
  useNexubMessages
12
- } from "./chunk-743Y5MY3.js";
13
+ } from "./chunk-24ZFAXB2.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
  };
@@ -1,7 +1,8 @@
1
1
  'use client';
2
2
  import {
3
+ useLocale,
3
4
  useNexubMessages
4
- } from "./chunk-743Y5MY3.js";
5
+ } from "./chunk-24ZFAXB2.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",
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-JHVYI5GK.js";
5
5
  import {
6
6
  useNexubMessages
7
- } from "./chunk-743Y5MY3.js";
7
+ } from "./chunk-24ZFAXB2.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-24ZFAXB2.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
- formatDate
4
- } from "./chunk-IGLOYOCH.js";
3
+ useCalendarLocale
4
+ } from "./chunk-MYP5ZTC3.js";
5
5
  import {
6
6
  floatingSurface
7
7
  } from "./chunk-FLZD7HQY.js";
@@ -10,9 +10,8 @@ import {
10
10
  fieldFocusVisible
11
11
  } from "./chunk-7SXR4PGO.js";
12
12
  import {
13
- useIntlLocale,
14
13
  useNexubMessages
15
- } from "./chunk-743Y5MY3.js";
14
+ } from "./chunk-24ZFAXB2.js";
16
15
  import {
17
16
  cn
18
17
  } from "./chunk-Q7G5WGYV.js";
@@ -21,14 +20,14 @@ import {
21
20
  import * as React from "react";
22
21
  import * as RadixPopover from "@radix-ui/react-popover";
23
22
  import { DayPicker } from "react-day-picker";
24
- import { CalendarDays, ChevronLeft, ChevronRight } from "@nexub/icons";
23
+ import { CalendarDays } from "@nexub/icons";
25
24
  import { jsx, jsxs } from "react/jsx-runtime";
26
- function formatRange(range, placeholder, locale) {
25
+ function formatRange(range, placeholder, formatDate) {
27
26
  if (!range) return placeholder;
28
27
  if (range.from && range.to) {
29
- return `${formatDate(range.from, locale)} \u2013 ${formatDate(range.to, locale)}`;
28
+ return `${formatDate(range.from)} \u2013 ${formatDate(range.to)}`;
30
29
  }
31
- if (range.from) return `${formatDate(range.from, locale)} \u2013 \u2026`;
30
+ if (range.from) return `${formatDate(range.from)} \u2013 \u2026`;
32
31
  return placeholder;
33
32
  }
34
33
  var calendarClassNames = {
@@ -56,8 +55,9 @@ var calendarClassNames = {
56
55
  // skips middle days without depending on CSS order.
57
56
  selected: "[&:not(.nx-range-middle)>button]:bg-[var(--color-primary)] [&:not(.nx-range-middle)>button]:text-[var(--color-on-primary)]",
58
57
  // Half bands join the end capsules to the middle band (not on a one-day range).
59
- range_start: "nx-range-start [&:not(.nx-range-end)]:bg-[linear-gradient(to_right,transparent_50%,var(--color-primary-container)_50%)]",
60
- range_end: "nx-range-end [&:not(.nx-range-start)]:bg-[linear-gradient(to_left,transparent_50%,var(--color-primary-container)_50%)]",
58
+ // RTL (DayPicker's dir): the bands run the other way.
59
+ range_start: "nx-range-start [&:not(.nx-range-end)]:bg-[linear-gradient(to_right,transparent_50%,var(--color-primary-container)_50%)] rtl:[&:not(.nx-range-end)]:bg-[linear-gradient(to_left,transparent_50%,var(--color-primary-container)_50%)]",
60
+ range_end: "nx-range-end [&:not(.nx-range-start)]:bg-[linear-gradient(to_left,transparent_50%,var(--color-primary-container)_50%)] rtl:[&:not(.nx-range-start)]:bg-[linear-gradient(to_right,transparent_50%,var(--color-primary-container)_50%)]",
61
61
  range_middle: "nx-range-middle bg-[var(--color-primary-container)] [&>button]:text-[var(--color-on-primary-container)]",
62
62
  today: "[&>button]:border-[var(--color-primary)]",
63
63
  outside: "[&:not([data-selected]):not([data-disabled])>button]:text-[var(--color-on-surface-muted)]",
@@ -73,13 +73,14 @@ var DateRangePicker = React.forwardRef(function DateRangePicker2({
73
73
  maxDate,
74
74
  className,
75
75
  id,
76
- "aria-label": ariaLabel
76
+ "aria-label": ariaLabel,
77
+ locale: localeProp
77
78
  }, ref) {
78
79
  const [open, setOpen] = React.useState(false);
79
80
  const messages = useNexubMessages();
80
- const locale = useIntlLocale();
81
+ const calendar = useCalendarLocale(localeProp);
81
82
  const placeholder = placeholderProp ?? messages.pickDateRange;
82
- const display = formatRange(value, placeholder, locale);
83
+ const display = formatRange(value, placeholder, calendar.format);
83
84
  const label = ariaLabel ? `${ariaLabel}: ${display}` : display;
84
85
  return /* @__PURE__ */ jsxs(RadixPopover.Root, { open, onOpenChange: setOpen, children: [
85
86
  /* @__PURE__ */ jsx(RadixPopover.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
@@ -128,9 +129,7 @@ var DateRangePicker = React.forwardRef(function DateRangePicker2({
128
129
  showOutsideDays: false,
129
130
  className: "relative p-3",
130
131
  classNames: calendarClassNames,
131
- components: {
132
- 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 })
133
- }
132
+ ...calendar.dayPickerProps
134
133
  }
135
134
  )
136
135
  }
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
  import {
3
3
  useNexubMessages
4
- } from "./chunk-743Y5MY3.js";
4
+ } from "./chunk-24ZFAXB2.js";
5
5
  import {
6
6
  cn
7
7
  } from "./chunk-Q7G5WGYV.js";
@@ -52,13 +52,15 @@ var Avatar = React.forwardRef(
52
52
  const [imgError, setImgError] = React.useState(false);
53
53
  const showImage = Boolean(src) && !imgError;
54
54
  const initials = name ? getInitials(name) : null;
55
+ const labelled = Boolean(name || props["aria-label"] || props["aria-labelledby"]);
55
56
  return /* @__PURE__ */ jsxs(
56
57
  "span",
57
58
  {
58
59
  ref,
59
60
  className: cn(avatarVariants({ size }), className),
60
61
  "aria-label": name ?? void 0,
61
- role: "img",
62
+ role: labelled ? "img" : void 0,
63
+ "aria-hidden": labelled ? void 0 : true,
62
64
  ...props,
63
65
  children: [
64
66
  showImage ? /* @__PURE__ */ jsx(
@@ -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-24ZFAXB2.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 });
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-KE4YVG5Q.js";
5
5
  import {
6
6
  useNexubMessages
7
- } from "./chunk-743Y5MY3.js";
7
+ } from "./chunk-24ZFAXB2.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-24ZFAXB2.js";
5
5
  import {
6
6
  cn
7
7
  } from "./chunk-Q7G5WGYV.js";
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-FLZD7HQY.js";
9
9
  import {
10
10
  useNexubMessages
11
- } from "./chunk-743Y5MY3.js";
11
+ } from "./chunk-24ZFAXB2.js";
12
12
  import {
13
13
  cn
14
14
  } from "./chunk-Q7G5WGYV.js";