@nizivo/react 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (258) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +120 -2
  3. package/THIRD_PARTY_NOTICES +61 -0
  4. package/dist/_engines/react-aria/dialog.client.js +134 -0
  5. package/dist/_engines/react-aria/dom-allowlist.js +19 -0
  6. package/dist/_engines/react-aria/dom.js +31 -0
  7. package/dist/_engines/react-aria/locale.client.js +13 -0
  8. package/dist/_engines/react-aria/menu.client.js +225 -0
  9. package/dist/_engines/react-aria/overlay.client.js +41 -0
  10. package/dist/_engines/react-aria/popup.client.js +127 -0
  11. package/dist/_engines/react-aria/select.client.js +170 -0
  12. package/dist/_engines/react-aria/tabs.client.js +95 -0
  13. package/dist/_engines/react-aria/tooltip.client.js +72 -0
  14. package/dist/_internal/cx.js +11 -0
  15. package/dist/_internal/engine-part.d.ts +1 -0
  16. package/dist/_internal/field.js +20 -0
  17. package/dist/_internal/glyphs.js +34 -0
  18. package/dist/_internal/keys.js +62 -0
  19. package/dist/_internal/overlay.d.ts +9 -0
  20. package/dist/_virtual/_rolldown/runtime.js +13 -0
  21. package/dist/alert/alert-dismiss.client.d.ts +32 -0
  22. package/dist/alert/alert-dismiss.client.js +36 -0
  23. package/dist/alert/alert.d.ts +28 -0
  24. package/dist/alert/alert.js +44 -0
  25. package/dist/alert/index.d.ts +3 -0
  26. package/dist/alert/index.js +3 -0
  27. package/dist/augment.d.ts +13 -0
  28. package/dist/augment.js +0 -0
  29. package/dist/badge/badge.d.ts +19 -0
  30. package/dist/badge/badge.js +22 -0
  31. package/dist/badge/index.d.ts +2 -0
  32. package/dist/badge/index.js +1 -0
  33. package/dist/button/button.d.ts +54 -0
  34. package/dist/button/button.js +62 -0
  35. package/dist/button/index.d.ts +2 -0
  36. package/dist/button/index.js +1 -0
  37. package/dist/card/card.d.ts +57 -0
  38. package/dist/card/card.js +62 -0
  39. package/dist/card/card.parts.d.ts +6 -0
  40. package/dist/card/card.parts.js +14 -0
  41. package/dist/card/index.d.ts +3 -0
  42. package/dist/card/index.js +3 -0
  43. package/dist/checkbox/checkbox.client.d.ts +37 -0
  44. package/dist/checkbox/checkbox.client.js +81 -0
  45. package/dist/checkbox/index.d.ts +2 -0
  46. package/dist/checkbox/index.js +1 -0
  47. package/dist/config/config.client.d.ts +9 -0
  48. package/dist/config/config.client.js +18 -0
  49. package/dist/config/index.d.ts +2 -0
  50. package/dist/config/index.js +1 -0
  51. package/dist/container/container.d.ts +13 -0
  52. package/dist/container/container.js +16 -0
  53. package/dist/container/index.d.ts +2 -0
  54. package/dist/container/index.js +1 -0
  55. package/dist/contracts/details.d.ts +13 -0
  56. package/dist/contracts/details.js +9 -0
  57. package/dist/contracts/index.d.ts +5 -0
  58. package/dist/contracts/index.js +5 -0
  59. package/dist/contracts/merge-props.d.ts +16 -0
  60. package/dist/contracts/merge-props.js +76 -0
  61. package/dist/contracts/render.d.ts +17 -0
  62. package/dist/contracts/render.js +43 -0
  63. package/dist/contracts/state.d.ts +42 -0
  64. package/dist/contracts/state.js +42 -0
  65. package/dist/css/alert.css +2 -0
  66. package/dist/css/badge.css +2 -0
  67. package/dist/css/base.css +2 -0
  68. package/dist/css/button.css +2 -0
  69. package/dist/css/card.css +2 -0
  70. package/dist/css/checkbox.css +2 -0
  71. package/dist/css/container.css +2 -0
  72. package/dist/css/delta.css +2 -0
  73. package/dist/css/dialog.css +2 -0
  74. package/dist/css/empty-state.css +2 -0
  75. package/dist/css/field.css +2 -0
  76. package/dist/css/fieldset.css +2 -0
  77. package/dist/css/grid.css +2 -0
  78. package/dist/css/heading.css +2 -0
  79. package/dist/css/icon-button.css +2 -0
  80. package/dist/css/image.css +2 -0
  81. package/dist/css/inline-error.css +2 -0
  82. package/dist/css/inline.css +2 -0
  83. package/dist/css/input.css +2 -0
  84. package/dist/css/kbd.css +2 -0
  85. package/dist/css/menu.css +2 -0
  86. package/dist/css/meter.css +2 -0
  87. package/dist/css/native-select.css +2 -0
  88. package/dist/css/progress-bar.css +2 -0
  89. package/dist/css/progress-ring.css +2 -0
  90. package/dist/css/radio-group.css +2 -0
  91. package/dist/css/segmented-control.css +2 -0
  92. package/dist/css/select.css +2 -0
  93. package/dist/css/separator.css +2 -0
  94. package/dist/css/skeleton.css +2 -0
  95. package/dist/css/stack.css +2 -0
  96. package/dist/css/switch.css +2 -0
  97. package/dist/css/tab-nav.css +2 -0
  98. package/dist/css/tabs.css +2 -0
  99. package/dist/css/text.css +2 -0
  100. package/dist/css/textarea.css +2 -0
  101. package/dist/css/tooltip.css +2 -0
  102. package/dist/delta/delta.d.ts +32 -0
  103. package/dist/delta/delta.js +50 -0
  104. package/dist/delta/index.d.ts +2 -0
  105. package/dist/delta/index.js +1 -0
  106. package/dist/dialog/dialog.client.d.ts +25 -0
  107. package/dist/dialog/dialog.client.js +167 -0
  108. package/dist/dialog/dialog.contract.d.ts +97 -0
  109. package/dist/dialog/dialog.parts.d.ts +6 -0
  110. package/dist/dialog/dialog.parts.js +15 -0
  111. package/dist/dialog/index.d.ts +5 -0
  112. package/dist/dialog/index.js +3 -0
  113. package/dist/empty-state/empty-state.d.ts +18 -0
  114. package/dist/empty-state/empty-state.js +32 -0
  115. package/dist/empty-state/index.d.ts +2 -0
  116. package/dist/empty-state/index.js +1 -0
  117. package/dist/field/field-scope.client.d.ts +50 -0
  118. package/dist/field/field-scope.client.js +205 -0
  119. package/dist/field/field-static.d.ts +122 -0
  120. package/dist/field/field-static.js +159 -0
  121. package/dist/field/field.d.ts +5 -0
  122. package/dist/field/field.js +53 -0
  123. package/dist/field/index.d.ts +4 -0
  124. package/dist/field/index.js +4 -0
  125. package/dist/fieldset/fieldset.d.ts +36 -0
  126. package/dist/fieldset/fieldset.js +63 -0
  127. package/dist/fieldset/index.d.ts +2 -0
  128. package/dist/fieldset/index.js +1 -0
  129. package/dist/grid/grid.d.ts +38 -0
  130. package/dist/grid/grid.js +28 -0
  131. package/dist/grid/index.d.ts +2 -0
  132. package/dist/grid/index.js +1 -0
  133. package/dist/heading/heading.d.ts +27 -0
  134. package/dist/heading/heading.js +26 -0
  135. package/dist/heading/index.d.ts +2 -0
  136. package/dist/heading/index.js +1 -0
  137. package/dist/icon-button/icon-button-static.d.ts +23 -0
  138. package/dist/icon-button/icon-button-static.js +83 -0
  139. package/dist/icon-button/icon-button.client.js +29 -0
  140. package/dist/icon-button/icon-button.contract.d.ts +89 -0
  141. package/dist/icon-button/icon-button.d.ts +5 -0
  142. package/dist/icon-button/icon-button.js +21 -0
  143. package/dist/icon-button/index.d.ts +4 -0
  144. package/dist/icon-button/index.js +3 -0
  145. package/dist/image/image.d.ts +28 -0
  146. package/dist/image/image.js +24 -0
  147. package/dist/image/index.d.ts +2 -0
  148. package/dist/image/index.js +1 -0
  149. package/dist/index.d.ts +95 -0
  150. package/dist/index.js +51 -0
  151. package/dist/inline/index.d.ts +2 -0
  152. package/dist/inline/index.js +1 -0
  153. package/dist/inline/inline.d.ts +16 -0
  154. package/dist/inline/inline.js +14 -0
  155. package/dist/inline-error/index.d.ts +2 -0
  156. package/dist/inline-error/index.js +1 -0
  157. package/dist/inline-error/inline-error.d.ts +17 -0
  158. package/dist/inline-error/inline-error.js +33 -0
  159. package/dist/input/index.d.ts +2 -0
  160. package/dist/input/index.js +1 -0
  161. package/dist/input/input.client.d.ts +39 -0
  162. package/dist/input/input.client.js +82 -0
  163. package/dist/kbd/index.d.ts +2 -0
  164. package/dist/kbd/index.js +1 -0
  165. package/dist/kbd/kbd.d.ts +19 -0
  166. package/dist/kbd/kbd.js +68 -0
  167. package/dist/menu/index.d.ts +5 -0
  168. package/dist/menu/index.js +3 -0
  169. package/dist/menu/menu.client.d.ts +14 -0
  170. package/dist/menu/menu.client.js +152 -0
  171. package/dist/menu/menu.contract.d.ts +152 -0
  172. package/dist/menu/menu.parts.d.ts +6 -0
  173. package/dist/menu/menu.parts.js +17 -0
  174. package/dist/meter/index.d.ts +2 -0
  175. package/dist/meter/index.js +1 -0
  176. package/dist/meter/meter.d.ts +43 -0
  177. package/dist/meter/meter.js +59 -0
  178. package/dist/native-select/index.d.ts +2 -0
  179. package/dist/native-select/index.js +1 -0
  180. package/dist/native-select/native-select.d.ts +43 -0
  181. package/dist/native-select/native-select.js +56 -0
  182. package/dist/progress-bar/index.d.ts +2 -0
  183. package/dist/progress-bar/index.js +1 -0
  184. package/dist/progress-bar/progress-bar.d.ts +34 -0
  185. package/dist/progress-bar/progress-bar.js +55 -0
  186. package/dist/progress-ring/index.d.ts +2 -0
  187. package/dist/progress-ring/index.js +1 -0
  188. package/dist/progress-ring/progress-ring.d.ts +38 -0
  189. package/dist/progress-ring/progress-ring.js +67 -0
  190. package/dist/radio-group/index.d.ts +3 -0
  191. package/dist/radio-group/index.js +3 -0
  192. package/dist/radio-group/radio-group.client.d.ts +22 -0
  193. package/dist/radio-group/radio-group.client.js +70 -0
  194. package/dist/radio-group/radio-group.d.ts +28 -0
  195. package/dist/radio-group/radio-group.js +35 -0
  196. package/dist/segmented-control/index.d.ts +3 -0
  197. package/dist/segmented-control/index.js +3 -0
  198. package/dist/segmented-control/segmented-control.client.d.ts +61 -0
  199. package/dist/segmented-control/segmented-control.client.js +156 -0
  200. package/dist/segmented-control/segmented-control.parts.d.ts +6 -0
  201. package/dist/segmented-control/segmented-control.parts.js +9 -0
  202. package/dist/select/index.d.ts +5 -0
  203. package/dist/select/index.js +3 -0
  204. package/dist/select/select.client.d.ts +12 -0
  205. package/dist/select/select.client.js +152 -0
  206. package/dist/select/select.contract.d.ts +119 -0
  207. package/dist/select/select.parts.d.ts +6 -0
  208. package/dist/select/select.parts.js +15 -0
  209. package/dist/separator/index.d.ts +2 -0
  210. package/dist/separator/index.js +1 -0
  211. package/dist/separator/separator.d.ts +26 -0
  212. package/dist/separator/separator.js +23 -0
  213. package/dist/skeleton/index.d.ts +2 -0
  214. package/dist/skeleton/index.js +1 -0
  215. package/dist/skeleton/skeleton.d.ts +20 -0
  216. package/dist/skeleton/skeleton.js +19 -0
  217. package/dist/stack/index.d.ts +2 -0
  218. package/dist/stack/index.js +1 -0
  219. package/dist/stack/stack.d.ts +17 -0
  220. package/dist/stack/stack.js +14 -0
  221. package/dist/styles.css +536 -0
  222. package/dist/switch/index.d.ts +2 -0
  223. package/dist/switch/index.js +1 -0
  224. package/dist/switch/switch.client.d.ts +33 -0
  225. package/dist/switch/switch.client.js +63 -0
  226. package/dist/tab-nav/index.d.ts +3 -0
  227. package/dist/tab-nav/index.js +3 -0
  228. package/dist/tab-nav/tab-nav.d.ts +36 -0
  229. package/dist/tab-nav/tab-nav.js +47 -0
  230. package/dist/tab-nav/tab-nav.parts.d.ts +6 -0
  231. package/dist/tab-nav/tab-nav.parts.js +9 -0
  232. package/dist/tabs/index.d.ts +4 -0
  233. package/dist/tabs/index.js +3 -0
  234. package/dist/tabs/tabs.client.d.ts +8 -0
  235. package/dist/tabs/tabs.client.js +68 -0
  236. package/dist/tabs/tabs.contract.d.ts +89 -0
  237. package/dist/tabs/tabs.parts.d.ts +6 -0
  238. package/dist/tabs/tabs.parts.js +11 -0
  239. package/dist/text/index.d.ts +2 -0
  240. package/dist/text/index.js +1 -0
  241. package/dist/text/text.d.ts +21 -0
  242. package/dist/text/text.js +17 -0
  243. package/dist/textarea/index.d.ts +2 -0
  244. package/dist/textarea/index.js +1 -0
  245. package/dist/textarea/textarea.client.d.ts +18 -0
  246. package/dist/textarea/textarea.client.js +31 -0
  247. package/dist/theme-script/index.d.ts +2 -0
  248. package/dist/theme-script/index.js +1 -0
  249. package/dist/theme-script/theme-script.d.ts +43 -0
  250. package/dist/theme-script/theme-script.js +46 -0
  251. package/dist/tooltip/index.d.ts +5 -0
  252. package/dist/tooltip/index.js +3 -0
  253. package/dist/tooltip/tooltip.client.d.ts +12 -0
  254. package/dist/tooltip/tooltip.client.js +51 -0
  255. package/dist/tooltip/tooltip.contract.d.ts +60 -0
  256. package/dist/tooltip/tooltip.parts.d.ts +6 -0
  257. package/dist/tooltip/tooltip.parts.js +10 -0
  258. package/package.json +284 -3
