@nexub/react 1.5.1 → 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 (207) hide show
  1. package/dist/chunk-24ZFAXB2.js +101 -0
  2. package/dist/{chunk-XR4NBY54.js → chunk-2DYKENBM.js} +10 -10
  3. package/dist/{chunk-SVQCINRE.js → chunk-2I7FIU6R.js} +5 -2
  4. package/dist/{chunk-S46W2QER.js → chunk-37L5ERUJ.js} +17 -11
  5. package/dist/{chunk-CWS37T3K.js → chunk-3E7X3YK3.js} +4 -2
  6. package/dist/{chunk-EZ23IA3H.js → chunk-3LTB6TGN.js} +4 -4
  7. package/dist/chunk-3QD76BKT.js +80 -0
  8. package/dist/{chunk-PQ6GU7SG.js → chunk-4HQFOIZW.js} +20 -14
  9. package/dist/{chunk-RLE5RN3T.js → chunk-4NFUBFYK.js} +15 -11
  10. package/dist/{chunk-B54WADL4.js → chunk-4P2JJ2FH.js} +12 -12
  11. package/dist/{chunk-I4BHRVRL.js → chunk-4UBVU53C.js} +9 -5
  12. package/dist/chunk-52ZVJPF7.js +1 -0
  13. package/dist/chunk-5QEARXY3.js +55 -0
  14. package/dist/chunk-643EYCLL.js +54 -0
  15. package/dist/{chunk-CNNJFWFA.js → chunk-6BGUZQAX.js} +4 -4
  16. package/dist/{chunk-LDYD7WL3.js → chunk-6ECOCGZG.js} +4 -3
  17. package/dist/{chunk-3AXIMXDU.js → chunk-6JBQAJJD.js} +6 -12
  18. package/dist/{chunk-YRDCY6BI.js → chunk-6UKNUI46.js} +0 -19
  19. package/dist/chunk-77LYWSJW.js +85 -0
  20. package/dist/{chunk-NCRFKPA4.js → chunk-7MSIOYJZ.js} +6 -8
  21. package/dist/{chunk-GIGOTRXX.js → chunk-7VJABRKB.js} +3 -10
  22. package/dist/{chunk-6QLLH6ID.js → chunk-7XWJCFWI.js} +8 -17
  23. package/dist/chunk-A3O23F2B.js +1 -0
  24. package/dist/chunk-AGYGWU6C.js +88 -0
  25. package/dist/chunk-AT2DSFP3.js +47 -0
  26. package/dist/{chunk-IIPYF6ZQ.js → chunk-B254JXS7.js} +16 -13
  27. package/dist/{chunk-GRB6T2TT.js → chunk-BSL62LBX.js} +19 -13
  28. package/dist/{chunk-GHCV6UXG.js → chunk-BTYDDKRQ.js} +5 -5
  29. package/dist/chunk-C6JRJ6JW.js +167 -0
  30. package/dist/chunk-CAOLGXA5.js +1 -0
  31. package/dist/{chunk-OJ2TLWYD.js → chunk-CKFRMCZ7.js} +5 -3
  32. package/dist/{chunk-LZB3KTSH.js → chunk-CQWYZPPJ.js} +1 -1
  33. package/dist/{chunk-6RBNM5RO.js → chunk-CUOASXI7.js} +10 -10
  34. package/dist/{chunk-HG6HTUWU.js → chunk-CV5ZKED7.js} +2 -2
  35. package/dist/{chunk-HJERFB7J.js → chunk-DDRYT3SY.js} +2 -2
  36. package/dist/chunk-DGCAM2UJ.js +60 -0
  37. package/dist/{chunk-FD7YU53N.js → chunk-DT3QGFXB.js} +4 -4
  38. package/dist/chunk-F73DTG2V.js +123 -0
  39. package/dist/{chunk-Z3IG5WRA.js → chunk-FJUVYRNT.js} +3 -3
  40. package/dist/{chunk-KQPLFVFR.js → chunk-FLZD7HQY.js} +0 -2
  41. package/dist/chunk-GG54WBLA.js +134 -0
  42. package/dist/{chunk-64JDZWCV.js → chunk-GRKCUQG4.js} +6 -5
  43. package/dist/{chunk-YPHNHQYQ.js → chunk-GWDEKW7P.js} +6 -2
  44. package/dist/{chunk-4I5ULCYG.js → chunk-HFTS5AN7.js} +3 -3
  45. package/dist/{chunk-GUB7YKG2.js → chunk-I4U36P54.js} +6 -3
  46. package/dist/{chunk-BTRTORKU.js → chunk-I6CAF7C5.js} +6 -7
  47. package/dist/{chunk-TJCHA3OI.js → chunk-J65MK3N4.js} +7 -4
  48. package/dist/{chunk-IK23Q2OF.js → chunk-JHVYI5GK.js} +3 -3
  49. package/dist/{chunk-J6TU45KP.js → chunk-JSBNYRO4.js} +26 -12
  50. package/dist/chunk-K5FKEAAK.js +94 -0
  51. package/dist/{chunk-5URGARPH.js → chunk-KE4YVG5Q.js} +6 -10
  52. package/dist/{chunk-QCNLE27O.js → chunk-KRCLK5O4.js} +11 -7
  53. package/dist/{chunk-A4IMFAZX.js → chunk-LESI7J7B.js} +3 -3
  54. package/dist/chunk-MLT7SA3T.js +171 -0
  55. package/dist/chunk-MNEXMMLM.js +23 -0
  56. package/dist/{chunk-PVTACENM.js → chunk-MTK3GHDQ.js} +2 -2
  57. package/dist/chunk-MYP5ZTC3.js +169 -0
  58. package/dist/chunk-NA5UMOE5.js +55 -0
  59. package/dist/chunk-NAJKIBU2.js +163 -0
  60. package/dist/{chunk-WESZPFBZ.js → chunk-NERAWEIQ.js} +7 -4
  61. package/dist/{chunk-YJ3JQYAN.js → chunk-NGQKBDHA.js} +5 -13
  62. package/dist/{chunk-7Q7ZF6BY.js → chunk-NNIFOMIH.js} +18 -8
  63. package/dist/{chunk-7L3CGIRA.js → chunk-NQPGELMP.js} +8 -19
  64. package/dist/{chunk-5O34ZNC3.js → chunk-NYWD5SI4.js} +19 -13
  65. package/dist/chunk-NZR4UGUZ.js +143 -0
  66. package/dist/{chunk-6J3QTWKC.js → chunk-NZT4TTNV.js} +18 -9
  67. package/dist/{chunk-JSD3H7WV.js → chunk-OYCK6BRG.js} +6 -6
  68. package/dist/{chunk-2555JXCP.js → chunk-PBPUSRTJ.js} +19 -11
  69. package/dist/{chunk-QD7H3WV3.js → chunk-PGDXFBKT.js} +8 -8
  70. package/dist/{chunk-NIX4SEKM.js → chunk-PREMZMLU.js} +7 -4
  71. package/dist/{chunk-4SSUM4CL.js → chunk-QUNH4BFR.js} +9 -6
  72. package/dist/{chunk-FHFVBOF3.js → chunk-QUYOV2ZJ.js} +6 -4
  73. package/dist/{chunk-KM6Z3VTI.js → chunk-QVTVDL6Y.js} +1 -1
  74. package/dist/{chunk-XI63BK3S.js → chunk-RATKKN3F.js} +3 -3
  75. package/dist/chunk-RM7MTOT5.js +339 -0
  76. package/dist/{chunk-DJZZ3FIP.js → chunk-RUR57JZQ.js} +5 -14
  77. package/dist/{chunk-ZV3AF5CL.js → chunk-S2CTBFLN.js} +13 -2
  78. package/dist/{chunk-72I7EVOL.js → chunk-SYZADSLI.js} +10 -6
  79. package/dist/{chunk-W2NEXOTG.js → chunk-T7RLPFGX.js} +2 -2
  80. package/dist/chunk-TAVVXXGO.js +131 -0
  81. package/dist/{chunk-BFRX6X4O.js → chunk-TZ6KJIR4.js} +23 -17
  82. package/dist/{chunk-V3TETH4J.js → chunk-U2ZYPPRG.js} +17 -16
  83. package/dist/{chunk-AHT35UWY.js → chunk-UTLKZPKJ.js} +10 -6
  84. package/dist/{chunk-OJRSPDNJ.js → chunk-VD4RFTNV.js} +8 -14
  85. package/dist/chunk-VLQGQFW7.js +110 -0
  86. package/dist/{chunk-RTDUTWJ4.js → chunk-VMT7Y3AT.js} +5 -8
  87. package/dist/{chunk-AXOKFS4K.js → chunk-W3KO3JNZ.js} +20 -4
  88. package/dist/{chunk-LGQ737BP.js → chunk-WHTLXQB6.js} +1 -1
  89. package/dist/chunk-WLRRMT6W.js +1 -0
  90. package/dist/{chunk-2FCSWBSM.js → chunk-WMWX6DPB.js} +3 -3
  91. package/dist/{chunk-UMC64NCT.js → chunk-WVBGQCYC.js} +6 -3
  92. package/dist/{chunk-TEOLG3N2.js → chunk-X4BQHXLB.js} +10 -6
  93. package/dist/{chunk-SY6V3HAK.js → chunk-XDU27NRX.js} +3 -3
  94. package/dist/{chunk-KA2J5OBA.js → chunk-XQDD76EF.js} +4 -7
  95. package/dist/chunk-XTATJMY6.js +64 -0
  96. package/dist/chunk-XYXMPHND.js +1 -0
  97. package/dist/{chunk-7ZWBHHRK.js → chunk-YNU6VRD5.js} +23 -32
  98. package/dist/{chunk-6SJPVQQW.js → chunk-Z3HF6XJ3.js} +1 -1
  99. package/dist/{chunk-I4URNMI7.js → chunk-ZC4MZAEX.js} +9 -7
  100. package/dist/{chunk-PWBPHGM3.js → chunk-ZCEUVK2R.js} +2 -2
  101. package/dist/{chunk-NQVRF4RB.js → chunk-ZMJ54TG6.js} +16 -13
  102. package/dist/chunk-ZT3NWE5U.js +1 -0
  103. package/dist/{chunk-RHOYF7MO.js → chunk-ZTLALVWA.js} +6 -15
  104. package/dist/components/Accordion/index.js +1 -1
  105. package/dist/components/Alert/index.js +2 -1
  106. package/dist/components/AlertDialog/index.js +3 -3
  107. package/dist/components/Amount/index.js +3 -1
  108. package/dist/components/AspectRatio/index.js +1 -1
  109. package/dist/components/Autocomplete/index.js +3 -2
  110. package/dist/components/Avatar/index.js +1 -1
  111. package/dist/components/AvatarGroup/index.js +3 -2
  112. package/dist/components/Badge/index.js +1 -1
  113. package/dist/components/Banner/index.js +2 -1
  114. package/dist/components/Breadcrumb/index.js +2 -1
  115. package/dist/components/Button/index.js +1 -1
  116. package/dist/components/ButtonGroup/index.js +1 -1
  117. package/dist/components/Callout/index.js +1 -1
  118. package/dist/components/Card/index.js +3 -1
  119. package/dist/components/CheckList/index.js +1 -1
  120. package/dist/components/Checkbox/index.js +1 -1
  121. package/dist/components/CheckboxCard/index.js +9 -0
  122. package/dist/components/Chip/index.js +2 -1
  123. package/dist/components/Citation/index.js +17 -0
  124. package/dist/components/Code/index.js +1 -1
  125. package/dist/components/Combobox/index.js +1 -1
  126. package/dist/components/CommandPalette/index.js +3 -2
  127. package/dist/components/ContextMenu/index.js +2 -2
  128. package/dist/components/CountryBadge/index.js +1 -1
  129. package/dist/components/DataTable/index.js +2 -1
  130. package/dist/components/DatePicker/index.js +5 -1
  131. package/dist/components/DateRangePicker/index.js +5 -1
  132. package/dist/components/Dialog/index.js +2 -2
  133. package/dist/components/Drawer/index.js +2 -2
  134. package/dist/components/DropdownMenu/index.js +2 -2
  135. package/dist/components/EmptyState/index.js +1 -1
  136. package/dist/components/ErrorState/index.js +2 -1
  137. package/dist/components/EyebrowChip/index.js +4 -1
  138. package/dist/components/FileUpload/index.js +2 -1
  139. package/dist/components/FilterChip/index.js +3 -1
  140. package/dist/components/Flex/index.js +2 -1
  141. package/dist/components/FormError/index.js +1 -1
  142. package/dist/components/FormField/index.js +7 -4
  143. package/dist/components/GradientDivider/index.js +1 -1
  144. package/dist/components/Grid/index.js +2 -1
  145. package/dist/components/Heading/index.js +4 -1
  146. package/dist/components/HelperText/index.js +4 -1
  147. package/dist/components/HoverCard/index.js +3 -2
  148. package/dist/components/IconButton/index.js +2 -1
  149. package/dist/components/Input/index.js +1 -1
  150. package/dist/components/Kbd/index.js +1 -1
  151. package/dist/components/KeyboardShortcut/index.js +2 -2
  152. package/dist/components/Label/index.js +4 -1
  153. package/dist/components/Link/index.js +1 -1
  154. package/dist/components/Logo/index.js +1 -1
  155. package/dist/components/MediaCard/index.js +9 -0
  156. package/dist/components/Menubar/index.js +2 -2
  157. package/dist/components/MessageBubble/index.js +18 -0
  158. package/dist/components/MoneyInput/index.js +3 -2
  159. package/dist/components/NavigationMenu/index.js +2 -2
  160. package/dist/components/NavigationRail/index.js +2 -1
  161. package/dist/components/NexubProvider/index.js +14 -0
  162. package/dist/components/NumberInput/index.js +3 -2
  163. package/dist/components/NumberTicker/index.js +10 -0
  164. package/dist/components/PageHeader/index.js +1 -1
  165. package/dist/components/Pagination/index.js +3 -1
  166. package/dist/components/PasswordInput/index.js +3 -2
  167. package/dist/components/Popover/index.js +2 -2
  168. package/dist/components/Progress/index.js +2 -1
  169. package/dist/components/PromptInput/index.js +15 -0
  170. package/dist/components/RadioCard/index.js +11 -0
  171. package/dist/components/RadioGroup/index.js +1 -1
  172. package/dist/components/Rating/index.js +2 -1
  173. package/dist/components/ScrollArea/index.js +1 -1
  174. package/dist/components/SearchInput/index.js +3 -2
  175. package/dist/components/Section/index.js +1 -1
  176. package/dist/components/SegmentedControl/index.js +3 -2
  177. package/dist/components/Select/index.js +2 -2
  178. package/dist/components/Separator/index.js +1 -1
  179. package/dist/components/Sidebar/index.js +2 -1
  180. package/dist/components/Skeleton/index.js +1 -1
  181. package/dist/components/Spinner/index.js +2 -1
  182. package/dist/components/SplitButton/index.js +5 -5
  183. package/dist/components/Stack/index.js +2 -1
  184. package/dist/components/StatusPill/index.js +1 -1
  185. package/dist/components/StreamingText/index.js +8 -0
  186. package/dist/components/Switch/index.js +1 -1
  187. package/dist/components/Table/index.js +1 -1
  188. package/dist/components/Tabs/index.js +3 -2
  189. package/dist/components/Tag/index.js +1 -1
  190. package/dist/components/Text/index.js +1 -1
  191. package/dist/components/Textarea/index.js +1 -1
  192. package/dist/components/ThinkingIndicator/index.js +9 -0
  193. package/dist/components/Toast/index.js +3 -1
  194. package/dist/components/Tooltip/index.js +2 -1
  195. package/dist/components/TopNav/index.js +2 -1
  196. package/dist/index.d.ts +440 -24
  197. package/dist/index.js +225 -146
  198. package/package.json +52 -50
  199. package/dist/chunk-63DPMUMR.js +0 -67
  200. package/dist/chunk-CHGPGRML.js +0 -115
  201. package/dist/chunk-H2W7IYVY.js +0 -155
  202. package/dist/chunk-J2T4GFFS.js +0 -85
  203. package/dist/chunk-LH3BSAIS.js +0 -119
  204. package/dist/chunk-LMPGHWUA.js +0 -114
  205. package/dist/chunk-NMH5WSZG.js +0 -72
  206. package/dist/chunk-P44EROBX.js +0 -55
  207. package/dist/chunk-TYTW4F3B.js +0 -178
