@nsaa/core 0.1.0-alpha.1 → 0.1.0-alpha.2

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 (236) hide show
  1. package/dist/accordion/accordion.d.ts +7 -0
  2. package/dist/accordion/accordion.js +54 -0
  3. package/dist/accordion/index.d.ts +3 -0
  4. package/dist/alert/alert.d.ts +18 -0
  5. package/dist/alert/alert.js +53 -0
  6. package/dist/alert/index.d.ts +3 -0
  7. package/dist/alert-dialog/alert-dialog.d.ts +19 -0
  8. package/dist/alert-dialog/alert-dialog.js +100 -0
  9. package/dist/alert-dialog/index.d.ts +3 -0
  10. package/dist/avatar/avatar.d.ts +12 -0
  11. package/dist/avatar/avatar.js +50 -0
  12. package/dist/avatar/index.d.ts +3 -0
  13. package/dist/badge/badge.d.ts +8 -0
  14. package/dist/badge/badge.js +29 -0
  15. package/dist/badge/index.d.ts +3 -0
  16. package/dist/button/button.d.ts +25 -0
  17. package/dist/button/button.js +136 -0
  18. package/dist/button/index.d.ts +3 -0
  19. package/dist/calendar/calendar.d.ts +11 -0
  20. package/dist/calendar/calendar.js +131 -0
  21. package/dist/calendar/index.d.ts +3 -0
  22. package/dist/card/card.d.ts +12 -0
  23. package/dist/card/card.js +55 -0
  24. package/dist/card/index.d.ts +3 -0
  25. package/dist/checkbox/checkbox.d.ts +4 -0
  26. package/dist/checkbox/checkbox.js +35 -0
  27. package/dist/checkbox/index.d.ts +3 -0
  28. package/dist/collapsible/collapsible.d.ts +6 -0
  29. package/dist/collapsible/collapsible.js +24 -0
  30. package/dist/collapsible/index.d.ts +3 -0
  31. package/dist/combobox/combobox.d.ts +27 -0
  32. package/dist/combobox/combobox.js +226 -0
  33. package/dist/combobox/index.d.ts +3 -0
  34. package/dist/command/command.d.ts +20 -0
  35. package/dist/command/command.js +116 -0
  36. package/dist/command/index.d.ts +3 -0
  37. package/dist/context-menu/context-menu.d.ts +30 -0
  38. package/dist/context-menu/context-menu.js +173 -0
  39. package/dist/context-menu/index.d.ts +3 -0
  40. package/dist/dialog/dialog.d.ts +18 -0
  41. package/dist/dialog/dialog.js +106 -0
  42. package/dist/dialog/index.d.ts +3 -0
  43. package/dist/direction.d.ts +3 -0
  44. package/dist/direction.js +2 -0
  45. package/dist/drawer/drawer.d.ts +17 -0
  46. package/dist/drawer/drawer.js +136 -0
  47. package/dist/drawer/index.d.ts +3 -0
  48. package/dist/dropdown-menu/dropdown-menu.d.ts +30 -0
  49. package/dist/dropdown-menu/dropdown-menu.js +177 -0
  50. package/dist/dropdown-menu/index.d.ts +3 -0
  51. package/dist/empty/empty.d.ts +35 -0
  52. package/dist/empty/empty.js +93 -0
  53. package/dist/empty/index.d.ts +3 -0
  54. package/dist/field/field.d.ts +26 -0
  55. package/dist/field/field.js +109 -0
  56. package/dist/field/index.d.ts +3 -0
  57. package/dist/index.d.ts +89 -674
  58. package/dist/index.js +48 -3876
  59. package/dist/input/index.d.ts +3 -0
  60. package/dist/input/input.d.ts +4 -0
  61. package/dist/input/input.js +14 -0
  62. package/dist/input-group/index.d.ts +3 -0
  63. package/dist/input-group/input-group.d.ts +19 -0
  64. package/dist/input-group/input-group.js +78 -0
  65. package/dist/input-otp/index.d.ts +3 -0
  66. package/dist/input-otp/input-otp.d.ts +12 -0
  67. package/dist/input-otp/input-otp.js +73 -0
  68. package/dist/kbd/index.d.ts +3 -0
  69. package/dist/kbd/kbd.d.ts +5 -0
  70. package/dist/kbd/kbd.js +19 -0
  71. package/dist/label/index.d.ts +3 -0
  72. package/dist/label/label.d.ts +4 -0
  73. package/dist/label/label.js +13 -0
  74. package/dist/legacy/icon-button/icon-swap.js +58 -0
  75. package/dist/lib/cn.d.ts +3 -0
  76. package/dist/{cn-DxFBFdwT.js → lib/cn.js} +1 -1
  77. package/dist/lib/control-defaults.js +8 -0
  78. package/dist/lib/icon-swap.d.ts +15 -0
  79. package/dist/lib/icon-swap.js +26 -0
  80. package/dist/lib/input-modality.js +39 -0
  81. package/dist/lib/merge-refs.js +21 -0
  82. package/dist/lib/shortcut.js +50 -0
  83. package/dist/lib/track-input-modality.d.ts +2 -0
  84. package/dist/lib/track-input-modality.js +4 -0
  85. package/dist/lib/tv.js +7 -0
  86. package/dist/lib/use-press.js +48 -0
  87. package/dist/lib/user-action.js +13 -0
  88. package/dist/loaders/arc.d.ts +6 -0
  89. package/dist/loaders/arc.js +31 -0
  90. package/dist/loaders/atom.d.ts +5 -0
  91. package/dist/loaders/atom.js +70 -0
  92. package/dist/loaders/blocks.d.ts +8 -0
  93. package/dist/loaders/blocks.js +74 -0
  94. package/dist/loaders/bouncing-dots.d.ts +3 -0
  95. package/dist/loaders/bouncing-dots.js +45 -0
  96. package/dist/loaders/cap.d.ts +6 -0
  97. package/dist/loaders/cap.js +7 -0
  98. package/dist/loaders/cascade.d.ts +5 -0
  99. package/dist/loaders/cascade.js +50 -0
  100. package/dist/loaders/circular-dots.d.ts +3 -0
  101. package/dist/loaders/circular-dots.js +40 -0
  102. package/dist/loaders/classic-v2.d.ts +3 -0
  103. package/dist/loaders/classic-v2.js +41 -0
  104. package/dist/loaders/classic.d.ts +3 -0
  105. package/dist/loaders/classic.js +48 -0
  106. package/dist/loaders/clock.d.ts +5 -0
  107. package/dist/loaders/clock.js +31 -0
  108. package/dist/loaders/comet.d.ts +5 -0
  109. package/dist/loaders/comet.js +52 -0
  110. package/dist/loaders/compass.d.ts +3 -0
  111. package/dist/loaders/compass.js +39 -0
  112. package/dist/loaders/dual.d.ts +6 -0
  113. package/dist/loaders/dual.js +47 -0
  114. package/dist/loaders/easing.d.ts +6 -0
  115. package/dist/loaders/easing.js +34 -0
  116. package/dist/loaders/eclipse.d.ts +3 -0
  117. package/dist/loaders/eclipse.js +69 -0
  118. package/dist/loaders/fade.js +28 -0
  119. package/dist/loaders/flip.d.ts +3 -0
  120. package/dist/loaders/flip.js +41 -0
  121. package/dist/{frame-CK9IBOZB.js → loaders/frame.js} +2 -50
  122. package/dist/loaders/gather.d.ts +3 -0
  123. package/dist/loaders/gather.js +85 -0
  124. package/dist/loaders/leap.d.ts +3 -0
  125. package/dist/loaders/leap.js +67 -0
  126. package/dist/loaders/linear-dots.d.ts +3 -0
  127. package/dist/loaders/linear-dots.js +54 -0
  128. package/dist/loaders/loading.d.ts +3 -0
  129. package/dist/loaders/loading.js +64 -0
  130. package/dist/loaders/morph.d.ts +3 -0
  131. package/dist/loaders/morph.js +40 -0
  132. package/dist/loaders/motion.d.ts +35 -0
  133. package/dist/loaders/motion.js +51 -0
  134. package/dist/loaders/orbit.d.ts +5 -0
  135. package/dist/loaders/orbit.js +44 -0
  136. package/dist/loaders/pulse.d.ts +3 -0
  137. package/dist/loaders/pulse.js +52 -0
  138. package/dist/loaders/radar.d.ts +5 -0
  139. package/dist/loaders/radar.js +64 -0
  140. package/dist/loaders/ring.d.ts +6 -0
  141. package/dist/loaders/ring.js +38 -0
  142. package/dist/loaders/ripple.d.ts +8 -0
  143. package/dist/loaders/ripple.js +57 -0
  144. package/dist/loaders/slide.d.ts +3 -0
  145. package/dist/loaders/slide.js +74 -0
  146. package/dist/loaders/snake.d.ts +6 -0
  147. package/dist/loaders/snake.js +59 -0
  148. package/dist/loaders/spinners.d.ts +61 -0
  149. package/dist/loaders/spinners.js +63 -0
  150. package/dist/loaders/swirl.d.ts +3 -0
  151. package/dist/loaders/swirl.js +50 -0
  152. package/dist/loaders/text/shared.js +25 -0
  153. package/dist/loaders/text/text-loaders.d.ts +48 -0
  154. package/dist/loaders/text/text-loaders.js +723 -0
  155. package/dist/loaders/trace.d.ts +6 -0
  156. package/dist/loaders/trace.js +46 -0
  157. package/dist/loaders/types.d.ts +10 -0
  158. package/dist/loaders/wave.d.ts +8 -0
  159. package/dist/loaders/wave.js +59 -0
  160. package/dist/loaders-text.d.ts +2 -47
  161. package/dist/loaders-text.js +1 -743
  162. package/dist/loaders.d.ts +36 -132
  163. package/dist/loaders.js +35 -1096
  164. package/dist/native-select/index.d.ts +3 -0
  165. package/dist/native-select/native-select.d.ts +9 -0
  166. package/dist/native-select/native-select.js +44 -0
  167. package/dist/pagination/index.d.ts +3 -0
  168. package/dist/pagination/pagination.d.ts +18 -0
  169. package/dist/pagination/pagination.js +134 -0
  170. package/dist/popover/index.d.ts +3 -0
  171. package/dist/popover/popover.d.ts +10 -0
  172. package/dist/popover/popover.js +54 -0
  173. package/dist/radio-group/index.d.ts +3 -0
  174. package/dist/radio-group/radio-group.d.ts +6 -0
  175. package/dist/radio-group/radio-group.js +33 -0
  176. package/dist/select/index.d.ts +3 -0
  177. package/dist/select/select.d.ts +16 -0
  178. package/dist/select/select.js +148 -0
  179. package/dist/separator/index.d.ts +3 -0
  180. package/dist/separator/separator.d.ts +4 -0
  181. package/dist/separator/separator.js +15 -0
  182. package/dist/skeleton/index.d.ts +3 -0
  183. package/dist/skeleton/skeleton.d.ts +10 -0
  184. package/dist/skeleton/skeleton.js +24 -0
  185. package/dist/slider/index.d.ts +3 -0
  186. package/dist/slider/slider.d.ts +4 -0
  187. package/dist/slider/slider.js +39 -0
  188. package/dist/sound/sound-map.d.ts +70 -0
  189. package/dist/sound/sound-map.js +72 -0
  190. package/dist/sound/sound.d.ts +38 -0
  191. package/dist/sound/sound.js +136 -0
  192. package/dist/sound/uisfx.d.ts +37 -0
  193. package/dist/sound/uisfx.js +59 -0
  194. package/dist/sound-uisfx.d.ts +2 -37
  195. package/dist/sound-uisfx.js +1 -58
  196. package/dist/spinner/index.d.ts +5 -0
  197. package/dist/spinner/loader-provider.d.ts +16 -0
  198. package/dist/spinner/loader-provider.js +28 -0
  199. package/dist/spinner/registry.d.ts +9 -0
  200. package/dist/spinner/registry.js +15 -0
  201. package/dist/spinner/spinner.d.ts +26 -0
  202. package/dist/spinner/spinner.js +143 -0
  203. package/dist/switch/index.d.ts +3 -0
  204. package/dist/switch/switch.d.ts +6 -0
  205. package/dist/switch/switch.js +25 -0
  206. package/dist/table/index.d.ts +3 -0
  207. package/dist/table/table.d.ts +17 -0
  208. package/dist/table/table.js +66 -0
  209. package/dist/tabs/index.d.ts +3 -0
  210. package/dist/tabs/tabs.d.ts +11 -0
  211. package/dist/tabs/tabs.js +46 -0
  212. package/dist/textarea/index.d.ts +3 -0
  213. package/dist/textarea/textarea.d.ts +4 -0
  214. package/dist/textarea/textarea.js +12 -0
  215. package/dist/toast/index.d.ts +3 -0
  216. package/dist/toast/toast.d.ts +17 -0
  217. package/dist/toast/toast.js +211 -0
  218. package/dist/toggle-group/index.d.ts +3 -0
  219. package/dist/toggle-group/toggle-group.d.ts +64 -0
  220. package/dist/toggle-group/toggle-group.js +95 -0
  221. package/dist/tokens/dist/motion.d.ts +24 -0
  222. package/dist/{motion-NQq2BA78.js → tokens/dist/motion.js} +1 -1
  223. package/dist/toolbar/index.d.ts +3 -0
  224. package/dist/toolbar/overflow.d.ts +4 -0
  225. package/dist/toolbar/overflow.js +242 -0
  226. package/dist/toolbar/toolbar-item.d.ts +29 -0
  227. package/dist/toolbar/toolbar-item.js +71 -0
  228. package/dist/toolbar/toolbar.d.ts +73 -0
  229. package/dist/toolbar/toolbar.js +250 -0
  230. package/dist/tooltip/index.d.ts +3 -0
  231. package/dist/tooltip/tooltip.d.ts +7 -0
  232. package/dist/tooltip/tooltip.js +41 -0
  233. package/package.json +4 -3
  234. package/dist/registry-2PyPW9Xw.js +0 -390
  235. package/dist/registry-DjfWNw3R.d.ts +0 -18
  236. package/dist/sound-DiYNAnR_.d.ts +0 -61