@@ -0,0 +1,72 @@
1
+ "use client";
2
+ import { mergeProps } from "../../contracts/merge-props.js";
3
+ import { details } from "../../contracts/details.js";
4
+ import { stateAttrs } from "../../contracts/state.js";
5
+ import { defined, engineDom } from "./dom.js";
6
+ import { EngineLocale } from "./locale.client.js";
7
+ import { popupStyle, resolveSide, toPlacement } from "./overlay.client.js";
8
+ import { use } from "react";
9
+ import { jsx } from "react/jsx-runtime";
10
+ import { Tooltip, TooltipTrigger, TooltipTriggerStateContext, useLocale } from "react-aria-components";
11
+ import { useFocusable } from "react-aria/useFocusable";
12
+ import { useObjectRef } from "react-aria/useObjectRef";
13
+ //#region src/_engines/react-aria/tooltip.client.tsx
14
+ const Root = ({ open, defaultOpen, onOpenChange, delay, disabled, children }) => /* @__PURE__ */ jsx(EngineLocale, { children: /* @__PURE__ */ jsx(TooltipTrigger, {
15
+ delay,
16
+ ...defined({
17
+ isOpen: open,
18
+ defaultOpen,
19
+ isDisabled: disabled
20
+ }),
21
+ onOpenChange: (isOpen) => onOpenChange?.(isOpen, details("unknown")),
22
+ children
23
+ }) });
24
+ /**
25
+ * The trigger is the consumer's own element (often a server `<Button>`), so it takes the engine's
26
+ * hover/focus props through `useFocusable` instead of a React Aria `Button`.
27
+ */
28
+ const Trigger = ({ render, ...dom }) => {
29
+ const ref = useObjectRef();
30
+ const { focusableProps } = useFocusable({}, ref);
31
+ const s = { open: use(TooltipTriggerStateContext)?.isOpen ?? false };
32
+ return render(mergeProps(engineDom(focusableProps), { ref }, dom, stateAttrs(s)), s);
33
+ };
34
+ /**
35
+ * React Aria 1.22.1 closes a tooltip "instantly" (no exit animation) when another one opens during
36
+ * the warm-up period, as Tab moves across tooltip triggers. Its exit state is then left "exiting"
37
+ * with no element to animate, so the next ordinary close of that tooltip (a press on its trigger,
38
+ * after the keyboard, with no pointer move that would reopen it first) mounts an unpositioned popup
39
+ * in `data-exiting` that never leaves. Keying the engine's Tooltip on that instant close remounts it
40
+ * with a fresh exit state; it renders nothing in either state, so nothing visible remounts.
41
+ */
42
+ function instantlyClosed(state) {
43
+ return state !== null && !state.isOpen && state.shouldSkipAnimation === true;
44
+ }
45
+ const Popup = ({ side, align, sideOffset, container, render, children, ...dom }) => {
46
+ const { direction } = useLocale();
47
+ return /* @__PURE__ */ jsx(Tooltip, {
48
+ placement: toPlacement(side, align),
49
+ offset: sideOffset,
50
+ ...defined({ UNSTABLE_portalContainer: container ?? void 0 }),
51
+ render: (p, rp) => {
52
+ const s = {
53
+ entering: rp.isEntering,
54
+ exiting: rp.isExiting,
55
+ side: resolveSide(rp.placement, side, direction)
56
+ };
57
+ const engine = {
58
+ ...engineDom(p),
59
+ style: popupStyle(p.style)
60
+ };
61
+ const attrs = stateAttrs({
62
+ open: rp.state.isOpen,
63
+ ...s,
64
+ align
65
+ });
66
+ return render(mergeProps(engine, dom, attrs), s);
67
+ },
68
+ children
69
+ }, instantlyClosed(use(TooltipTriggerStateContext)) ? "instant" : "live");
70
+ };
71
+ //#endregion
72
+ export { Popup, Root, Trigger };
@@ -0,0 +1,11 @@
1
+ //#region src/_internal/cx.ts
2
+ /** Joins class names, skipping empty values and repeated classes. Never exported from the package. */
3
+ function cx(...parts) {
4
+ const classes = /* @__PURE__ */ new Set();
5
+ for (const part of parts) if (part) {
6
+ for (const name of part.split(/\s+/)) if (name !== "") classes.add(name);
7
+ }
8
+ return [...classes].join(" ");
9
+ }
10
+ //#endregion
11
+ export { cx };
@@ -0,0 +1 @@
1
+ import { ComponentPropsWithRef, JSX, ReactElement, ReactNode } from "react";
@@ -0,0 +1,20 @@
1
+ //#region src/_internal/field.ts
2
+ /**
3
+ * Whether a message node renders something. `null`, `undefined`, booleans and `''` render nothing,
4
+ * so `error={failed && 'Enter a price'}` presents no error when `failed` is false.
5
+ */
6
+ function presented(node) {
7
+ return node != null && typeof node !== "boolean" && node !== "";
8
+ }
9
+ /** Joins id references for `aria-describedby`, skipping empty ones; `undefined` when none remain. */
10
+ function joinIds(...ids) {
11
+ const joined = ids.filter((id) => typeof id === "string" && id !== "").join(" ");
12
+ return joined === "" ? void 0 : joined;
13
+ }
14
+ /**
15
+ * Marks a server-safe control (NativeSelect) that Field wires as plain props when it is placed
16
+ * directly inside, as if it were a function child: zero JS, and the label still points at it.
17
+ */
18
+ const FIELD_CONTROL = Symbol.for("nizivo.field-control");
19
+ //#endregion
20
+ export { FIELD_CONTROL, joinIds, presented };
@@ -0,0 +1,34 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ //#region src/_internal/glyphs.tsx
3
+ function svg(name, paths) {
4
+ return /* @__PURE__ */ jsx("svg", {
5
+ className: `nz-glyph nz-glyph-${name}`,
6
+ viewBox: "0 0 24 24",
7
+ width: "1em",
8
+ height: "1em",
9
+ fill: "none",
10
+ stroke: "currentColor",
11
+ strokeWidth: 1.92,
12
+ strokeLinecap: "round",
13
+ strokeLinejoin: "round",
14
+ "aria-hidden": "true",
15
+ focusable: "false",
16
+ children: paths
17
+ });
18
+ }
19
+ const SpinnerGlyph = () => svg("spinner", /* @__PURE__ */ jsx("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" }));
20
+ const ChevronsUpDownGlyph = () => svg("chevrons-up-down", /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("path", { d: "m7 15 5 5 5-5" }), /* @__PURE__ */ jsx("path", { d: "m7 9 5-5 5 5" })] }));
21
+ const CircleXGlyph = () => svg("circle-x", /* @__PURE__ */ jsxs(Fragment, { children: [
22
+ /* @__PURE__ */ jsx("circle", {
23
+ cx: "12",
24
+ cy: "12",
25
+ r: "10"
26
+ }),
27
+ /* @__PURE__ */ jsx("path", { d: "m15 9-6 6" }),
28
+ /* @__PURE__ */ jsx("path", { d: "m9 9 6 6" })
29
+ ] }));
30
+ const CloseGlyph = () => svg("close", /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("path", { d: "M18 6 6 18" }), /* @__PURE__ */ jsx("path", { d: "m6 6 12 12" })] }));
31
+ const CheckGlyph = () => svg("check", /* @__PURE__ */ jsx("path", { d: "M20 6 9 17l-5-5" }));
32
+ const MinusGlyph = () => svg("minus", /* @__PURE__ */ jsx("path", { d: "M5 12h14" }));
33
+ //#endregion
34
+ export { CheckGlyph, ChevronsUpDownGlyph, CircleXGlyph, CloseGlyph, MinusGlyph, SpinnerGlyph };
@@ -0,0 +1,62 @@
1
+ //#region src/_internal/keys.ts
2
+ /**
3
+ * `"mod+shift+d"` → `["mod", "shift", "d"]`. The plus key is `plus`, or a `+` where a key is due:
4
+ * `"mod++"` and `"mod+plus"` are both ⌘ and +.
5
+ */
6
+ function splitKeys(keys) {
7
+ const parts = keys.split("+").map((part) => part.trim());
8
+ const out = [];
9
+ for (let index = 0; index < parts.length; index += 1) {
10
+ const part = parts[index] ?? "";
11
+ if (part !== "") out.push(part);
12
+ else if (parts[index + 1] === "") {
13
+ out.push("+");
14
+ index += 1;
15
+ }
16
+ }
17
+ return out;
18
+ }
19
+ /** Key name → its `aria-keyshortcuts` name (WAI-ARIA 1.2, UI Events `key` values). */
20
+ const ARIA = {
21
+ cmd: "Meta",
22
+ command: "Meta",
23
+ meta: "Meta",
24
+ ctrl: "Control",
25
+ control: "Control",
26
+ alt: "Alt",
27
+ option: "Alt",
28
+ shift: "Shift",
29
+ enter: "Enter",
30
+ return: "Enter",
31
+ esc: "Escape",
32
+ escape: "Escape",
33
+ tab: "Tab",
34
+ backspace: "Backspace",
35
+ delete: "Delete",
36
+ space: "Space",
37
+ plus: "Plus",
38
+ "+": "Plus",
39
+ up: "ArrowUp",
40
+ down: "ArrowDown",
41
+ left: "ArrowLeft",
42
+ right: "ArrowRight"
43
+ };
44
+ /** One key's `aria-keyshortcuts` name; `mod` is the platform's command key, given by the caller. */
45
+ function ariaName(key, mod) {
46
+ const lower = key.toLowerCase();
47
+ if (lower === "mod") return mod;
48
+ return ARIA[lower] ?? (key.length === 1 ? key.toUpperCase() : key);
49
+ }
50
+ /**
51
+ * `"mod+b"` → `"Meta+B Control+B"`. The server does not know the platform, so `mod` lists both
52
+ * alternatives (space-separated, as the attribute allows); one letter is uppercased.
53
+ */
54
+ function ariaKeyShortcuts(keys) {
55
+ const parts = splitKeys(keys);
56
+ if (parts.length === 0) return void 0;
57
+ const apple = parts.map((key) => ariaName(key, "Meta")).join("+");
58
+ const other = parts.map((key) => ariaName(key, "Control")).join("+");
59
+ return apple === other ? apple : `${apple} ${other}`;
60
+ }
61
+ //#endregion
62
+ export { ariaKeyShortcuts, splitKeys };
@@ -0,0 +1,9 @@
1
+ import { CSSProperties, ReactElement, ReactNode, RefObject } from "react";
2
+ //#region src/_internal/overlay.d.ts
3
+ /**
4
+ * Where focus goes when an overlay closes (§12.2 Focus return): `true` follows the chain (the
5
+ * trigger, else the parent overlay's trigger), an element ref or a function returning an element
6
+ * goes there first while it is on the page, and `false` leaves focus alone.
7
+ */
8
+ export type ReturnFocusTarget = boolean | RefObject<HTMLElement | null> | (() => HTMLElement | null | undefined);
9
+ //#endregion
@@ -0,0 +1,13 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __defProp = Object.defineProperty;
3
+ var __exportAll = (all, no_symbols) => {
4
+ let target = {};
5
+ for (var name in all) __defProp(target, name, {
6
+ get: all[name],
7
+ enumerable: true
8
+ });
9
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
10
+ return target;
11
+ };
12
+ //#endregion
13
+ export { __exportAll };
@@ -0,0 +1,32 @@
1
+ import { RenderProp } from "../contracts/render.js";
2
+ import { ComponentPropsWithRef, ReactElement, ReactNode } from "react";
3
+ //#region src/alert/alert-dismiss.client.d.ts
4
+ /** Strings this part renders (§16.4). */
5
+ export interface AlertDismissLabels {
6
+ /** The button's accessible name. @default 'Dismiss' */
7
+ dismiss: string;
8
+ }
9
+ export interface AlertDismissProps extends Omit<ComponentPropsWithRef<"button">, "children"> {
10
+ /**
11
+ * Called with no arguments, so a Server Component can pass a Server Action. The Alert does not hide
12
+ * itself: the caller stops rendering it.
13
+ */
14
+ onDismiss?: () => void;
15
+ labels?: Partial<AlertDismissLabels>;
16
+ /** The close glyph, decorative. Defaults to the internal `close` glyph (Lucide's `x`). */
17
+ children?: ReactNode;
18
+ /**
19
+ * Your element in place of the default IconButton; it must render a `<button>`. A plain element
20
+ * keeps its own look. An IconButton, for example
21
+ * `render={<IconButton icon={<X />} label="Dismiss" variant="tertiary" size="sm" />}` to add its
22
+ * tooltip, keeps its variant and size, and in an Alert takes the dismiss slot's placement (made for
23
+ * `sm`) and icon/secondary glyph colour, as a composed IconButton does in `Dialog.Close`.
24
+ */
25
+ render?: RenderProp<Record<string, never>>;
26
+ }
27
+ /**
28
+ * With no `render`, an IconButton (tertiary, `sm`: the 16 px glyph Figma draws, in a 32 px target)
29
+ * with no tooltip, as `Dialog.Close` does.
30
+ */
31
+ export declare function AlertDismiss({ onDismiss, labels, "aria-label": ariaLabel, type, render, className, onClick, children, ...rest }: AlertDismissProps): ReactElement;
32
+ //#endregion
@@ -0,0 +1,36 @@
1
+ "use client";
2
+ import { cx } from "../_internal/cx.js";
3
+ import { renderElement } from "../contracts/render.js";
4
+ import { CloseGlyph } from "../_internal/glyphs.js";
5
+ import { jsx } from "react/jsx-runtime";
6
+ //#region src/alert/alert-dismiss.client.tsx
7
+ /**
8
+ * With no `render`, an IconButton (tertiary, `sm`: the 16 px glyph Figma draws, in a 32 px target)
9
+ * with no tooltip, as `Dialog.Close` does.
10
+ */
11
+ function AlertDismiss({ onDismiss, labels, "aria-label": ariaLabel, type, render, className, onClick, children, ...rest }) {
12
+ const own = render === void 0;
13
+ return renderElement("button", render, {}, {
14
+ "data-slot": "alert-dismiss",
15
+ ...own && {
16
+ "data-variant": "tertiary",
17
+ "data-size": "sm"
18
+ },
19
+ ...rest,
20
+ type: own ? type ?? "button" : void 0,
21
+ "aria-label": ariaLabel ?? labels?.dismiss ?? "Dismiss",
22
+ className: cx("nz-alert-dismiss", own && "nz-icon-button", "nz-hit-target", className),
23
+ onClick: (event) => {
24
+ onClick?.(event);
25
+ if (!event.defaultPrevented) onDismiss?.();
26
+ },
27
+ children: /* @__PURE__ */ jsx("span", {
28
+ className: "nz-icon-button-icon",
29
+ "data-slot": "icon-button-icon",
30
+ "aria-hidden": "true",
31
+ children: children ?? /* @__PURE__ */ jsx(CloseGlyph, {})
32
+ })
33
+ });
34
+ }
35
+ //#endregion
36
+ export { AlertDismiss };
@@ -0,0 +1,28 @@
1
+ import { RenderProp } from "../contracts/render.js";
2
+ import { ComponentPropsWithRef, ReactElement, ReactNode } from "react";
3
+ //#region src/alert/alert.d.ts
4
+ /** Figma "Tone". */
5
+ export type AlertTone = "info" | "success" | "warning" | "critical";
6
+ export interface AlertState {
7
+ tone: AlertTone;
8
+ }
9
+ export interface AlertProps extends Omit<ComponentPropsWithRef<"div">, "title"> {
10
+ /** @default 'info' */
11
+ tone?: AlertTone;
12
+ /** One line, Label/M Strong. The description is `children`. */
13
+ title?: ReactNode;
14
+ /** Decorative tone glyph, for example `<CircleX />` for `critical`; the text carries the meaning. */
15
+ icon?: ReactNode;
16
+ /** Controls under the text, for example `<Button size="sm">Retry</Button>`. */
17
+ action?: ReactNode;
18
+ /** `<AlertDismiss onDismiss={…}>…</AlertDismiss>`; leave it out for an alert that cannot be dismissed. */
19
+ dismiss?: ReactNode;
20
+ /**
21
+ * There is no live role by default: an alert present on page load must not interrupt. Pass
22
+ * `role="status"` or `role="alert"` for one injected after a user action.
23
+ */
24
+ role?: ComponentPropsWithRef<"div">["role"];
25
+ render?: RenderProp<AlertState>;
26
+ }
27
+ export declare function Alert({ tone, title, icon, action, dismiss, render, className, children, ...rest }: AlertProps): ReactElement;
28
+ //#endregion
@@ -0,0 +1,44 @@
1
+ import { cx } from "../_internal/cx.js";
2
+ import { renderElement } from "../contracts/render.js";
3
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
+ //#region src/alert/alert.tsx
5
+ function Alert({ tone = "info", title, icon, action, dismiss, render, className, children, ...rest }) {
6
+ return renderElement("div", render, { tone }, {
7
+ "data-slot": "alert",
8
+ "data-tone": tone,
9
+ ...rest,
10
+ className: cx("nz-alert", className),
11
+ children: /* @__PURE__ */ jsxs(Fragment, { children: [
12
+ icon != null && /* @__PURE__ */ jsx("span", {
13
+ className: "nz-alert-icon",
14
+ "data-slot": "alert-icon",
15
+ "aria-hidden": "true",
16
+ children: icon
17
+ }),
18
+ /* @__PURE__ */ jsxs("div", {
19
+ className: "nz-alert-content",
20
+ "data-slot": "alert-content",
21
+ children: [
22
+ title != null && /* @__PURE__ */ jsx("div", {
23
+ className: "nz-alert-title",
24
+ "data-slot": "alert-title",
25
+ children: title
26
+ }),
27
+ children != null && children !== false && children !== "" && /* @__PURE__ */ jsx("div", {
28
+ className: "nz-alert-description",
29
+ "data-slot": "alert-description",
30
+ children
31
+ }),
32
+ action != null && /* @__PURE__ */ jsx("div", {
33
+ className: "nz-alert-action",
34
+ "data-slot": "alert-action",
35
+ children: action
36
+ })
37
+ ]
38
+ }),
39
+ dismiss
40
+ ] })
41
+ });
42
+ }
43
+ //#endregion
44
+ export { Alert };
@@ -0,0 +1,3 @@
1
+ import { Alert, AlertProps, AlertState, AlertTone } from "./alert.js";
2
+ import { AlertDismiss, AlertDismissLabels, AlertDismissProps } from "./alert-dismiss.client.js";
3
+ export { Alert, AlertDismiss, type AlertDismissLabels, type AlertDismissProps, type AlertProps, type AlertState, type AlertTone };
@@ -0,0 +1,3 @@
1
+ import { Alert } from "./alert.js";
2
+ import { AlertDismiss } from "./alert-dismiss.client.js";
3
+ export { Alert, AlertDismiss };
@@ -0,0 +1,13 @@
1
+ //#region src/augment.d.ts
2
+ /** Button variants, as lowercase Figma names. Augment this interface to add one. */
3
+ export interface ButtonVariantMap {
4
+ primary: true;
5
+ secondary: true;
6
+ tertiary: true;
7
+ critical: true;
8
+ accent: true;
9
+ }
10
+ export type ButtonVariant = keyof ButtonVariantMap;
11
+ /** Control heights 32 / 40 / 48 px. */
12
+ export type ControlSize = "sm" | "md" | "lg";
13
+ //#endregion
File without changes
@@ -0,0 +1,19 @@
1
+ import { RenderProp } from "../contracts/render.js";
2
+ import { ComponentPropsWithRef, ReactElement } from "react";
3
+ //#region src/badge/badge.d.ts
4
+ /** Figma "Tone". `brand` is the only solid fill. */
5
+ export type BadgeTone = "neutral" | "success" | "warning" | "critical" | "info" | "brand";
6
+ export interface BadgeState {
7
+ tone: BadgeTone;
8
+ dot: boolean;
9
+ }
10
+ export interface BadgeProps extends ComponentPropsWithRef<"span"> {
11
+ /** @default 'neutral' */
12
+ tone?: BadgeTone;
13
+ /** Figma "Dot": a decorative status dot before the label. The label carries the meaning. @default true */
14
+ dot?: boolean;
15
+ /** Composition, for example `render={<a href="/orders?status=paid" />}`. */
16
+ render?: RenderProp<BadgeState>;
17
+ }
18
+ export declare function Badge({ tone, dot, render, className, children, ...rest }: BadgeProps): ReactElement;
19
+ //#endregion
@@ -0,0 +1,22 @@
1
+ import { cx } from "../_internal/cx.js";
2
+ import { renderElement } from "../contracts/render.js";
3
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
+ //#region src/badge/badge.tsx
5
+ function Badge({ tone = "neutral", dot = true, render, className, children, ...rest }) {
6
+ return renderElement("span", render, {
7
+ tone,
8
+ dot
9
+ }, {
10
+ "data-slot": "badge",
11
+ "data-tone": tone,
12
+ ...rest,
13
+ className: cx("nz-badge", className),
14
+ children: /* @__PURE__ */ jsxs(Fragment, { children: [dot && /* @__PURE__ */ jsx("span", {
15
+ className: "nz-badge-dot",
16
+ "data-slot": "badge-dot",
17
+ "aria-hidden": "true"
18
+ }), children] })
19
+ });
20
+ }
21
+ //#endregion
22
+ export { Badge };
@@ -0,0 +1,2 @@
1
+ import { Badge, BadgeProps, BadgeState, BadgeTone } from "./badge.js";
2
+ export { Badge, type BadgeProps, type BadgeState, type BadgeTone };
@@ -0,0 +1 @@
1
+ export { Badge } from "./badge.js";
@@ -0,0 +1,54 @@
1
+ import { RenderProp } from "../contracts/render.js";
2
+ import { ButtonVariant, ControlSize } from "../augment.js";
3
+ import { ComponentPropsWithRef, ReactElement, ReactNode } from "react";
4
+ //#region src/button/button.d.ts
5
+ export interface ButtonState {
6
+ variant: ButtonVariant;
7
+ size: ControlSize;
8
+ pending: boolean;
9
+ disabled: boolean;
10
+ }
11
+ /** Button's own strings (§16.4): serialisable, English defaults. */
12
+ export interface ButtonLabels {
13
+ /**
14
+ * The text a pending button shows in place of its label under Reduced motion, where the spinner stops
15
+ * (Figma: "Spinner and skeleton loops stop; a text label shows").
16
+ * @default 'Loading…'
17
+ */
18
+ pending: string;
19
+ }
20
+ export interface ButtonProps extends Omit<ComponentPropsWithRef<"button">, "children"> {
21
+ /**
22
+ * Figma "Variant". One primary per view; secondary for everything else; tertiary inside dense rows.
23
+ * @default 'secondary'
24
+ */
25
+ variant?: ButtonVariant;
26
+ /** 32 / 40 / 48 px. @default 'md' */
27
+ size?: ControlSize;
28
+ leadingIcon?: ReactNode;
29
+ trailingIcon?: ReactNode;
30
+ /**
31
+ * An action is in flight: the spinner replaces the leading icon, the label stays, and the button
32
+ * stays focusable with `aria-disabled` and swallows clicks. The spinner turns once per
33
+ * `--nz-duration-spin`; under Reduced motion it stops and `labels.pending` ("Loading…") shows in
34
+ * the label's place, in a button that keeps its width. The label stays in the accessible name,
35
+ * after that text ("Loading… Publish").
36
+ * @default false
37
+ */
38
+ pending?: boolean;
39
+ /** Replaces the internal spinner glyph. */
40
+ pendingIndicator?: ReactNode;
41
+ /** Fills the width of its container. @default false */
42
+ fullWidth?: boolean;
43
+ /** Composition, for example `render={<Link href="/orders" />}`. */
44
+ render?: RenderProp<ButtonState>;
45
+ /**
46
+ * Overrides Button's strings, for example `labels={{ pending: 'Wird geladen…' }}`; `pending: ''`
47
+ * shows no text and keeps the label visible. Translation is per instance (no global labels in 0.1.0): an app wraps Button once to
48
+ * pass its own.
49
+ */
50
+ labels?: Partial<ButtonLabels>;
51
+ children?: ReactNode;
52
+ }
53
+ export declare function Button({ variant, size, leadingIcon, trailingIcon, pending, pendingIndicator, fullWidth, disabled, type, render, className, onClick, labels, children, ...rest }: ButtonProps): ReactElement;
54
+ //#endregion
@@ -0,0 +1,62 @@
1
+ import { cx } from "../_internal/cx.js";
2
+ import { renderElement } from "../contracts/render.js";
3
+ import { SpinnerGlyph } from "../_internal/glyphs.js";
4
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
+ //#region src/button/button.tsx
6
+ function Button({ variant = "secondary", size = "md", leadingIcon, trailingIcon, pending = false, pendingIndicator, fullWidth = false, disabled = false, type, render, className, onClick, labels, children, ...rest }) {
7
+ const native = render === void 0;
8
+ const empty = children == null && leadingIcon == null && trailingIcon == null && !pending;
9
+ return renderElement("button", render, {
10
+ variant,
11
+ size,
12
+ pending,
13
+ disabled
14
+ }, {
15
+ "data-slot": "button",
16
+ "data-variant": variant,
17
+ "data-size": size,
18
+ "data-pending": pending ? "" : void 0,
19
+ "data-disabled": disabled ? "" : void 0,
20
+ "data-full-width": fullWidth ? "" : void 0,
21
+ ...rest,
22
+ className: cx("nz-button nz-hit-target", className),
23
+ type: native ? pending ? "button" : type ?? "button" : void 0,
24
+ disabled: native && disabled && !pending ? true : void 0,
25
+ "aria-disabled": pending || !native && disabled ? true : void 0,
26
+ onClick: pending && onClick ? swallow : onClick,
27
+ children: empty ? void 0 : /* @__PURE__ */ jsxs(Fragment, { children: [
28
+ pending ? /* @__PURE__ */ jsx("span", {
29
+ className: "nz-button-icon",
30
+ "data-slot": "button-icon",
31
+ "aria-hidden": "true",
32
+ children: pendingIndicator ?? /* @__PURE__ */ jsx(SpinnerGlyph, {})
33
+ }) : leadingIcon != null && /* @__PURE__ */ jsx("span", {
34
+ className: "nz-button-icon",
35
+ "data-slot": "button-icon",
36
+ "aria-hidden": "true",
37
+ children: leadingIcon
38
+ }),
39
+ pending && labels?.pending !== "" && /* @__PURE__ */ jsx("span", {
40
+ className: "nz-button-pending-label",
41
+ "data-slot": "button-pending-label",
42
+ children: labels?.pending ?? "Loading…"
43
+ }),
44
+ /* @__PURE__ */ jsx("span", {
45
+ className: "nz-button-label",
46
+ "data-slot": "button-label",
47
+ children
48
+ }),
49
+ trailingIcon != null && /* @__PURE__ */ jsx("span", {
50
+ className: "nz-button-icon",
51
+ "data-slot": "button-icon",
52
+ "aria-hidden": "true",
53
+ children: trailingIcon
54
+ })
55
+ ] })
56
+ });
57
+ }
58
+ function swallow(event) {
59
+ event.preventDefault();
60
+ }
61
+ //#endregion
62
+ export { Button };
@@ -0,0 +1,2 @@
1
+ import { Button, ButtonLabels, ButtonProps, ButtonState } from "./button.js";
2
+ export { Button, type ButtonLabels, type ButtonProps, type ButtonState };
@@ -0,0 +1 @@
1
+ export { Button } from "./button.js";
@@ -0,0 +1,57 @@
1
+ import { RenderProp } from "../contracts/render.js";
2
+ import { ComponentPropsWithRef, ReactElement } from "react";
3
+ //#region src/card/card.d.ts
4
+ /** Figma "Style": Surface | Subtle | Inverse. */
5
+ export type CardTone = "surface" | "subtle" | "inverse";
6
+ export type CardTitleLevel = 2 | 3 | 4 | 5 | 6;
7
+ /** 24 px (`md`, Figma) or 20 px (`sm`). */
8
+ export type CardPadding = "sm" | "md";
9
+ /** 0 draws no shadow (the rest elevation); 1 draws `--nz-elevation-1`. */
10
+ export type CardElevation = 0 | 1;
11
+ export interface CardRootState {
12
+ tone: CardTone;
13
+ padding: CardPadding;
14
+ elevation: CardElevation;
15
+ }
16
+ export interface CardRootProps extends ComponentPropsWithRef<"div"> {
17
+ /**
18
+ * `inverse` sets `data-nz-scheme="inverse"`, so every token inside resolves in the inverse scheme.
19
+ * @default 'surface'
20
+ */
21
+ tone?: CardTone;
22
+ /** @default 'md' */
23
+ padding?: CardPadding;
24
+ /** No shadow at rest until design says otherwise (decision 8j). @default 0 */
25
+ elevation?: CardElevation;
26
+ render?: RenderProp<CardRootState>;
27
+ }
28
+ export interface CardHeaderProps extends ComponentPropsWithRef<"div"> {
29
+ render?: RenderProp<Record<string, never>>;
30
+ }
31
+ export interface CardTitleProps extends ComponentPropsWithRef<"h3"> {
32
+ /** The heading level; its look is Heading/H4 at every level. @default 3 */
33
+ level?: CardTitleLevel;
34
+ render?: RenderProp<Record<string, never>>;
35
+ }
36
+ export interface CardDescriptionProps extends ComponentPropsWithRef<"p"> {
37
+ render?: RenderProp<Record<string, never>>;
38
+ }
39
+ /** Figma "Show action": the control at the end of the header, for example an IconButton. */
40
+ export interface CardActionProps extends ComponentPropsWithRef<"div"> {
41
+ render?: RenderProp<Record<string, never>>;
42
+ }
43
+ /** Figma's "Slot" frame. */
44
+ export interface CardBodyProps extends ComponentPropsWithRef<"div"> {
45
+ render?: RenderProp<Record<string, never>>;
46
+ }
47
+ export interface CardFooterProps extends ComponentPropsWithRef<"div"> {
48
+ render?: RenderProp<Record<string, never>>;
49
+ }
50
+ export declare function CardRoot({ tone, padding, elevation, render, className, ...rest }: CardRootProps): ReactElement;
51
+ export declare function CardHeader({ render, className, ...rest }: CardHeaderProps): ReactElement;
52
+ export declare function CardTitle({ level, render, className, ...rest }: CardTitleProps): ReactElement;
53
+ export declare function CardDescription({ render, className, ...rest }: CardDescriptionProps): ReactElement;
54
+ export declare function CardAction({ render, className, ...rest }: CardActionProps): ReactElement;
55
+ export declare function CardBody({ render, className, ...rest }: CardBodyProps): ReactElement;
56
+ export declare function CardFooter({ render, className, ...rest }: CardFooterProps): ReactElement;
57
+ //#endregion