@@ -0,0 +1,171 @@
1
+ 'use client';
2
+ import {
3
+ useMergedRefs
4
+ } from "./chunk-MNEXMMLM.js";
5
+ import {
6
+ useControllableState
7
+ } from "./chunk-JLUCMNVS.js";
8
+ import {
9
+ IconButton
10
+ } from "./chunk-CQWYZPPJ.js";
11
+ import {
12
+ fieldDisabledWithin,
13
+ fieldFocusWithin
14
+ } from "./chunk-7SXR4PGO.js";
15
+ import {
16
+ glassSurfaceClass
17
+ } from "./chunk-DEIBF3P7.js";
18
+ import {
19
+ useNexubMessages
20
+ } from "./chunk-24ZFAXB2.js";
21
+ import {
22
+ cn
23
+ } from "./chunk-Q7G5WGYV.js";
24
+
25
+ // src/components/PromptInput/PromptInput.tsx
26
+ import * as React from "react";
27
+ import { ArrowUp } from "@nexub/icons";
28
+ import { jsx, jsxs } from "react/jsx-runtime";
29
+ var fallbackMessages = {
30
+ promptLabel: "Message",
31
+ sendMessage: "Send message",
32
+ stopGenerating: "Stop generating",
33
+ promptHint: "Press Enter to send, Shift+Enter for a new line"
34
+ };
35
+ var stopIcon = /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "size-3.5 rounded-shape-min bg-current" });
36
+ var PromptInput = React.forwardRef(
37
+ ({
38
+ value: valueProp,
39
+ defaultValue = "",
40
+ onValueChange,
41
+ onSubmit,
42
+ onStop,
43
+ status = "idle",
44
+ maxRows = 8,
45
+ attachments,
46
+ actions,
47
+ surface = "solid",
48
+ label,
49
+ messages: messagesProp,
50
+ className,
51
+ textareaClassName,
52
+ disabled,
53
+ onKeyDown,
54
+ id,
55
+ "aria-describedby": describedBy,
56
+ ...props
57
+ }, ref) => {
58
+ const m = {
59
+ ...fallbackMessages,
60
+ ...useNexubMessages(),
61
+ ...messagesProp
62
+ };
63
+ const [value = "", setValue] = useControllableState({
64
+ value: valueProp,
65
+ defaultValue,
66
+ onChange: onValueChange
67
+ });
68
+ const hintId = React.useId();
69
+ const growRef = React.useRef(null);
70
+ const textareaRef = React.useRef(null);
71
+ const mergedRef = useMergedRefs(ref, textareaRef);
72
+ React.useEffect(() => {
73
+ growRef.current?.style.setProperty("--nx-max-rows", String(maxRows));
74
+ }, [maxRows]);
75
+ const streaming = status === "streaming";
76
+ const canSubmit = !disabled && status === "idle" && value.trim() !== "";
77
+ const submit = () => {
78
+ if (!canSubmit) return;
79
+ onSubmit?.(value);
80
+ if (valueProp === void 0) setValue("");
81
+ };
82
+ const handleKeyDown = (e) => {
83
+ onKeyDown?.(e);
84
+ if (e.defaultPrevented) return;
85
+ if (e.key === "Enter" && !e.shiftKey) {
86
+ if (e.nativeEvent.isComposing || e.keyCode === 229) return;
87
+ e.preventDefault();
88
+ submit();
89
+ } else if (e.key === "Escape" && streaming) {
90
+ e.preventDefault();
91
+ onStop?.();
92
+ }
93
+ };
94
+ const textClass = "col-start-1 row-start-1 m-0 px-1 py-1.5 text-body-md max-h-[calc(var(--nx-max-rows,8)*1lh+0.75rem)] whitespace-pre-wrap break-words";
95
+ return /* @__PURE__ */ jsxs(
96
+ "div",
97
+ {
98
+ className: cn(
99
+ "flex flex-col gap-2 p-3 rounded-shape-overlay border border-[var(--color-outline-variant)] bg-[var(--color-surface-container-low)] text-[var(--color-on-surface)]",
100
+ "transition-[border-color,box-shadow] duration-effects-fast ease-effects-fast",
101
+ fieldFocusWithin,
102
+ fieldDisabledWithin,
103
+ surface === "glass" && glassSurfaceClass,
104
+ className
105
+ ),
106
+ "data-material": surface === "glass" ? "glass" : void 0,
107
+ "data-status": status,
108
+ children: [
109
+ attachments && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: attachments }),
110
+ /* @__PURE__ */ jsxs("div", { ref: growRef, className: "grid", children: [
111
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: cn(textClass, "invisible overflow-hidden pointer-events-none"), children: value + "\u200B" }),
112
+ /* @__PURE__ */ jsx(
113
+ "textarea",
114
+ {
115
+ ref: mergedRef,
116
+ id,
117
+ rows: 1,
118
+ value,
119
+ onChange: (e) => setValue(e.target.value),
120
+ onKeyDown: handleKeyDown,
121
+ disabled,
122
+ "aria-label": label ?? m.promptLabel,
123
+ "aria-describedby": describedBy ? `${hintId} ${describedBy}` : hintId,
124
+ className: cn(
125
+ textClass,
126
+ "w-full resize-none overflow-y-auto bg-transparent border-0 text-inherit",
127
+ "placeholder:text-[var(--color-on-surface-muted)] focus-visible:outline-none disabled:cursor-not-allowed",
128
+ textareaClassName
129
+ ),
130
+ ...props
131
+ }
132
+ )
133
+ ] }),
134
+ /* @__PURE__ */ jsx("span", { id: hintId, hidden: true, children: m.promptHint }),
135
+ /* @__PURE__ */ jsxs("div", { className: "flex items-end gap-2", children: [
136
+ /* @__PURE__ */ jsx("div", { className: "flex min-w-0 flex-1 flex-wrap items-center gap-1", children: actions }),
137
+ streaming ? /* @__PURE__ */ jsx(
138
+ IconButton,
139
+ {
140
+ type: "button",
141
+ label: m.stopGenerating,
142
+ variant: "subtle",
143
+ disabled,
144
+ onClick: onStop,
145
+ className: "bg-[var(--color-secondary-container)] text-[var(--color-on-secondary-container)]",
146
+ children: stopIcon
147
+ }
148
+ ) : /* @__PURE__ */ jsx(
149
+ IconButton,
150
+ {
151
+ type: "button",
152
+ label: m.sendMessage,
153
+ variant: "solid",
154
+ disabled,
155
+ "aria-disabled": !canSubmit || void 0,
156
+ onClick: submit,
157
+ className: "aria-disabled:bg-[color-mix(in_srgb,var(--color-on-surface)_12%,transparent)] aria-disabled:text-[var(--color-text-disabled)]",
158
+ children: /* @__PURE__ */ jsx(ArrowUp, { size: "md" })
159
+ }
160
+ )
161
+ ] })
162
+ ]
163
+ }
164
+ );
165
+ }
166
+ );
167
+ PromptInput.displayName = "PromptInput";
168
+
169
+ export {
170
+ PromptInput
171
+ };
@@ -0,0 +1,23 @@
1
+ 'use client';
2
+
3
+ // src/hooks/useMergedRefs.ts
4
+ import { useCallback, useRef } from "react";
5
+ function setRef(ref, value) {
6
+ if (!ref) return;
7
+ if (typeof ref === "function") {
8
+ ref(value);
9
+ } else {
10
+ ref.current = value;
11
+ }
12
+ }
13
+ function useMergedRefs(...refs) {
14
+ const refsRef = useRef(refs);
15
+ refsRef.current = refs;
16
+ return useCallback((node) => {
17
+ for (const ref of refsRef.current) setRef(ref, node);
18
+ }, []);
19
+ }
20
+
21
+ export {
22
+ useMergedRefs
23
+ };
@@ -11,8 +11,8 @@ var PageHeader = React.forwardRef(
11
11
  breadcrumb && /* @__PURE__ */ jsx("div", { children: breadcrumb }),
12
12
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between", children: [
13
13
  /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
14
- /* @__PURE__ */ jsx("h1", { className: "text-2xl font-semibold tracking-tight text-[var(--color-text-primary)] truncate", children: title }),
15
- description && /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-[var(--color-text-muted)]", children: description })
14
+ /* @__PURE__ */ jsx("h1", { className: "text-2xl font-semibold tracking-tight text-[var(--color-on-surface)] truncate", children: title }),
15
+ description && /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-[var(--color-on-surface-muted)]", children: description })
16
16
  ] }),