@@ -0,0 +1,3 @@
1
+
2
+ import { Input } from "./input.js";
3
+ export { Input };
@@ -0,0 +1,4 @@
1
+
2
+ import * as React from "react";
3
+ declare function Input({ className, type, ...props }: React.ComponentProps<"input">): React.JSX.Element;
4
+ export { Input };
@@ -0,0 +1,14 @@
1
+ "use client";
2
+ import { cn } from "../lib/cn.js";
3
+ import { jsx } from "react/jsx-runtime";
4
+ import { Input } from "@base-ui/react/input";
5
+ // src/input/input.tsx
6
+ function Input$1({ className, type, ...props }) {
7
+ return /* @__PURE__ */ jsx(Input, {
8
+ type,
9
+ "data-slot": "input",
10
+ className: cn("h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40", className),
11
+ ...props
12
+ });
13
+ }
14
+ export { Input$1 as Input };
@@ -0,0 +1,3 @@
1
+
2
+ import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea } from "./input-group.js";
3
+ export { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea };
@@ -0,0 +1,19 @@
1
+
2
+ import { Button } from "../button/button.js";
3
+ import { VariantProps } from "class-variance-authority";
4
+ import * as React from "react";
5
+ declare function InputGroup({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
6
+ declare const inputGroupAddonVariants: (props?: ({
7
+ align?: "inline-start" | "inline-end" | "block-start" | "block-end" | null | undefined;
8
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
9
+ declare function InputGroupAddon({ className, align, ...props }: React.ComponentProps<"div"> & VariantProps<typeof inputGroupAddonVariants>): React.JSX.Element;
10
+ declare const inputGroupButtonVariants: (props?: ({
11
+ size?: "xs" | "sm" | "icon-xs" | "icon-sm" | null | undefined;
12
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
13
+ declare function InputGroupButton({ className, type, variant, size, ...props }: Omit<React.ComponentProps<typeof Button>, "size" | "type"> & VariantProps<typeof inputGroupButtonVariants> & {
14
+ type?: "button" | "submit" | "reset";
15
+ }): React.JSX.Element;
16
+ declare function InputGroupText({ className, ...props }: React.ComponentProps<"span">): React.JSX.Element;
17
+ declare function InputGroupInput({ className, ...props }: React.ComponentProps<"input">): React.JSX.Element;
18
+ declare function InputGroupTextarea({ className, ...props }: React.ComponentProps<"textarea">): React.JSX.Element;
19
+ export { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea };
@@ -0,0 +1,78 @@
1
+ "use client";
2
+ "use client";
3
+ import { cn } from "../lib/cn.js";
4
+ import { Button } from "../button/button.js";
5
+ import { Input } from "../input/input.js";
6
+ import { Textarea } from "../textarea/textarea.js";
7
+ import { jsx } from "react/jsx-runtime";
8
+ import { cva } from "class-variance-authority";
9
+ // src/input-group/input-group.tsx
10
+ function InputGroup({ className, ...props }) {
11
+ return /* @__PURE__ */ jsx("div", {
12
+ "data-slot": "input-group",
13
+ role: "group",
14
+ className: cn("group/input-group relative flex h-8 w-full min-w-0 items-center rounded-lg border border-input transition-colors outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-disabled:bg-input/50 has-disabled:opacity-50 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-3 has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-3 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto dark:bg-input/30 dark:has-disabled:bg-input/80 dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5", className),
15
+ ...props
16
+ });
17
+ }
18
+ const inputGroupAddonVariants = cva("flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium text-muted-foreground select-none group-data-[disabled=true]/input-group:opacity-50 [&>kbd]:rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-4", {
19
+ variants: { align: {
20
+ "inline-start": "order-first pl-2 has-[>button]:ml-[-0.3rem] has-[>kbd]:ml-[-0.15rem]",
21
+ "inline-end": "order-last pr-2 has-[>button]:mr-[-0.3rem] has-[>kbd]:mr-[-0.15rem]",
22
+ "block-start": "order-first w-full justify-start px-2.5 pt-2 group-has-[>input]/input-group:pt-2 [.border-b]:pb-2",
23
+ "block-end": "order-last w-full justify-start px-2.5 pb-2 group-has-[>input]/input-group:pb-2 [.border-t]:pt-2"
24
+ } },
25
+ defaultVariants: { align: "inline-start" }
26
+ });
27
+ function InputGroupAddon({ className, align = "inline-start", ...props }) {
28
+ return /* @__PURE__ */ jsx("div", {
29
+ role: "group",
30
+ "data-slot": "input-group-addon",
31
+ "data-align": align,
32
+ className: cn(inputGroupAddonVariants({ align }), className),
33
+ onClick: (e) => {
34
+ if (e.target.closest("button")) return;
35
+ e.currentTarget.parentElement?.querySelector("input, textarea")?.focus();
36
+ },
37
+ ...props
38
+ });
39
+ }
40
+ const inputGroupButtonVariants = cva("flex items-center gap-2 text-sm shadow-none", {
41
+ variants: { size: {
42
+ xs: "h-6 gap-1 rounded-[calc(var(--radius)-3px)] px-1.5 [&>svg:not([class*='size-'])]:size-3.5",
43
+ sm: "",
44
+ "icon-xs": "size-6 rounded-[calc(var(--radius)-3px)] p-0 has-[>svg]:p-0",
45
+ "icon-sm": "size-8 p-0 has-[>svg]:p-0"
46
+ } },
47
+ defaultVariants: { size: "xs" }
48
+ });
49
+ function InputGroupButton({ className, type = "button", variant = "ghost", size = "xs", ...props }) {
50
+ return /* @__PURE__ */ jsx(Button, {
51
+ type,
52
+ "data-size": size,
53
+ variant,
54
+ className: cn(inputGroupButtonVariants({ size }), className),
55
+ ...props
56
+ });
57
+ }
58
+ function InputGroupText({ className, ...props }) {
59
+ return /* @__PURE__ */ jsx("span", {
60
+ className: cn("flex items-center gap-2 text-sm text-muted-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4", className),
61
+ ...props
62
+ });
63
+ }
64
+ function InputGroupInput({ className, ...props }) {
65
+ return /* @__PURE__ */ jsx(Input, {
66
+ "data-slot": "input-group-control",
67
+ className: cn("flex-1 rounded-none border-0 bg-transparent shadow-none ring-0 focus-visible:ring-0 disabled:bg-transparent aria-invalid:ring-0 dark:bg-transparent dark:disabled:bg-transparent", className),
68
+ ...props
69
+ });
70
+ }
71
+ function InputGroupTextarea({ className, ...props }) {
72
+ return /* @__PURE__ */ jsx(Textarea, {
73
+ "data-slot": "input-group-control",
74
+ className: cn("flex-1 resize-none rounded-none border-0 bg-transparent py-2 shadow-none ring-0 focus-visible:ring-0 disabled:bg-transparent aria-invalid:ring-0 dark:bg-transparent dark:disabled:bg-transparent", className),
75
+ ...props
76
+ });
77
+ }
78
+ export { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea };
@@ -0,0 +1,3 @@
1
+
2
+ import { InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot } from "./input-otp.js";
3
+ export { InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot };
@@ -0,0 +1,12 @@
1
+
2
+ import * as React from "react";
3
+ import { OTPInput } from "input-otp";
4
+ declare function InputOTP({ className, containerClassName, ...props }: React.ComponentProps<typeof OTPInput> & {
5
+ containerClassName?: string;
6
+ }): React.JSX.Element;
7
+ declare function InputOTPGroup({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
8
+ declare function InputOTPSlot({ index, className, ...props }: React.ComponentProps<"div"> & {
9
+ index: number;
10
+ }): React.JSX.Element;
11
+ declare function InputOTPSeparator({ ...props }: React.ComponentProps<"div">): React.JSX.Element;
12
+ export { InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot };
@@ -0,0 +1,73 @@
1
+ "use client";
2
+ "use client";
3
+ import { cn } from "../lib/cn.js";
4
+ import { recentUserAction } from "../lib/user-action.js";
5
+ import { useCue } from "../sound/sound-map.js";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import * as React from "react";
8
+ import { OTPInput, OTPInputContext } from "input-otp";
9
+ // src/input-otp/input-otp.tsx
10
+ function InputOTP({ className, containerClassName, ...props }) {
11
+ const cue = useCue("input-otp");
12
+ const invalid = props["aria-invalid"] === true || props["aria-invalid"] === "true";
13
+ const complete = typeof props.value === "string" && props.value.length === props.maxLength;
14
+ const wasInvalid = React.useRef(invalid);
15
+ React.useEffect(() => {
16
+ if (invalid && !wasInvalid.current && complete && recentUserAction()) cue("invalid");
17
+ wasInvalid.current = invalid;
18
+ }, [
19
+ invalid,
20
+ complete,
21
+ cue
22
+ ]);
23
+ return /* @__PURE__ */ jsx(OTPInput, {
24
+ "data-slot": "input-otp",
25
+ containerClassName: cn("cn-input-otp flex items-center has-disabled:opacity-50", containerClassName),
26
+ spellCheck: false,
27
+ className: cn("disabled:cursor-not-allowed", className),
28
+ ...props
29
+ });
30
+ }
31
+ function InputOTPGroup({ className, ...props }) {
32
+ return /* @__PURE__ */ jsx("div", {
33
+ "data-slot": "input-otp-group",
34
+ className: cn("flex items-center rounded-lg has-aria-invalid:border-destructive has-aria-invalid:ring-3 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40", className),
35
+ ...props
36
+ });
37
+ }
38
+ function InputOTPSlot({ index, className, ...props }) {
39
+ const { char, hasFakeCaret, isActive } = React.useContext(OTPInputContext)?.slots[index] ?? {};
40
+ return /* @__PURE__ */ jsxs("div", {
41
+ "data-slot": "input-otp-slot",
42
+ "data-active": isActive,
43
+ className: cn("relative flex size-8 items-center justify-center border-y border-r border-input text-sm transition-all outline-none first:rounded-l-lg first:border-l last:rounded-r-lg aria-invalid:border-destructive data-[active=true]:z-10 data-[active=true]:border-ring data-[active=true]:ring-3 data-[active=true]:ring-ring/50 data-[active=true]:aria-invalid:border-destructive data-[active=true]:aria-invalid:ring-destructive/20 dark:bg-input/30 dark:data-[active=true]:aria-invalid:ring-destructive/40", className),
44
+ ...props,
45
+ children: [char && /* @__PURE__ */ jsx("span", {
46
+ "data-slot": "input-otp-char",
47
+ children: char
48
+ }, char), hasFakeCaret && /* @__PURE__ */ jsx("div", {
49
+ className: "pointer-events-none absolute inset-0 flex items-center justify-center",
50
+ children: /* @__PURE__ */ jsx("div", { className: "h-4 w-px animate-caret-blink bg-foreground" })
51
+ })]
52
+ });
53
+ }
54
+ function InputOTPSeparator({ ...props }) {
55
+ return /* @__PURE__ */ jsx("div", {
56
+ "data-slot": "input-otp-separator",
57
+ className: "flex items-center [&_svg:not([class*='size-'])]:size-4",
58
+ role: "separator",
59
+ ...props,
60
+ children: /* @__PURE__ */ jsx("svg", {
61
+ xmlns: "http://www.w3.org/2000/svg",
62
+ viewBox: "0 0 24 24",
63
+ fill: "none",
64
+ stroke: "currentColor",
65
+ strokeWidth: "2",
66
+ strokeLinecap: "round",
67
+ strokeLinejoin: "round",
68
+ "aria-hidden": "true",
69
+ children: /* @__PURE__ */ jsx("path", { d: "M5 12h14" })
70
+ })
71
+ });
72
+ }
73
+ export { InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot };
@@ -0,0 +1,3 @@
1
+
2
+ import { Kbd, KbdGroup } from "./kbd.js";
3
+ export { Kbd, KbdGroup };
@@ -0,0 +1,5 @@
1
+
2
+ import * as React from "react";
3
+ declare function Kbd({ className, ...props }: React.ComponentProps<"kbd">): React.JSX.Element;
4
+ declare function KbdGroup({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
5
+ export { Kbd, KbdGroup };
@@ -0,0 +1,19 @@
1
+ "use client";
2
+ import { cn } from "../lib/cn.js";
3
+ import { jsx } from "react/jsx-runtime";
4
+ // src/kbd/kbd.tsx
5
+ function Kbd({ className, ...props }) {
6
+ return /* @__PURE__ */ jsx("kbd", {
7
+ "data-slot": "kbd",
8
+ className: cn("pointer-events-none inline-flex h-5 w-fit min-w-5 items-center justify-center gap-1 rounded-sm bg-muted px-1 font-sans text-xs font-medium text-muted-foreground select-none in-data-[slot=tooltip-content]:bg-background/20 in-data-[slot=tooltip-content]:text-background dark:in-data-[slot=tooltip-content]:bg-background/10 [&_svg:not([class*='size-'])]:size-3", className),
9
+ ...props
10
+ });
11
+ }
12
+ function KbdGroup({ className, ...props }) {
13
+ return /* @__PURE__ */ jsx("kbd", {
14
+ "data-slot": "kbd-group",
15
+ className: cn("inline-flex items-center gap-1", className),
16
+ ...props
17
+ });
18
+ }
19
+ export { Kbd, KbdGroup };
@@ -0,0 +1,3 @@
1
+
2
+ import { Label } from "./label.js";
3
+ export { Label };
@@ -0,0 +1,4 @@
1
+
2
+ import * as React from "react";
3
+ declare function Label({ className, ...props }: React.ComponentProps<"label">): React.JSX.Element;
4
+ export { Label };
@@ -0,0 +1,13 @@
1
+ "use client";
2
+ "use client";
3
+ import { cn } from "../lib/cn.js";
4
+ import { jsx } from "react/jsx-runtime";
5
+ // src/label/label.tsx
6
+ function Label({ className, ...props }) {
7
+ return /* @__PURE__ */ jsx("label", {
8
+ "data-slot": "label",
9
+ className: cn("flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50 peer-data-disabled:cursor-not-allowed peer-data-disabled:opacity-50", className),
10
+ ...props
11
+ });
12
+ }
13
+ export { Label };
@@ -0,0 +1,58 @@
1
+ "use client";
2
+ import { cn } from "../../lib/cn.js";
3
+ import { blur, scale, spring } from "../../tokens/dist/motion.js";
4
+ import { jsx } from "react/jsx-runtime";
5
+ import { AnimatePresence, motion } from "motion/react";
6
+ // src/legacy/icon-button/icon-swap.tsx
7
+ const INSTANT = { duration: 0 };
8
+ const blurred = (radius) => `blur(${radius}px)`;
9
+ /**
10
+ * Swap states, as functions of `custom`, so an exiting icon reads the latest instant / reduced
11
+ * values from AnimatePresence rather than the props it had when it was last rendered. Instant
12
+ * and reduced swaps never scale or blur, not even for a frame.
13
+ */
14
+ const iconSwapVariants = {
15
+ hidden: ({ instant, reduced }) => ({
16
+ opacity: 0,
17
+ transform: `scale(${instant || reduced ? 1 : scale["icon-from"]})`,
18
+ filter: blurred(instant || reduced ? 0 : blur.icon),
19
+ transition: instant ? INSTANT : spring.icon
20
+ }),
21
+ shown: ({ instant }) => ({
22
+ opacity: 1,
23
+ transform: "scale(1)",
24
+ filter: blurred(0),
25
+ transition: instant ? INSTANT : spring.icon,
26
+ transitionEnd: { filter: "none" }
27
+ })
28
+ };
29
+ /**
30
+ * Cross-fades between icons stacked in one grid cell, so the container never resizes. Nothing
31
+ * animates on mount (`initial={false}`); springs retarget from the live value when interrupted,
32
+ * and the latest content always wins.
33
+ */
34
+ function IconSwap({ contentKey, instant, reduced, slot, layerClassName, className, children }) {
35
+ const custom = {
36
+ instant,
37
+ reduced
38
+ };
39
+ return /* @__PURE__ */ jsx("span", {
40
+ "aria-hidden": "true",
41
+ className: cn(className, "grid place-items-center"),
42
+ children: /* @__PURE__ */ jsx(AnimatePresence, {
43
+ initial: false,
44
+ custom,
45
+ children: /* @__PURE__ */ jsx(motion.span, {
46
+ "data-slot": slot,
47
+ custom,
48
+ variants: iconSwapVariants,
49
+ initial: "hidden",
50
+ animate: "shown",
51
+ exit: "hidden",
52
+ className: cn("inline-flex size-full items-center justify-center [grid-area:1/1] [&_svg]:size-full", layerClassName),
53
+ children
54
+ }, contentKey)
55
+ })
56
+ });
57
+ }
58
+ export { IconSwap, iconSwapVariants };
@@ -0,0 +1,3 @@
1
+
2
+ import { ClassValue } from "clsx";
3
+ export declare function cn(...inputs: ClassValue[]): string;
@@ -60,4 +60,4 @@ const twMerge = extendTailwindMerge(twMergeConfig);
60
60
  function cn(...inputs) {
61
61
  return twMerge(clsx(inputs));
62
62
  }
63
- export { twMergeConfig as n, cn as t };
63
+ export { cn, twMergeConfig };
@@ -0,0 +1,8 @@
1
+ "use client";
2
+ import { createContext, useContext } from "react";
3
+ // src/lib/control-defaults.tsx
4
+ const ControlDefaultsContext = createContext({});
5
+ function useControlDefaults() {
6
+ return useContext(ControlDefaultsContext);
7
+ }
8
+ export { ControlDefaultsContext, useControlDefaults };
@@ -0,0 +1,15 @@
1
+
2
+ import { ReactNode } from "react";
3
+ export interface IconSwapProps {
4
+ /** Changes when the shown icon changes; the old one cross-fades out on `spring.icon`. */
5
+ contentKey: string;
6
+ /** Classes for the stack, which sets the size (e.g. `size-4`). */
7
+ className?: string | undefined;
8
+ children: ReactNode;
9
+ }
10
+ /**
11
+ * Cross-fades icons in one cell: scale 0.25 → 1, opacity, blur 4 → 0 on `spring.icon`. Instant
12
+ * after a key press (input modality, #71 (3)); an opacity fade only under reduced motion (the OS,
13
+ * a MotionConfig or `<html data-motion>`). Nothing animates on mount.
14
+ */
15
+ export declare function IconSwap({ contentKey, className, children }: IconSwapProps): import("react").JSX.Element;
@@ -0,0 +1,26 @@
1
+ "use client";
2
+ import { getInputModality } from "./input-modality.js";
3
+ import { IconSwap as IconSwap$1 } from "../legacy/icon-button/icon-swap.js";
4
+ import { jsx } from "react/jsx-runtime";
5
+ import { useReducedMotion, useReducedMotionConfig } from "motion/react";
6
+ // src/lib/icon-swap.tsx
7
+ /**
8
+ * Cross-fades icons in one cell: scale 0.25 → 1, opacity, blur 4 → 0 on `spring.icon`. Instant
9
+ * after a key press (input modality, #71 (3)); an opacity fade only under reduced motion (the OS,
10
+ * a MotionConfig or `<html data-motion>`). Nothing animates on mount.
11
+ */
12
+ function IconSwap({ contentKey, className, children }) {
13
+ const prefersReduced = useReducedMotion() ?? false;
14
+ const configReduced = useReducedMotionConfig() ?? false;
15
+ const html = typeof document === "undefined" ? void 0 : document.documentElement.dataset.motion;
16
+ const reduced = html === "reduce" || html !== "full" && (prefersReduced || configReduced);
17
+ return /* @__PURE__ */ jsx(IconSwap$1, {
18
+ contentKey,
19
+ instant: getInputModality() === "keyboard",
20
+ reduced,
21
+ slot: "icon-swap",
22
+ className,
23
+ children
24
+ });
25
+ }
26
+ export { IconSwap };
@@ -0,0 +1,39 @@
1
+ "use client";
2
+ // src/lib/input-modality.ts
3
+ let modality = "pointer";
4
+ let installed = false;
5
+ let interactedAt = null;
6
+ /** The attribute on <html> that feel.css reads: keyboard-opened surfaces open without motion (#71, #108). */
7
+ const MODALITY_ATTRIBUTE = "data-nsaa-input";
8
+ /**
9
+ * Tracks the latest input modality in the capture phase, so a state change driven by a page
10
+ * hotkey (Space, M, mod+B, mod+K) is known to be keyboard-initiated even though no button was
11
+ * clicked. A pointer that moves takes over again, so hovering after typing animates. Idempotent;
12
+ * `@nsaa/core` installs it when it loads.
13
+ */
14
+ function trackInputModality() {
15
+ if (installed || typeof document === "undefined") return;
16
+ installed = true;
17
+ document.addEventListener("keydown", () => interact("keyboard"), true);
18
+ document.addEventListener("pointerdown", () => interact("pointer"), true);
19
+ document.addEventListener("pointermove", () => setInputModality("pointer"), true);
20
+ }
21
+ function interact(next) {
22
+ interactedAt = Date.now();
23
+ setInputModality(next);
24
+ }
25
+ /** When the person last pressed a key or a pointer (not a pointer move), or null before that. */
26
+ function lastInteractionAt() {
27
+ return interactedAt;
28
+ }
29
+ function setInputModality(next) {
30
+ if (next === modality && installed) {
31
+ if (document.documentElement.getAttribute("data-nsaa-input") === next) return;
32
+ }
33
+ modality = next;
34
+ if (typeof document !== "undefined") document.documentElement.setAttribute(MODALITY_ATTRIBUTE, next);
35
+ }
36
+ function getInputModality() {
37
+ return modality;
38
+ }
39
+ export { MODALITY_ATTRIBUTE, getInputModality, lastInteractionAt, setInputModality, trackInputModality };
@@ -0,0 +1,21 @@
1
+ "use client";
2
+ // src/lib/merge-refs.ts
3
+ /** Combines refs into one callback ref (React 19 cleanup-aware). */
4
+ function mergeRefs(...refs) {
5
+ return (node) => {
6
+ const cleanups = [];
7
+ for (const ref of refs) if (typeof ref === "function") {
8
+ const cleanup = ref(node);
9
+ cleanups.push(typeof cleanup === "function" ? cleanup : () => ref(null));
10
+ } else if (ref) {
11
+ ref.current = node;
12
+ cleanups.push(() => {
13
+ ref.current = null;
14
+ });
15
+ }
16
+ return () => {
17
+ for (const cleanup of cleanups) cleanup();
18
+ };
19
+ };
20
+ }
21
+ export { mergeRefs };
@@ -0,0 +1,50 @@
1
+ "use client";
2
+ // src/lib/shortcut.ts
3
+ const APPLE = /Mac|iPhone|iPad|iPod/i;
4
+ function isApple() {
5
+ if (typeof navigator === "undefined") return false;
6
+ const nav = navigator;
7
+ return APPLE.test(nav.userAgentData?.platform ?? nav.platform ?? nav.userAgent);
8
+ }
9
+ const APPLE_KEYS = {
10
+ mod: "⌘",
11
+ ctrl: "⌃",
12
+ alt: "⌥",
13
+ shift: "⇧"
14
+ };
15
+ const OTHER_KEYS = {
16
+ mod: "Ctrl",
17
+ ctrl: "Ctrl",
18
+ alt: "Alt",
19
+ shift: "Shift"
20
+ };
21
+ const ARIA_KEYS = {
22
+ mod: ["Meta", "Control"],
23
+ ctrl: ["Control", "Control"],
24
+ alt: ["Alt", "Alt"],
25
+ shift: ["Shift", "Shift"]
26
+ };
27
+ /**
28
+ * The same shortcut for `aria-keyshortcuts` (`"mod+B"` → `"Meta+B"` on Apple, `"Control+B"`
29
+ * elsewhere), so assistive tech gets what the tooltip shows only visually.
30
+ */
31
+ function ariaShortcut(shortcut, apple = isApple()) {
32
+ return shortcut.split("+").map((part) => {
33
+ const key = part.trim();
34
+ const named = ARIA_KEYS[key.toLowerCase()];
35
+ if (named) return apple ? named[0] : named[1];
36
+ return key.length === 1 ? key.toUpperCase() : key;
37
+ }).join("+");
38
+ }
39
+ /**
40
+ * Formats a display-only shortcut such as `"mod+B"`: `⌘B` on Apple platforms, `Ctrl+B` elsewhere.
41
+ * The app binds the keys; this only shows them.
42
+ */
43
+ function formatShortcut(shortcut, apple = isApple()) {
44
+ const keys = apple ? APPLE_KEYS : OTHER_KEYS;
45
+ return shortcut.split("+").map((part) => {
46
+ const key = part.trim();
47
+ return keys[key.toLowerCase()] ?? (key.length === 1 ? key.toUpperCase() : key);
48
+ }).join(apple ? "" : "+");
49
+ }
50
+ export { ariaShortcut, formatShortcut };
@@ -0,0 +1,2 @@
1
+
2
+ export {}
@@ -0,0 +1,4 @@
1
+ "use client";
2
+ import { trackInputModality } from "./input-modality.js";
3
+ // src/lib/track-input-modality.ts
4
+ trackInputModality();
package/dist/lib/tv.js ADDED
@@ -0,0 +1,7 @@
1
+ "use client";
2
+ import { twMergeConfig } from "./cn.js";
3
+ import { createTV } from "tailwind-variants";
4
+ // src/lib/tv.ts
5
+ /** tailwind-variants configured with the same merge rules as cn(). */
6
+ const tv = createTV({ twMergeConfig });
7
+ export { tv };
@@ -0,0 +1,48 @@
1
+ "use client";
2
+ import { scale, spring } from "../tokens/dist/motion.js";
3
+ import { useCallback, useRef } from "react";
4
+ import { animate, useReducedMotion, useReducedMotionConfig } from "motion/react";
5
+ // src/lib/use-press.ts
6
+ /**
7
+ * Parts of a larger shape, or high-frequency toggles: their buttons don't scale on their own
8
+ * (legacy `pressScale={false}`). A Toggle Group outside a Toolbar counts too (#128, alpha-4), and
9
+ * Pagination and the Calendar's day grid (#136).
10
+ */
11
+ const SEGMENT = "[data-slot=\"input-group\"], [data-slot=\"button-group\"], [data-slot=\"toolbar\"], [data-slot=\"toggle-group\"], [data-slot=\"pagination-link\"], [data-slot=\"calendar\"]";
12
+ /**
13
+ * Pointer-only press: scale to `scale.press` on pointer-down and back on release, on `spring.snap`,
14
+ * interruptible from the live value. Never on hover, on keyboard activation, when disabled, under
15
+ * reduced motion (the OS or `<html data-motion>`), or inside a segmented shape.
16
+ */
17
+ function usePress() {
18
+ const prefersReduced = useReducedMotion() ?? false;
19
+ const configReduced = useReducedMotionConfig() ?? false;
20
+ const pressed = useRef(null);
21
+ const reduced = useCallback(() => {
22
+ const html = document.documentElement.dataset.motion;
23
+ if (html === "reduce") return true;
24
+ if (html === "full") return false;
25
+ return prefersReduced || configReduced;
26
+ }, [prefersReduced, configReduced]);
27
+ const release = useCallback(() => {
28
+ const el = pressed.current;
29
+ if (!el) return;
30
+ pressed.current = null;
31
+ animate(el, { scale: 1 }, spring.snap);
32
+ }, []);
33
+ return {
34
+ onPointerDown: useCallback((event) => {
35
+ const el = event.currentTarget;
36
+ if (event.defaultPrevented || event.button !== 0 || reduced()) return;
37
+ if (el.matches(":disabled, [aria-disabled='true'], [data-disabled]")) return;
38
+ if (el.closest(SEGMENT)) return;
39
+ if (el.hasAttribute("aria-haspopup")) return;
40
+ pressed.current = el;
41
+ animate(el, { scale: scale.press }, spring.snap);
42
+ }, [reduced]),
43
+ onPointerUp: release,
44
+ onPointerLeave: release,
45
+ onPointerCancel: release
46
+ };
47
+ }
48
+ export { usePress };
@@ -0,0 +1,13 @@
1
+ "use client";
2
+ import { lastInteractionAt } from "./input-modality.js";
3
+ // src/lib/user-action.ts
4
+ /** How long after a key press or pointer down something counts as its result (the browsers' own
5
+ * transient-activation window). */
6
+ const USER_ACTION_WINDOW_MS = 5e3;
7
+ /** True when the person pressed a key or a pointer within the window: a state that appears now is
8
+ * most likely their action's result (a failed payment Alert), not something on load. */
9
+ function recentUserAction(now = Date.now()) {
10
+ const at = lastInteractionAt();
11
+ return at !== null && now - at < 5e3;
12
+ }
13
+ export { USER_ACTION_WINDOW_MS, recentUserAction };
@@ -0,0 +1,6 @@
1
+
2
+ import { SpinnerProps } from "./types.js";
3
+ import { CapProps } from "./cap.js";
4
+ import { EasingProps } from "./easing.js";
5
+ export interface ArcProps extends SpinnerProps, EasingProps, CapProps {}
6
+ export declare function Arc({ cap, easing, ...rest }: ArcProps): import("react").JSX.Element;
@@ -0,0 +1,31 @@
1
+ "use client";
2
+ import { linecap } from "./cap.js";
3
+ import { rotationCss, spinClass } from "./easing.js";
4
+ import { SpinnerStyle, spinnerRoot } from "./frame.js";
5
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
+ // src/loaders/arc.tsx
7
+ const css = `
8
+ ${rotationCss("arc")}
9
+ `;
10
+ function Arc({ cap, easing, ...rest }) {
11
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(SpinnerStyle, {
12
+ name: "arc",
13
+ children: css
14
+ }), /* @__PURE__ */ jsx("svg", {
15
+ ...spinnerRoot("arc", rest),
16
+ fill: "none",
17
+ role: "presentation",
18
+ viewBox: "0 0 24 24",
19
+ children: /* @__PURE__ */ jsx("circle", {
20
+ className: spinClass("arc", easing),
21
+ cx: "12",
22
+ cy: "12",
23
+ r: "10",
24
+ stroke: "currentColor",
25
+ strokeDasharray: "18 44.8",
26
+ strokeLinecap: linecap(cap),
27
+ strokeWidth: "2.5"
28
+ })
29
+ })] });
30
+ }
31
+ export { Arc };
@@ -0,0 +1,5 @@
1
+
2
+ import { SpinnerProps } from "./types.js";
3
+ import { EasingProps } from "./easing.js";
4
+ export interface AtomProps extends SpinnerProps, EasingProps {}
5
+ export declare function Atom({ easing, ...rest }: AtomProps): import("react").JSX.Element;