17
17
  actions && /* @__PURE__ */ jsx("div", { className: "flex shrink-0 items-center gap-2", children: actions })
18
18
  ] })
@@ -0,0 +1,169 @@
1
+ 'use client';
2
+ import {
3
+ floatingSurface
4
+ } from "./chunk-FLZD7HQY.js";
5
+ import {
6
+ field,
7
+ fieldFocusVisible
8
+ } from "./chunk-7SXR4PGO.js";
9
+ import {
10
+ useIntlLocale,
11
+ useLocale,
12
+ useNexubMessages
13
+ } from "./chunk-24ZFAXB2.js";
14
+ import {
15
+ cn
16
+ } from "./chunk-Q7G5WGYV.js";
17
+
18
+ // src/components/DatePicker/DatePicker.tsx
19
+ import * as React from "react";
20
+ import * as RadixPopover from "@radix-ui/react-popover";
21
+ import { DayPicker } from "react-day-picker";
22
+ import { format } from "date-fns";
23
+ import { CalendarDays, ChevronLeft, ChevronRight } from "@nexub/icons";
24
+ import { jsx, jsxs } from "react/jsx-runtime";
25
+ function formatDate(date, locale, dateLocale) {
26
+ if (dateLocale) return format(date, "PP", { locale: dateLocale });
27
+ return locale ? new Intl.DateTimeFormat(locale, { dateStyle: "medium" }).format(date) : format(date, "PP");
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
+ }
63
+ var calendarClassNames = {
64
+ months: "flex flex-col sm:flex-row gap-4",
65
+ month: "flex flex-col gap-4",
66
+ month_caption: "flex h-8 items-center justify-center",
67
+ caption_label: "text-label-lg text-[var(--color-on-surface)]",
68
+ // v9 renders nav beside the months, not in the caption: pin it to the caption row.
69
+ nav: "pointer-events-none absolute inset-x-3 top-3 flex h-8 items-center justify-between",
70
+ button_previous: "nx-state-layer pointer-events-auto inline-flex h-7 w-7 items-center justify-center rounded-full text-[var(--color-on-surface)] disabled:pointer-events-none disabled:text-[var(--color-text-disabled)]",
71
+ button_next: "nx-state-layer pointer-events-auto inline-flex h-7 w-7 items-center justify-center rounded-full text-[var(--color-on-surface)] disabled:pointer-events-none disabled:text-[var(--color-text-disabled)]",
72
+ month_grid: "w-full border-collapse",
73
+ weekdays: "flex",
74
+ weekday: "text-[var(--color-on-surface-muted)] w-8 text-label-sm flex-1 text-center",
75
+ week: "flex w-full mt-2",
76
+ day: "relative flex flex-1 justify-center p-0 text-center focus-within:z-20",
77
+ day_button: cn(
78
+ // Capsule day with a state layer; focus = the global ring. The transparent
79
+ // border carries today's primary outline.
80
+ "nx-state-layer inline-flex h-8 w-8 items-center justify-center rounded-full border border-transparent text-body-sm text-[var(--color-on-surface)]",
81
+ "disabled:pointer-events-none disabled:text-[var(--color-text-disabled)]"
82
+ ),
83
+ selected: "[&>button]:bg-[var(--color-primary)] [&>button]:text-[var(--color-on-primary)]",
84
+ today: "[&>button]:border-[var(--color-primary)]",
85
+ outside: "[&:not([data-selected]):not([data-disabled])>button]:text-[var(--color-on-surface-muted)]",
86
+ disabled: "",
87
+ hidden: "invisible"
88
+ };
89
+ var DatePicker = React.forwardRef(
90
+ function DatePicker2({
91
+ value,
92
+ onChange,
93
+ placeholder: placeholderProp,
94
+ disabled = false,
95
+ minDate,
96
+ maxDate,
97
+ className,
98
+ id,
99
+ "aria-label": ariaLabel,
100
+ locale: localeProp
101
+ }, ref) {
102
+ const [open, setOpen] = React.useState(false);
103
+ const messages = useNexubMessages();
104
+ const placeholder = placeholderProp ?? messages.pickDate;
105
+ const calendar = useCalendarLocale(localeProp);
106
+ const display = value ? calendar.format(value) : placeholder;
107
+ return /* @__PURE__ */ jsxs(RadixPopover.Root, { open, onOpenChange: setOpen, children: [
108
+ /* @__PURE__ */ jsx(RadixPopover.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
109
+ "button",
110
+ {
111
+ ref,
112
+ id,
113
+ disabled,
114
+ "aria-label": ariaLabel ? `${ariaLabel}: ${display}` : display,
115
+ className: cn(
116
+ "inline-flex h-control-md w-full items-center justify-start gap-2 px-3.5 text-body-md",
117
+ field,
118
+ fieldFocusVisible,
119
+ // Open reads like focus: the 2px primary border (as Select).
120
+ "data-[state=open]:border-[var(--color-primary)] data-[state=open]:shadow-[inset_0_0_0_1px_var(--color-primary)]",
121
+ "disabled:cursor-not-allowed disabled:border-[var(--color-outline-variant)] disabled:bg-[var(--color-surface-container-low)] disabled:text-[var(--color-text-disabled)]",
122
+ !value && "text-[var(--color-on-surface-muted)]",
123
+ className
124
+ ),
125
+ children: [
126
+ /* @__PURE__ */ jsx(CalendarDays, { size: "sm", "aria-hidden": "true" }),
127
+ display
128
+ ]
129
+ }
130
+ ) }),
131
+ /* @__PURE__ */ jsx(RadixPopover.Portal, { children: /* @__PURE__ */ jsx(
132
+ RadixPopover.Content,
133
+ {
134
+ align: "start",
135
+ className: cn(
136
+ "z-[var(--z-popover)] outline-none",
137
+ floatingSurface,
138
+ "nx-motion nx-pop origin-[var(--radix-popover-content-transform-origin)]"
139
+ ),
140
+ children: /* @__PURE__ */ jsx(
141
+ DayPicker,
142
+ {
143
+ mode: "single",
144
+ selected: value,
145
+ defaultMonth: value,
146
+ onSelect: (date) => {
147
+ onChange?.(date);
148
+ setOpen(false);
149
+ },
150
+ startMonth: minDate,
151
+ endMonth: maxDate,
152
+ initialFocus: true,
153
+ showOutsideDays: true,
154
+ className: "relative p-3",
155
+ classNames: calendarClassNames,
156
+ ...calendar.dayPickerProps
157
+ }
158
+ )
159
+ }
160
+ ) })
161
+ ] });
162
+ }
163
+ );
164
+ DatePicker.displayName = "DatePicker";
165
+
166
+ export {
167
+ useCalendarLocale,
168
+ DatePicker
169
+ };
@@ -0,0 +1,55 @@
1
+ 'use client';
2
+ import {
3
+ cn
4
+ } from "./chunk-Q7G5WGYV.js";
5
+
6
+ // src/components/Tag/Tag.tsx
7
+ import * as React from "react";
8
+ import { cva } from "class-variance-authority";
9
+ import { jsx } from "react/jsx-runtime";
10
+ var tagVariants = cva(
11
+ "inline-flex items-center rounded-shape-min font-medium select-none whitespace-nowrap",
12
+ {
13
+ variants: {
14
+ size: {
15
+ sm: "px-1.5 py-0.5 text-xs",
16
+ md: "px-2 py-0.5 text-xs",
17
+ lg: "px-2.5 py-1 text-sm"
18
+ },
19
+ tone: {
20
+ neutral: "bg-[var(--color-surface-container-high)] text-[var(--color-on-surface-variant)]",
21
+ info: "bg-[var(--color-info-container)] text-[var(--color-on-info-container)]",
22
+ success: "bg-[var(--color-success-container)] text-[var(--color-on-success-container)]",
23
+ warning: "bg-[var(--color-warning-container)] text-[var(--color-on-warning-container)]",
24
+ danger: "bg-[var(--color-error-container)] text-[var(--color-on-error-container)]",
25
+ leap: "bg-[var(--color-leap-container)] text-[var(--color-on-leap-container)]",
26
+ bookub: "bg-[var(--color-bookub-container)] text-[var(--color-on-bookub-container)]",
27
+ payub: "bg-[var(--color-payub-container)] text-[var(--color-on-payub-container)]",
28
+ founderub: "bg-[var(--color-founderub-container)] text-[var(--color-on-founderub-container)]"
29
+ }
30
+ },
31
+ defaultVariants: {
32
+ size: "md",
33
+ tone: "neutral"
34
+ }
35
+ }
36
+ );
37
+ var Tag = React.forwardRef(
38
+ ({ className, size, tone = "neutral", children, ...props }, ref) => {
39
+ return /* @__PURE__ */ jsx(
40
+ "span",
41
+ {
42
+ ref,
43
+ className: cn(tagVariants({ size, tone }), className),
44
+ ...props,
45
+ children
46
+ }
47
+ );
48
+ }
49
+ );
50
+ Tag.displayName = "Tag";
51
+
52
+ export {
53
+ tagVariants,
54
+ Tag
55
+ };
@@ -0,0 +1,163 @@
1
+ 'use client';
2
+ import {
3
+ useLocale,
4
+ useNexubMessages
5
+ } from "./chunk-24ZFAXB2.js";
6
+ import {
7
+ cn
8
+ } from "./chunk-Q7G5WGYV.js";
9
+
10
+ // src/components/FileUpload/FileUpload.tsx
11
+ import * as React from "react";
12
+ import { Upload, X } from "@nexub/icons";
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
+ }
18
+ var FileUploadContext = React.createContext(null);
19
+ function useFileUpload() {
20
+ const ctx = React.useContext(FileUploadContext);
21
+ if (!ctx) throw new Error("FileUpload parts must be used inside FileUpload.Root");
22
+ return ctx;
23
+ }
24
+ var Root = React.forwardRef(
25
+ ({ className, accept, maxFiles, onFilesChange, children, ...props }, ref) => {
26
+ const [files, setFiles] = React.useState([]);
27
+ const [isDragging, setIsDragging] = React.useState(false);
28
+ const addFiles = React.useCallback(
29
+ (newFiles) => {
30
+ setFiles((prev) => {
31
+ const next = [...prev, ...newFiles].slice(0, maxFiles);
32
+ onFilesChange?.(next);
33
+ return next;
34
+ });
35
+ },
36
+ [maxFiles, onFilesChange]
37
+ );
38
+ const removeFile = React.useCallback(
39
+ (index) => {
40
+ setFiles((prev) => {
41
+ const next = prev.filter((_, i) => i !== index);
42
+ onFilesChange?.(next);
43
+ return next;
44
+ });
45
+ },
46
+ [onFilesChange]
47
+ );
48
+ const contextValue = React.useMemo(
49
+ () => ({ accept, maxFiles, onFilesChange, files, addFiles, removeFile, isDragging, setIsDragging }),
50
+ [accept, maxFiles, onFilesChange, files, addFiles, removeFile, isDragging, setIsDragging]
51
+ );
52
+ return /* @__PURE__ */ jsx(FileUploadContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx("div", { ref, className: cn("flex flex-col gap-4", className), ...props, children }) });
53
+ }
54
+ );
55
+ Root.displayName = "FileUpload.Root";
56
+ var Dropzone = React.forwardRef(
57
+ ({ className, children, ...props }, ref) => {
58
+ const { accept, addFiles, isDragging, setIsDragging } = useFileUpload();
59
+ const messages = useNexubMessages();
60
+ const inputRef = React.useRef(null);
61
+ function handleDrop(e) {
62
+ e.preventDefault();
63
+ setIsDragging(false);
64
+ const dropped = Array.from(e.dataTransfer.files);
65
+ addFiles(dropped);
66
+ }
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
+ }
108
+ }
109
+ )
110
+ ] })
111
+ }
112
+ )
113
+ );
114
+ }
115
+ );
116
+ Dropzone.displayName = "FileUpload.Dropzone";
117
+ var List = React.forwardRef(
118
+ ({ className, ...props }, ref) => {
119
+ const { files } = useFileUpload();
120
+ if (files.length === 0) return null;
121
+ return /* @__PURE__ */ jsx("ul", { ref, className: cn("flex flex-col gap-2", className), ...props });
122
+ }
123
+ );
124
+ List.displayName = "FileUpload.List";
125
+ var Item = React.forwardRef(({ className, index, ...props }, ref) => {
126
+ const { files, removeFile } = useFileUpload();
127
+ const messages = useNexubMessages();
128
+ const { locale } = useLocale();
129
+ const file = files[index];
130
+ if (!file) return null;
131
+ return /* @__PURE__ */ jsxs(
132
+ "li",
133
+ {
134
+ ref,
135
+ className: cn(
136
+ "flex items-center justify-between gap-3 rounded-shape-container border border-[var(--color-outline-variant)] bg-[var(--color-surface)] p-3",
137
+ className
138
+ ),
139
+ ...props,
140
+ children: [
141
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
142
+ /* @__PURE__ */ jsx("p", { className: "truncate text-sm font-medium text-[var(--color-on-surface)]", children: file.name }),
143
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-[var(--color-on-surface-muted)]", children: formatFileSize(file.size, locale) })
144
+ ] }),
145
+ /* @__PURE__ */ jsx(
146
+ "button",
147
+ {
148
+ onClick: () => removeFile(index),
149
+ "aria-label": messages.removeFile(file.name),
150
+ className: "nx-state-layer shrink-0 rounded-full p-1 text-[var(--color-on-surface-muted)] hover:text-[var(--color-on-surface)] transition-colors",
151
+ children: /* @__PURE__ */ jsx(X, { size: "sm", "aria-hidden": "true" })
152
+ }
153
+ )
154
+ ]
155
+ }
156
+ );
157
+ });
158
+ Item.displayName = "FileUpload.Item";
159
+ var FileUpload = { Root, Dropzone, List, Item };
160
+
161
+ export {
162
+ FileUpload
163
+ };
@@ -1,7 +1,10 @@
1
1
  'use client';
2
2
  import {
3
3
  Input
4
- } from "./chunk-IK23Q2OF.js";
4
+ } from "./chunk-JHVYI5GK.js";
5
+ import {
6
+ useNexubMessages
7
+ } from "./chunk-24ZFAXB2.js";
5
8
  import {
6
9
  cn
7
10
  } from "./chunk-Q7G5WGYV.js";
@@ -13,15 +16,15 @@ import { jsx } from "react/jsx-runtime";
13
16
  var PasswordInput = React.forwardRef(
14
17
  ({ className, ...props }, ref) => {
15
18
  const [showPassword, setShowPassword] = React.useState(false);
19
+ const messages = useNexubMessages();
16
20
  const toggleButton = /* @__PURE__ */ jsx(
17
21
  "button",
18
22
  {
19
23
  type: "button",
20
24
  onClick: () => setShowPassword((prev) => !prev),
21
- "aria-label": showPassword ? "Hide password" : "Show password",
25
+ "aria-label": showPassword ? messages.hidePassword : messages.showPassword,
22
26
  className: cn(
23
- "shrink-0 text-[var(--color-text-muted)] hover:text-[var(--color-text-primary)] transition-colors",
24
- "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-[var(--color-ring-default)] rounded"
27
+ "shrink-0 rounded-full text-[var(--color-on-surface-muted)] hover:text-[var(--color-on-surface)] transition-colors"
25
28
  ),
26
29
  children: showPassword ? /* @__PURE__ */ jsx(EyeOff, { className: "h-4 w-4", "aria-hidden": "true" }) : /* @__PURE__ */ jsx(Eye, { className: "h-4 w-4", "aria-hidden": "true" })
27
30
  }
@@ -1,4 +1,7 @@
1
1
  'use client';
2
+ import {
3
+ toneTextClasses
4
+ } from "./chunk-C6JRJ6JW.js";
2
5
  import {
3
6
  cn
4
7
  } from "./chunk-Q7G5WGYV.js";
@@ -6,17 +9,6 @@ import {
6
9
  // src/components/EyebrowChip/EyebrowChip.tsx
7
10
  import * as React from "react";
8
11
  import { jsx, jsxs } from "react/jsx-runtime";
9
- var toneTextMap = {
10
- neutral: "text-[var(--color-neutral-700)]",
11
- info: "text-[var(--color-semantic-info-default)]",
12
- success: "text-[var(--color-semantic-success-default)]",
13
- warning: "text-[var(--color-semantic-warning-default)]",
14
- danger: "text-[var(--color-semantic-error-default)]",
15
- leap: "text-[var(--color-leap-700)]",
16
- bookub: "text-[var(--color-bookub-700)]",
17
- payub: "text-[var(--color-payub-700)]",
18
- founderub: "text-[var(--color-founderub-700)]"
19
- };
20
12
  var EyebrowChip = React.forwardRef(
21
13
  ({ className, tone = "neutral", leadingIcon, children, ...props }, ref) => {
22
14
  return /* @__PURE__ */ jsxs(
@@ -26,8 +18,8 @@ var EyebrowChip = React.forwardRef(
26
18
  className: cn(
27
19
  "inline-flex items-center gap-1.5 rounded-full px-3 py-1",
28
20
  "text-xs font-semibold uppercase tracking-wider select-none",
29
- "bg-[var(--color-bg-subtle)]",
30
- toneTextMap[tone],
21
+ "bg-[var(--color-surface-container-low)]",
22
+ toneTextClasses[tone],
31
23
  className
32
24
  ),
33
25
  ...props,