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

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 (286) hide show
  1. package/README.md +30 -8
  2. package/dist/_virtual/_rolldown/runtime.js +13 -0
  3. package/dist/accordion/accordion.d.ts +7 -0
  4. package/dist/accordion/accordion.js +54 -0
  5. package/dist/accordion/index.d.ts +3 -0
  6. package/dist/alert/alert.d.ts +19 -0
  7. package/dist/alert/alert.js +58 -0
  8. package/dist/alert/index.d.ts +3 -0
  9. package/dist/alert-dialog/alert-dialog.d.ts +19 -0
  10. package/dist/alert-dialog/alert-dialog.js +106 -0
  11. package/dist/alert-dialog/index.d.ts +3 -0
  12. package/dist/avatar/avatar.d.ts +12 -0
  13. package/dist/avatar/avatar.js +50 -0
  14. package/dist/avatar/index.d.ts +3 -0
  15. package/dist/badge/badge.d.ts +8 -0
  16. package/dist/badge/badge.js +29 -0
  17. package/dist/badge/index.d.ts +3 -0
  18. package/dist/button/button.d.ts +25 -0
  19. package/dist/button/button.js +136 -0
  20. package/dist/button/index.d.ts +3 -0
  21. package/dist/calendar/calendar.d.ts +11 -0
  22. package/dist/calendar/calendar.js +131 -0
  23. package/dist/calendar/index.d.ts +3 -0
  24. package/dist/card/card.d.ts +12 -0
  25. package/dist/card/card.js +55 -0
  26. package/dist/card/index.d.ts +3 -0
  27. package/dist/checkbox/checkbox.d.ts +4 -0
  28. package/dist/checkbox/checkbox.js +35 -0
  29. package/dist/checkbox/index.d.ts +3 -0
  30. package/dist/collapsible/collapsible.d.ts +6 -0
  31. package/dist/collapsible/collapsible.js +24 -0
  32. package/dist/collapsible/index.d.ts +3 -0
  33. package/dist/combobox/combobox.d.ts +27 -0
  34. package/dist/combobox/combobox.js +226 -0
  35. package/dist/combobox/index.d.ts +3 -0
  36. package/dist/command/command.d.ts +20 -0
  37. package/dist/command/command.js +116 -0
  38. package/dist/command/index.d.ts +3 -0
  39. package/dist/context-menu/context-menu.d.ts +30 -0
  40. package/dist/context-menu/context-menu.js +173 -0
  41. package/dist/context-menu/index.d.ts +3 -0
  42. package/dist/dialog/dialog.d.ts +18 -0
  43. package/dist/dialog/dialog.js +112 -0
  44. package/dist/dialog/index.d.ts +3 -0
  45. package/dist/direction.d.ts +3 -0
  46. package/dist/direction.js +2 -0
  47. package/dist/drawer/drawer.d.ts +17 -0
  48. package/dist/drawer/drawer.js +136 -0
  49. package/dist/drawer/index.d.ts +3 -0
  50. package/dist/dropdown-menu/dropdown-menu.d.ts +30 -0
  51. package/dist/dropdown-menu/dropdown-menu.js +177 -0
  52. package/dist/dropdown-menu/index.d.ts +3 -0
  53. package/dist/empty/empty.d.ts +35 -0
  54. package/dist/empty/empty.js +93 -0
  55. package/dist/empty/index.d.ts +3 -0
  56. package/dist/field/field.d.ts +26 -0
  57. package/dist/field/field.js +109 -0
  58. package/dist/field/index.d.ts +3 -0
  59. package/dist/index.d.ts +90 -674
  60. package/dist/index.js +50 -3877
  61. package/dist/input/index.d.ts +3 -0
  62. package/dist/input/input.d.ts +4 -0
  63. package/dist/input/input.js +14 -0
  64. package/dist/input-group/index.d.ts +3 -0
  65. package/dist/input-group/input-group.d.ts +19 -0
  66. package/dist/input-group/input-group.js +78 -0
  67. package/dist/input-otp/index.d.ts +3 -0
  68. package/dist/input-otp/input-otp.d.ts +12 -0
  69. package/dist/input-otp/input-otp.js +73 -0
  70. package/dist/kbd/index.d.ts +3 -0
  71. package/dist/kbd/kbd.d.ts +5 -0
  72. package/dist/kbd/kbd.js +19 -0
  73. package/dist/label/index.d.ts +3 -0
  74. package/dist/label/label.d.ts +4 -0
  75. package/dist/label/label.js +13 -0
  76. package/dist/legacy/icon-button/icon-swap.js +58 -0
  77. package/dist/lib/cn.d.ts +3 -0
  78. package/dist/{cn-DxFBFdwT.js → lib/cn.js} +1 -1
  79. package/dist/lib/control-defaults.js +8 -0
  80. package/dist/lib/icon-swap.d.ts +15 -0
  81. package/dist/lib/icon-swap.js +26 -0
  82. package/dist/lib/input-modality.js +39 -0
  83. package/dist/lib/merge-refs.js +21 -0
  84. package/dist/lib/opener.js +29 -0
  85. package/dist/lib/shortcut.js +50 -0
  86. package/dist/lib/track-input-modality.d.ts +2 -0
  87. package/dist/lib/track-input-modality.js +4 -0
  88. package/dist/lib/tv.js +7 -0
  89. package/dist/lib/use-press.js +48 -0
  90. package/dist/lib/user-action.js +13 -0
  91. package/dist/loaders/arc.d.ts +6 -0
  92. package/dist/loaders/arc.js +31 -0
  93. package/dist/loaders/atom.d.ts +5 -0
  94. package/dist/loaders/atom.js +70 -0
  95. package/dist/loaders/blocks.d.ts +8 -0
  96. package/dist/loaders/blocks.js +74 -0
  97. package/dist/loaders/bouncing-dots.d.ts +3 -0
  98. package/dist/loaders/bouncing-dots.js +45 -0
  99. package/dist/loaders/cap.d.ts +6 -0
  100. package/dist/loaders/cap.js +7 -0
  101. package/dist/loaders/cascade.d.ts +5 -0
  102. package/dist/loaders/cascade.js +50 -0
  103. package/dist/loaders/circular-dots.d.ts +3 -0
  104. package/dist/loaders/circular-dots.js +40 -0
  105. package/dist/loaders/classic-v2.d.ts +3 -0
  106. package/dist/loaders/classic-v2.js +41 -0
  107. package/dist/loaders/classic.d.ts +3 -0
  108. package/dist/loaders/classic.js +48 -0
  109. package/dist/loaders/clock.d.ts +5 -0
  110. package/dist/loaders/clock.js +31 -0
  111. package/dist/loaders/comet.d.ts +5 -0
  112. package/dist/loaders/comet.js +52 -0
  113. package/dist/loaders/compass.d.ts +3 -0
  114. package/dist/loaders/compass.js +39 -0
  115. package/dist/loaders/dual.d.ts +6 -0
  116. package/dist/loaders/dual.js +47 -0
  117. package/dist/loaders/easing.d.ts +6 -0
  118. package/dist/loaders/easing.js +34 -0
  119. package/dist/loaders/eclipse.d.ts +3 -0
  120. package/dist/loaders/eclipse.js +69 -0
  121. package/dist/loaders/fade.js +28 -0
  122. package/dist/loaders/flip.d.ts +3 -0
  123. package/dist/loaders/flip.js +41 -0
  124. package/dist/{frame-CK9IBOZB.js → loaders/frame.js} +2 -50
  125. package/dist/loaders/gather.d.ts +3 -0
  126. package/dist/loaders/gather.js +85 -0
  127. package/dist/loaders/leap.d.ts +3 -0
  128. package/dist/loaders/leap.js +67 -0
  129. package/dist/loaders/linear-dots.d.ts +3 -0
  130. package/dist/loaders/linear-dots.js +54 -0
  131. package/dist/loaders/loading.d.ts +3 -0
  132. package/dist/loaders/loading.js +64 -0
  133. package/dist/loaders/morph.d.ts +3 -0
  134. package/dist/loaders/morph.js +40 -0
  135. package/dist/loaders/motion.d.ts +35 -0
  136. package/dist/loaders/motion.js +51 -0
  137. package/dist/loaders/orbit.d.ts +5 -0
  138. package/dist/loaders/orbit.js +44 -0
  139. package/dist/loaders/pulse.d.ts +3 -0
  140. package/dist/loaders/pulse.js +52 -0
  141. package/dist/loaders/radar.d.ts +5 -0
  142. package/dist/loaders/radar.js +64 -0
  143. package/dist/loaders/ring.d.ts +6 -0
  144. package/dist/loaders/ring.js +38 -0
  145. package/dist/loaders/ripple.d.ts +8 -0
  146. package/dist/loaders/ripple.js +57 -0
  147. package/dist/loaders/slide.d.ts +3 -0
  148. package/dist/loaders/slide.js +74 -0
  149. package/dist/loaders/snake.d.ts +6 -0
  150. package/dist/loaders/snake.js +59 -0
  151. package/dist/loaders/spinners.d.ts +61 -0
  152. package/dist/loaders/spinners.js +63 -0
  153. package/dist/loaders/swirl.d.ts +3 -0
  154. package/dist/loaders/swirl.js +50 -0
  155. package/dist/loaders/text/shared.js +25 -0
  156. package/dist/loaders/text/text-loaders.d.ts +48 -0
  157. package/dist/loaders/text/text-loaders.js +723 -0
  158. package/dist/loaders/trace.d.ts +6 -0
  159. package/dist/loaders/trace.js +46 -0
  160. package/dist/loaders/types.d.ts +10 -0
  161. package/dist/loaders/wave.d.ts +8 -0
  162. package/dist/loaders/wave.js +59 -0
  163. package/dist/loaders-text.d.ts +2 -47
  164. package/dist/loaders-text.js +1 -743
  165. package/dist/loaders.d.ts +36 -132
  166. package/dist/loaders.js +35 -1096
  167. package/dist/native-select/index.d.ts +3 -0
  168. package/dist/native-select/native-select.d.ts +9 -0
  169. package/dist/native-select/native-select.js +44 -0
  170. package/dist/pagination/index.d.ts +3 -0
  171. package/dist/pagination/pagination.d.ts +18 -0
  172. package/dist/pagination/pagination.js +134 -0
  173. package/dist/popover/index.d.ts +3 -0
  174. package/dist/popover/popover.d.ts +10 -0
  175. package/dist/popover/popover.js +54 -0
  176. package/dist/radio-group/index.d.ts +3 -0
  177. package/dist/radio-group/radio-group.d.ts +6 -0
  178. package/dist/radio-group/radio-group.js +33 -0
  179. package/dist/select/index.d.ts +3 -0
  180. package/dist/select/select.d.ts +16 -0
  181. package/dist/select/select.js +148 -0
  182. package/dist/separator/index.d.ts +3 -0
  183. package/dist/separator/separator.d.ts +4 -0
  184. package/dist/separator/separator.js +15 -0
  185. package/dist/skeleton/index.d.ts +3 -0
  186. package/dist/skeleton/skeleton.d.ts +10 -0
  187. package/dist/skeleton/skeleton.js +24 -0
  188. package/dist/slider/index.d.ts +3 -0
  189. package/dist/slider/slider.d.ts +4 -0
  190. package/dist/slider/slider.js +39 -0
  191. package/dist/sound/lazy-uisfx.d.ts +20 -0
  192. package/dist/sound/lazy-uisfx.js +68 -0
  193. package/dist/sound/sound-map.d.ts +72 -0
  194. package/dist/sound/sound-map.js +76 -0
  195. package/dist/sound/sound.d.ts +38 -0
  196. package/dist/sound/sound.js +136 -0
  197. package/dist/sound/uisfx.d.ts +41 -0
  198. package/dist/sound/uisfx.js +59 -0
  199. package/dist/sound-uisfx.d.ts +2 -37
  200. package/dist/sound-uisfx.js +1 -58
  201. package/dist/sources/accordion.css +3 -0
  202. package/dist/sources/alert-dialog.css +26 -0
  203. package/dist/sources/alert.css +8 -0
  204. package/dist/sources/avatar.css +3 -0
  205. package/dist/sources/badge.css +3 -0
  206. package/dist/sources/button.css +24 -0
  207. package/dist/sources/calendar.css +25 -0
  208. package/dist/sources/card.css +3 -0
  209. package/dist/sources/checkbox.css +6 -0
  210. package/dist/sources/collapsible.css +2 -0
  211. package/dist/sources/combobox.css +28 -0
  212. package/dist/sources/command.css +30 -0
  213. package/dist/sources/context-menu.css +6 -0
  214. package/dist/sources/dialog.css +26 -0
  215. package/dist/sources/drawer.css +6 -0
  216. package/dist/sources/dropdown-menu.css +6 -0
  217. package/dist/sources/empty.css +3 -0
  218. package/dist/sources/field.css +5 -0
  219. package/dist/sources/input-group.css +27 -0
  220. package/dist/sources/input-otp.css +8 -0
  221. package/dist/sources/input.css +3 -0
  222. package/dist/sources/kbd.css +3 -0
  223. package/dist/sources/label.css +3 -0
  224. package/dist/sources/loaders-text.css +8 -0
  225. package/dist/sources/loaders.css +40 -0
  226. package/dist/sources/native-select.css +3 -0
  227. package/dist/sources/pagination.css +25 -0
  228. package/dist/sources/popover.css +3 -0
  229. package/dist/sources/radio-group.css +6 -0
  230. package/dist/sources/select.css +6 -0
  231. package/dist/sources/separator.css +3 -0
  232. package/dist/sources/skeleton.css +3 -0
  233. package/dist/sources/slider.css +6 -0
  234. package/dist/sources/spinner.css +20 -0
  235. package/dist/sources/switch.css +6 -0
  236. package/dist/sources/table.css +3 -0
  237. package/dist/sources/tabs.css +3 -0
  238. package/dist/sources/textarea.css +3 -0
  239. package/dist/sources/toast.css +25 -0
  240. package/dist/sources/toggle-group.css +32 -0
  241. package/dist/sources/toolbar.css +34 -0
  242. package/dist/sources/tooltip.css +3 -0
  243. package/dist/spinner/index.d.ts +5 -0
  244. package/dist/spinner/loader-provider.d.ts +16 -0
  245. package/dist/spinner/loader-provider.js +28 -0
  246. package/dist/spinner/registry.d.ts +9 -0
  247. package/dist/spinner/registry.js +15 -0
  248. package/dist/spinner/spinner.d.ts +26 -0
  249. package/dist/spinner/spinner.js +143 -0
  250. package/dist/switch/index.d.ts +3 -0
  251. package/dist/switch/switch.d.ts +6 -0
  252. package/dist/switch/switch.js +25 -0
  253. package/dist/table/index.d.ts +3 -0
  254. package/dist/table/table.d.ts +17 -0
  255. package/dist/table/table.js +66 -0
  256. package/dist/tabs/index.d.ts +3 -0
  257. package/dist/tabs/tabs.d.ts +11 -0
  258. package/dist/tabs/tabs.js +46 -0
  259. package/dist/textarea/index.d.ts +3 -0
  260. package/dist/textarea/textarea.d.ts +4 -0
  261. package/dist/textarea/textarea.js +12 -0
  262. package/dist/toast/index.d.ts +3 -0
  263. package/dist/toast/toast.d.ts +17 -0
  264. package/dist/toast/toast.js +211 -0
  265. package/dist/toggle-group/index.d.ts +3 -0
  266. package/dist/toggle-group/toggle-group.d.ts +64 -0
  267. package/dist/toggle-group/toggle-group.js +95 -0
  268. package/dist/tokens/dist/motion.d.ts +24 -0
  269. package/dist/{motion-NQq2BA78.js → tokens/dist/motion.js} +1 -1
  270. package/dist/toolbar/index.d.ts +3 -0
  271. package/dist/toolbar/overflow.d.ts +4 -0
  272. package/dist/toolbar/overflow.js +242 -0
  273. package/dist/toolbar/toolbar-item.d.ts +29 -0
  274. package/dist/toolbar/toolbar-item.js +71 -0
  275. package/dist/toolbar/toolbar.d.ts +73 -0
  276. package/dist/toolbar/toolbar.js +250 -0
  277. package/dist/tooltip/index.d.ts +3 -0
  278. package/dist/tooltip/tooltip.d.ts +7 -0
  279. package/dist/tooltip/tooltip.js +41 -0
  280. package/package.json +9 -5
  281. package/src/feel.css +52 -0
  282. package/src/styles-base.css +142 -0
  283. package/src/styles.css +3 -133
  284. package/dist/registry-2PyPW9Xw.js +0 -390
  285. package/dist/registry-DjfWNw3R.d.ts +0 -18
  286. package/dist/sound-DiYNAnR_.d.ts +0 -61
package/README.md CHANGED
@@ -17,7 +17,20 @@ import { Button, SoundProvider } from "@nsaa/core";
17
17
  ```
18
18
 
19
19
  Fonts are yours to load: the tokens name Geist (body), Newsreader (the editorial theme) and Geist
20
- Mono, and fall back to the system sans. For example, in your HTML `<head>`:
20
+ Mono, and fall back to the system sans. Self-host them with Fontsource (works under a strict CSP such
21
+ as `font-src 'self'`; the tokens list the Fontsource names first, so no `@font-face` is needed):
22
+
23
+ ```sh
24
+ pnpm add @fontsource-variable/geist @fontsource-variable/geist-mono @fontsource-variable/newsreader
25
+ ```
26
+
27
+ ```css
28
+ @import "@fontsource-variable/geist";
29
+ @import "@fontsource-variable/geist-mono";
30
+ @import "@fontsource-variable/newsreader"; /* editorial theme only */
31
+ ```
32
+
33
+ Or link Google Fonts in your HTML `<head>`:
21
34
 
22
35
  ```html
23
36
  <link rel="preconnect" href="https://fonts.googleapis.com" />
@@ -28,12 +41,21 @@ Mono, and fall back to the system sans. For example, in your HTML `<head>`:
28
41
  />
29
42
  ```
30
43
 
31
- | Entry | What |
32
- | ------------------------- | ----------------------------------------------------------------------------- |
33
- | `@nsaa/core` | components, `SoundProvider`, `LoaderProvider`, `Spinner` (featured 8 loaders) |
34
- | `@nsaa/core/loaders` | all 29 loading.dev loaders, `registerLoaders` |
35
- | `@nsaa/core/loaders/text` | text and AI loaders (ShimmerText, Typing, …) |
36
- | `@nsaa/core/sound-uisfx` | the UISFX sound engine for `SoundProvider` |
37
- | `@nsaa/core/styles.css` | tokens, the shadcn alias layer and the feel layer |
44
+ Sound: `lazyUisfxPlayer()` (recommended) loads the UISFX engine on the first interaction;
45
+ `createUisfxPlayer()` from `@nsaa/core/sound-uisfx` loads it up front.
46
+
47
+ ```tsx
48
+ const player = lazyUisfxPlayer();
49
+ <SoundProvider player={player}>…</SoundProvider>;
50
+ ```
51
+
52
+ | Entry | What |
53
+ | ---------------------------- | ------------------------------------------------------------------------------------ |
54
+ | `@nsaa/core` | components, `SoundProvider`, `lazyUisfxPlayer`, `LoaderProvider`, `Spinner` |
55
+ | `@nsaa/core/loaders` | all 29 loading.dev loaders, `registerLoaders` |
56
+ | `@nsaa/core/loaders/text` | text and AI loaders (ShimmerText, Typing, …) |
57
+ | `@nsaa/core/sound-uisfx` | the UISFX sound engine for `SoundProvider` |
58
+ | `@nsaa/core/styles.css` | tokens, the shadcn alias layer, the feel layer, every component's sources |
59
+ | `@nsaa/core/styles-base.css` | the same without Tailwind sources; add `@nsaa/core/sources/<name>.css` per component |
38
60
 
39
61
  Peer dependencies: `react` and `react-dom` 19. MIT; third-party notices in `NOTICE`.
@@ -0,0 +1,13 @@
1
+ "use client";
2
+ // \0rolldown/runtime.js
3
+ var __defProp = Object.defineProperty;
4
+ var __exportAll = (all, no_symbols) => {
5
+ let target = {};
6
+ for (var name in all) __defProp(target, name, {
7
+ get: all[name],
8
+ enumerable: true
9
+ });
10
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
11
+ return target;
12
+ };
13
+ export { __exportAll };
@@ -0,0 +1,7 @@
1
+
2
+ import { Accordion } from "@base-ui/react/accordion";
3
+ declare function Accordion$1({ className, ...props }: Accordion.Root.Props): import("react").JSX.Element;
4
+ declare function AccordionItem({ className, ...props }: Accordion.Item.Props): import("react").JSX.Element;
5
+ declare function AccordionTrigger({ className, children, ...props }: Accordion.Trigger.Props): import("react").JSX.Element;
6
+ declare function AccordionContent({ className, children, ...props }: Accordion.Panel.Props): import("react").JSX.Element;
7
+ export { Accordion$1 as Accordion, AccordionContent, AccordionItem, AccordionTrigger };
@@ -0,0 +1,54 @@
1
+ "use client";
2
+ import { cn } from "../lib/cn.js";
3
+ import { Accordion } from "@base-ui/react/accordion";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ // src/accordion/accordion.tsx
6
+ function Accordion$1({ className, ...props }) {
7
+ return /* @__PURE__ */ jsx(Accordion.Root, {
8
+ "data-slot": "accordion",
9
+ className: cn("flex w-full flex-col", className),
10
+ ...props
11
+ });
12
+ }
13
+ function AccordionItem({ className, ...props }) {
14
+ return /* @__PURE__ */ jsx(Accordion.Item, {
15
+ "data-slot": "accordion-item",
16
+ className: cn("not-last:border-b", className),
17
+ ...props
18
+ });
19
+ }
20
+ function AccordionTrigger({ className, children, ...props }) {
21
+ return /* @__PURE__ */ jsx(Accordion.Header, {
22
+ className: "flex",
23
+ children: /* @__PURE__ */ jsxs(Accordion.Trigger, {
24
+ "data-slot": "accordion-trigger",
25
+ className: cn("group/accordion-trigger relative flex flex-1 items-start justify-between rounded-lg border border-transparent py-2.5 text-left text-sm font-medium transition-all outline-none hover:underline focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 focus-visible:after:border-ring aria-disabled:pointer-events-none aria-disabled:opacity-50 **:data-[slot=accordion-trigger-icon]:ml-auto **:data-[slot=accordion-trigger-icon]:size-4 **:data-[slot=accordion-trigger-icon]:text-muted-foreground", className),
26
+ ...props,
27
+ children: [children, /* @__PURE__ */ jsx("svg", {
28
+ xmlns: "http://www.w3.org/2000/svg",
29
+ viewBox: "0 0 24 24",
30
+ fill: "none",
31
+ stroke: "currentColor",
32
+ strokeWidth: "2",
33
+ strokeLinecap: "round",
34
+ strokeLinejoin: "round",
35
+ "data-slot": "accordion-trigger-icon",
36
+ className: "pointer-events-none shrink-0",
37
+ "aria-hidden": "true",
38
+ children: /* @__PURE__ */ jsx("path", { d: "m6 9 6 6 6-6" })
39
+ })]
40
+ })
41
+ });
42
+ }
43
+ function AccordionContent({ className, children, ...props }) {
44
+ return /* @__PURE__ */ jsx(Accordion.Panel, {
45
+ "data-slot": "accordion-content",
46
+ className: "overflow-hidden text-sm data-open:animate-accordion-down data-closed:animate-accordion-up",
47
+ ...props,
48
+ children: /* @__PURE__ */ jsx("div", {
49
+ className: cn("h-(--accordion-panel-height) pt-0 pb-2.5 data-ending-style:h-0 data-starting-style:h-0 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p:not(:last-child)]:mb-4", className),
50
+ children
51
+ })
52
+ });
53
+ }
54
+ export { Accordion$1 as Accordion, AccordionContent, AccordionItem, AccordionTrigger };
@@ -0,0 +1,3 @@
1
+
2
+ import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "./accordion.js";
3
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger };
@@ -0,0 +1,19 @@
1
+
2
+ import { VariantProps } from "class-variance-authority";
3
+ import * as React from "react";
4
+ declare const alertVariants: (props?: ({
5
+ variant?: "success" | "warning" | "default" | "destructive" | "info" | null | undefined;
6
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
7
+ declare function Alert({ className, variant, announce, ...props }: React.ComponentProps<"div"> & VariantProps<typeof alertVariants> & {
8
+ /**
9
+ * The error sound (feedback.error) when the Alert appears (#114). Left unset it's automatic: a
10
+ * destructive Alert plays it when a person's action caused it (within the browser's transient
11
+ * activation window), never on load. `true` always plays it, `false` never does. Success and
12
+ * warning are silent unless `announce` is set, then play feedback.success / feedback.warning.
13
+ */
14
+ announce?: boolean;
15
+ }): React.JSX.Element;
16
+ declare function AlertTitle({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
17
+ declare function AlertDescription({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
18
+ declare function AlertAction({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
19
+ export { Alert, AlertAction, AlertDescription, AlertTitle };
@@ -0,0 +1,58 @@
1
+ "use client";
2
+ import { cn } from "../lib/cn.js";
3
+ import { recentUserAction } from "../lib/user-action.js";
4
+ import { useCue } from "../sound/sound-map.js";
5
+ import { jsx } from "react/jsx-runtime";
6
+ import { cva } from "class-variance-authority";
7
+ import * as React from "react";
8
+ // src/alert/alert.tsx
9
+ const alertVariants = cva("group/alert relative grid w-full gap-0.5 rounded-lg border px-2.5 py-2 text-left text-sm has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2 *:[svg]:row-span-2 *:[svg]:translate-y-0.5 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-4", {
10
+ variants: { variant: {
11
+ default: "bg-card text-card-foreground",
12
+ destructive: "bg-card text-destructive *:data-[slot=alert-description]:text-destructive/90 *:[svg]:text-current",
13
+ success: "border-positive-subtle-active bg-positive-subtle text-on-positive-subtle-foreground *:data-[slot=alert-description]:text-on-positive-subtle-foreground",
14
+ warning: "border-warning-subtle-active bg-warning-subtle text-on-warning-subtle-foreground *:data-[slot=alert-description]:text-on-warning-subtle-foreground",
15
+ info: "border-info-subtle-active bg-info-subtle text-on-info-subtle-foreground *:data-[slot=alert-description]:text-on-info-subtle-foreground"
16
+ } },
17
+ defaultVariants: { variant: "default" }
18
+ });
19
+ function Alert({ className, variant, announce, ...props }) {
20
+ const cue = useCue("alert");
21
+ const destructive = variant === "destructive";
22
+ const announceCue = variant === "success" || variant === "warning" ? variant : "destructive";
23
+ const appear = React.useEffectEvent(() => {
24
+ if (variant === "info") return;
25
+ if (announce === true || destructive && recentUserAction()) cue(announceCue);
26
+ });
27
+ React.useEffect(() => {
28
+ if (announce !== false && (destructive || announce)) appear();
29
+ }, [destructive, announce]);
30
+ return /* @__PURE__ */ jsx("div", {
31
+ "data-slot": "alert",
32
+ role: "alert",
33
+ className: cn(alertVariants({ variant }), className),
34
+ ...props
35
+ });
36
+ }
37
+ function AlertTitle({ className, ...props }) {
38
+ return /* @__PURE__ */ jsx("div", {
39
+ "data-slot": "alert-title",
40
+ className: cn("font-medium group-has-[>svg]/alert:col-start-2 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground", className),
41
+ ...props
42
+ });
43
+ }
44
+ function AlertDescription({ className, ...props }) {
45
+ return /* @__PURE__ */ jsx("div", {
46
+ "data-slot": "alert-description",
47
+ className: cn("text-sm text-balance text-muted-foreground md:text-pretty [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p:not(:last-child)]:mb-4", className),
48
+ ...props
49
+ });
50
+ }
51
+ function AlertAction({ className, ...props }) {
52
+ return /* @__PURE__ */ jsx("div", {
53
+ "data-slot": "alert-action",
54
+ className: cn("absolute top-2 right-2", className),
55
+ ...props
56
+ });
57
+ }
58
+ export { Alert, AlertAction, AlertDescription, AlertTitle };
@@ -0,0 +1,3 @@
1
+
2
+ import { Alert, AlertAction, AlertDescription, AlertTitle } from "./alert.js";
3
+ export { Alert, AlertAction, AlertDescription, AlertTitle };
@@ -0,0 +1,19 @@
1
+
2
+ import { Button } from "../button/button.js";
3
+ import * as React from "react";
4
+ import { AlertDialog } from "@base-ui/react/alert-dialog";
5
+ declare function AlertDialog$1({ onOpenChange, ...props }: AlertDialog.Root.Props): React.JSX.Element;
6
+ declare function AlertDialogTrigger({ ...props }: AlertDialog.Trigger.Props): React.JSX.Element;
7
+ declare function AlertDialogPortal({ ...props }: AlertDialog.Portal.Props): React.JSX.Element;
8
+ declare function AlertDialogOverlay({ className, ...props }: AlertDialog.Backdrop.Props): React.JSX.Element;
9
+ declare function AlertDialogContent({ className, size, ...props }: AlertDialog.Popup.Props & {
10
+ size?: "default" | "sm";
11
+ }): React.JSX.Element;
12
+ declare function AlertDialogHeader({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
13
+ declare function AlertDialogFooter({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
14
+ declare function AlertDialogMedia({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
15
+ declare function AlertDialogTitle({ className, ...props }: React.ComponentProps<typeof AlertDialog.Title>): React.JSX.Element;
16
+ declare function AlertDialogDescription({ className, ...props }: React.ComponentProps<typeof AlertDialog.Description>): React.JSX.Element;
17
+ declare function AlertDialogAction({ className, ...props }: React.ComponentProps<typeof Button>): React.JSX.Element;
18
+ declare function AlertDialogCancel({ className, variant, size, ...props }: AlertDialog.Close.Props & Pick<React.ComponentProps<typeof Button>, "variant" | "size">): React.JSX.Element;
19
+ export { AlertDialog$1 as AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogMedia, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger };
@@ -0,0 +1,106 @@
1
+ "use client";
2
+ "use client";
3
+ import { cn } from "../lib/cn.js";
4
+ import { useCue } from "../sound/sound-map.js";
5
+ import { Button } from "../button/button.js";
6
+ import { OpenerContext, useFinalFocus, useOpener } from "../lib/opener.js";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ import { AlertDialog } from "@base-ui/react/alert-dialog";
9
+ // src/alert-dialog/alert-dialog.tsx
10
+ function AlertDialog$1({ onOpenChange, ...props }) {
11
+ const cue = useCue("alert-dialog");
12
+ const opener = useOpener(props.open);
13
+ return /* @__PURE__ */ jsx(OpenerContext.Provider, {
14
+ value: opener,
15
+ children: /* @__PURE__ */ jsx(AlertDialog.Root, {
16
+ "data-slot": "alert-dialog",
17
+ onOpenChange: (open, details) => {
18
+ onOpenChange?.(open, details);
19
+ if (!details.isCanceled) cue(open ? "open" : "close");
20
+ },
21
+ ...props
22
+ })
23
+ });
24
+ }
25
+ function AlertDialogTrigger({ ...props }) {
26
+ return /* @__PURE__ */ jsx(AlertDialog.Trigger, {
27
+ "data-slot": "alert-dialog-trigger",
28
+ ...props
29
+ });
30
+ }
31
+ function AlertDialogPortal({ ...props }) {
32
+ return /* @__PURE__ */ jsx(AlertDialog.Portal, {
33
+ "data-slot": "alert-dialog-portal",
34
+ ...props
35
+ });
36
+ }
37
+ function AlertDialogOverlay({ className, ...props }) {
38
+ return /* @__PURE__ */ jsx(AlertDialog.Backdrop, {
39
+ "data-slot": "alert-dialog-overlay",
40
+ className: cn("fixed inset-0 isolate z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0", className),
41
+ ...props
42
+ });
43
+ }
44
+ function AlertDialogContent({ className, size = "default", ...props }) {
45
+ props.finalFocus = useFinalFocus(props.finalFocus);
46
+ return /* @__PURE__ */ jsxs(AlertDialogPortal, { children: [/* @__PURE__ */ jsx(AlertDialogOverlay, {}), /* @__PURE__ */ jsx(AlertDialog.Popup, {
47
+ "data-slot": "alert-dialog-content",
48
+ "data-size": size,
49
+ className: cn("group/alert-dialog-content fixed top-1/2 left-1/2 z-50 grid w-full -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl bg-popover p-4 text-popover-foreground ring-1 ring-foreground/10 duration-100 outline-none data-[size=default]:max-w-xs data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className),
50
+ ...props
51
+ })] });
52
+ }
53
+ function AlertDialogHeader({ className, ...props }) {
54
+ return /* @__PURE__ */ jsx("div", {
55
+ "data-slot": "alert-dialog-header",
56
+ className: cn("grid grid-rows-[auto_1fr] place-items-center gap-1.5 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-4 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-left sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr]", className),
57
+ ...props
58
+ });
59
+ }
60
+ function AlertDialogFooter({ className, ...props }) {
61
+ return /* @__PURE__ */ jsx("div", {
62
+ "data-slot": "alert-dialog-footer",
63
+ className: cn("-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t bg-muted/50 p-4 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row sm:justify-end", className),
64
+ ...props
65
+ });
66
+ }
67
+ function AlertDialogMedia({ className, ...props }) {
68
+ return /* @__PURE__ */ jsx("div", {
69
+ "data-slot": "alert-dialog-media",
70
+ className: cn("mb-2 inline-flex size-10 items-center justify-center rounded-md bg-muted sm:group-data-[size=default]/alert-dialog-content:row-span-2 *:[svg:not([class*='size-'])]:size-6", className),
71
+ ...props
72
+ });
73
+ }
74
+ function AlertDialogTitle({ className, ...props }) {
75
+ return /* @__PURE__ */ jsx(AlertDialog.Title, {
76
+ "data-slot": "alert-dialog-title",
77
+ className: cn("cn-font-heading text-base font-medium sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2", className),
78
+ ...props
79
+ });
80
+ }
81
+ function AlertDialogDescription({ className, ...props }) {
82
+ return /* @__PURE__ */ jsx(AlertDialog.Description, {
83
+ "data-slot": "alert-dialog-description",
84
+ className: cn("text-sm text-balance text-muted-foreground md:text-pretty *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground", className),
85
+ ...props
86
+ });
87
+ }
88
+ function AlertDialogAction({ className, ...props }) {
89
+ return /* @__PURE__ */ jsx(Button, {
90
+ "data-slot": "alert-dialog-action",
91
+ className: cn(className),
92
+ ...props
93
+ });
94
+ }
95
+ function AlertDialogCancel({ className, variant = "outline", size = "default", ...props }) {
96
+ return /* @__PURE__ */ jsx(AlertDialog.Close, {
97
+ "data-slot": "alert-dialog-cancel",
98
+ className: cn(className),
99
+ render: /* @__PURE__ */ jsx(Button, {
100
+ variant,
101
+ size
102
+ }),
103
+ ...props
104
+ });
105
+ }
106
+ export { AlertDialog$1 as AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogMedia, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger };
@@ -0,0 +1,3 @@
1
+
2
+ import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogMedia, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger } from "./alert-dialog.js";
3
+ export { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogMedia, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger };
@@ -0,0 +1,12 @@
1
+
2
+ import * as React from "react";
3
+ import { Avatar } from "@base-ui/react/avatar";
4
+ declare function Avatar$1({ className, size, ...props }: Avatar.Root.Props & {
5
+ size?: "default" | "sm" | "lg";
6
+ }): React.JSX.Element;
7
+ declare function AvatarImage({ className, ...props }: Avatar.Image.Props): React.JSX.Element;
8
+ declare function AvatarFallback({ className, ...props }: Avatar.Fallback.Props): React.JSX.Element;
9
+ declare function AvatarBadge({ className, ...props }: React.ComponentProps<"span">): React.JSX.Element;
10
+ declare function AvatarGroup({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
11
+ declare function AvatarGroupCount({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
12
+ export { Avatar$1 as Avatar, AvatarBadge, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarImage };
@@ -0,0 +1,50 @@
1
+ "use client";
2
+ "use client";
3
+ import { cn } from "../lib/cn.js";
4
+ import { jsx } from "react/jsx-runtime";
5
+ import { Avatar } from "@base-ui/react/avatar";
6
+ // src/avatar/avatar.tsx
7
+ function Avatar$1({ className, size = "default", ...props }) {
8
+ return /* @__PURE__ */ jsx(Avatar.Root, {
9
+ "data-slot": "avatar",
10
+ "data-size": size,
11
+ className: cn("group/avatar relative flex size-8 shrink-0 rounded-full select-none after:absolute after:inset-0 after:rounded-full after:border after:border-border after:mix-blend-darken data-[size=lg]:size-10 data-[size=sm]:size-6 dark:after:mix-blend-lighten", className),
12
+ ...props
13
+ });
14
+ }
15
+ function AvatarImage({ className, ...props }) {
16
+ return /* @__PURE__ */ jsx(Avatar.Image, {
17
+ "data-slot": "avatar-image",
18
+ className: cn("aspect-square size-full rounded-full object-cover", className),
19
+ ...props
20
+ });
21
+ }
22
+ function AvatarFallback({ className, ...props }) {
23
+ return /* @__PURE__ */ jsx(Avatar.Fallback, {
24
+ "data-slot": "avatar-fallback",
25
+ className: cn("flex size-full items-center justify-center rounded-full bg-muted text-sm text-muted-foreground group-data-[size=sm]/avatar:text-xs", className),
26
+ ...props
27
+ });
28
+ }
29
+ function AvatarBadge({ className, ...props }) {
30
+ return /* @__PURE__ */ jsx("span", {
31
+ "data-slot": "avatar-badge",
32
+ className: cn("absolute right-0 bottom-0 z-10 inline-flex items-center justify-center rounded-full bg-primary text-primary-foreground bg-blend-color ring-2 ring-background select-none", "group-data-[size=sm]/avatar:size-2 group-data-[size=sm]/avatar:[&>svg]:hidden", "group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2", "group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2", className),
33
+ ...props
34
+ });
35
+ }
36
+ function AvatarGroup({ className, ...props }) {
37
+ return /* @__PURE__ */ jsx("div", {
38
+ "data-slot": "avatar-group",
39
+ className: cn("group/avatar-group flex -space-x-2 *:data-[slot=avatar]:ring-2 *:data-[slot=avatar]:ring-background", className),
40
+ ...props
41
+ });
42
+ }
43
+ function AvatarGroupCount({ className, ...props }) {
44
+ return /* @__PURE__ */ jsx("div", {
45
+ "data-slot": "avatar-group-count",
46
+ className: cn("relative flex size-8 shrink-0 items-center justify-center rounded-full bg-muted text-sm text-muted-foreground ring-2 ring-background group-has-data-[size=lg]/avatar-group:size-10 group-has-data-[size=sm]/avatar-group:size-6 [&>svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3", className),
47
+ ...props
48
+ });
49
+ }
50
+ export { Avatar$1 as Avatar, AvatarBadge, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarImage };
@@ -0,0 +1,3 @@
1
+
2
+ import { Avatar, AvatarBadge, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarImage } from "./avatar.js";
3
+ export { Avatar, AvatarBadge, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarImage };
@@ -0,0 +1,8 @@
1
+
2
+ import { VariantProps } from "class-variance-authority";
3
+ import { useRender } from "@base-ui/react/use-render";
4
+ declare const badgeVariants: (props?: ({
5
+ variant?: "default" | "destructive" | "link" | "secondary" | "outline" | "ghost" | null | undefined;
6
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
7
+ declare function Badge({ className, variant, render, ...props }: useRender.ComponentProps<"span"> & VariantProps<typeof badgeVariants>): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
8
+ export { Badge, badgeVariants };
@@ -0,0 +1,29 @@
1
+ "use client";
2
+ import { cn } from "../lib/cn.js";
3
+ import { cva } from "class-variance-authority";
4
+ import { mergeProps } from "@base-ui/react/merge-props";
5
+ import { useRender } from "@base-ui/react/use-render";
6
+ // src/badge/badge.tsx
7
+ const badgeVariants = cva("group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!", {
8
+ variants: { variant: {
9
+ default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
10
+ secondary: "bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80",
11
+ destructive: "bg-destructive/10 text-destructive focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:text-destructive-hover-foreground",
12
+ outline: "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground",
13
+ ghost: "hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",
14
+ link: "text-primary underline-offset-4 hover:underline"
15
+ } },
16
+ defaultVariants: { variant: "default" }
17
+ });
18
+ function Badge({ className, variant = "default", render, ...props }) {
19
+ return useRender({
20
+ defaultTagName: "span",
21
+ props: mergeProps({ className: cn(badgeVariants({ variant }), className) }, props),
22
+ render,
23
+ state: {
24
+ slot: "badge",
25
+ variant
26
+ }
27
+ });
28
+ }
29
+ export { Badge, badgeVariants };
@@ -0,0 +1,3 @@
1
+
2
+ import { Badge, badgeVariants } from "./badge.js";
3
+ export { Badge, badgeVariants };
@@ -0,0 +1,25 @@
1
+
2
+ import { VariantProps } from "class-variance-authority";
3
+ import { Button } from "@base-ui/react/button";
4
+ declare const buttonVariants: (props?: ({
5
+ variant?: "default" | "destructive" | "link" | "secondary" | "outline" | "ghost" | null | undefined;
6
+ size?: "default" | "xs" | "sm" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
7
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
8
+ type LoadingPlacement = "auto" | "start" | "center";
9
+ declare function Button$1({ className, variant, size, loading, loadingLabel, loadingPlacement, children, onClick, onPointerDown, onPointerUp, onPointerLeave, onPointerCancel, ...props }: Button.Props & VariantProps<typeof buttonVariants> & {
10
+ /**
11
+ * Shows the Arc spinner in place of the start icon and ignores presses, keeping focus and the
12
+ * accessible name (`aria-busy`, `data-loading`; not `disabled`).
13
+ */
14
+ loading?: boolean | undefined;
15
+ /** Announced through the spinner while loading. Default "Loading". */
16
+ loadingLabel?: string | undefined;
17
+ /**
18
+ * Where the spinner goes while loading (#130). `start` takes the start icon's place, or sits
19
+ * before the label and the button grows; `center` overlays it and keeps the content's space, so
20
+ * the width never changes. `auto` (default): `start` with a start icon or on an icon size, else
21
+ * `center`. The resolved value is set as `data-loading-placement`.
22
+ */
23
+ loadingPlacement?: LoadingPlacement | undefined;
24
+ }): import("react").JSX.Element;
25
+ export { Button$1 as Button, buttonVariants };
@@ -0,0 +1,136 @@
1
+ "use client";
2
+ import { cn } from "../lib/cn.js";
3
+ import { useCue } from "../sound/sound-map.js";
4
+ import { useControlDefaults } from "../lib/control-defaults.js";
5
+ import { usePress } from "../lib/use-press.js";
6
+ import { Spinner } from "../spinner/spinner.js";
7
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8
+ import { cva } from "class-variance-authority";
9
+ import { Children, isValidElement } from "react";
10
+ import { Button } from "@base-ui/react/button";
11
+ // src/button/button.tsx
12
+ const buttonVariants = cva("group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", {
13
+ variants: {
14
+ variant: {
15
+ default: "bg-primary text-primary-foreground hover:bg-primary/80",
16
+ outline: "border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
17
+ secondary: "bg-secondary text-secondary-foreground hover:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)] aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
18
+ ghost: "hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50",
19
+ destructive: "bg-destructive/10 text-destructive hover:text-destructive-hover-foreground focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40",
20
+ link: "text-primary underline-offset-4 hover:underline"
21
+ },
22
+ size: {
23
+ default: "h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
24
+ xs: "h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3",
25
+ sm: "h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5",
26
+ lg: "h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
27
+ icon: "size-8",
28
+ "icon-xs": "size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3",
29
+ "icon-sm": "size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg",
30
+ "icon-lg": "size-9"
31
+ }
32
+ },
33
+ defaultVariants: {
34
+ variant: "default",
35
+ size: "default"
36
+ }
37
+ });
38
+ const SPINNER_SIZE = {
39
+ default: "md",
40
+ xs: "xs",
41
+ sm: "sm",
42
+ lg: "md",
43
+ icon: "md",
44
+ "icon-xs": "xs",
45
+ "icon-sm": "md",
46
+ "icon-lg": "md"
47
+ };
48
+ function hasStartIcon(children) {
49
+ return Children.toArray(children).some((child) => isValidElement(child) && child.props["data-icon"] === "inline-start");
50
+ }
51
+ /** `auto` (#130): `start` with a start icon or on an icon size, else `center`. */
52
+ function resolvePlacement(placement, children, size) {
53
+ if (placement !== "auto") return placement;
54
+ return size.startsWith("icon") || hasStartIcon(children) ? "start" : "center";
55
+ }
56
+ /**
57
+ * Loading content. `start` (#128): the Arc spinner takes the start icon's place at once, so the
58
+ * width stays the same; icon-only sizes swap their icon; with no start icon it sits before the
59
+ * label and the button grows. `center` (#130): the spinner sits over the middle and the content
60
+ * keeps its place, transparent (opacity, not visibility, so it still names the button).
61
+ */
62
+ function loadingContent(children, size, label, placement) {
63
+ if (placement === "center") return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
64
+ "data-slot": "button-spinner",
65
+ className: "absolute inset-0 flex items-center justify-center",
66
+ children: /* @__PURE__ */ jsx(Spinner, {
67
+ size: SPINNER_SIZE[size],
68
+ label
69
+ })
70
+ }), /* @__PURE__ */ jsx("span", {
71
+ "data-slot": "button-content",
72
+ className: "inline-flex items-center gap-[inherit] opacity-0",
73
+ children
74
+ })] });
75
+ const spinner = /* @__PURE__ */ jsx(Spinner, {
76
+ "data-icon": "inline-start",
77
+ size: SPINNER_SIZE[size],
78
+ label
79
+ }, "spinner");
80
+ if (size.startsWith("icon")) return spinner;
81
+ let swapped = false;
82
+ const rest = Children.map(children, (child) => {
83
+ if (!swapped && isValidElement(child) && child.props["data-icon"] === "inline-start") {
84
+ swapped = true;
85
+ return spinner;
86
+ }
87
+ return child;
88
+ });
89
+ return swapped ? rest : [spinner, ...rest ?? []];
90
+ }
91
+ function Button$1({ className, variant = "default", size = "default", loading = false, loadingLabel = "Loading", loadingPlacement = "auto", children, onClick, onPointerDown, onPointerUp, onPointerLeave, onPointerCancel, ...props }) {
92
+ const press = usePress();
93
+ const cue = useCue("button");
94
+ const { sound = true } = useControlDefaults();
95
+ const placement = loading ? resolvePlacement(loadingPlacement, children, size ?? "default") : null;
96
+ return /* @__PURE__ */ jsx(Button, {
97
+ "data-slot": "button",
98
+ className: cn(buttonVariants({
99
+ variant,
100
+ size
101
+ }), placement === "center" && "relative", className),
102
+ "aria-busy": loading || void 0,
103
+ "data-loading": loading ? "" : void 0,
104
+ "data-loading-placement": placement ?? void 0,
105
+ onPointerDown: (event) => {
106
+ onPointerDown?.(event);
107
+ if (!loading) press.onPointerDown(event);
108
+ },
109
+ onPointerUp: (event) => {
110
+ onPointerUp?.(event);
111
+ press.onPointerUp();
112
+ },
113
+ onPointerLeave: (event) => {
114
+ onPointerLeave?.(event);
115
+ press.onPointerLeave();
116
+ },
117
+ onPointerCancel: (event) => {
118
+ onPointerCancel?.(event);
119
+ press.onPointerCancel();
120
+ },
121
+ onClick: (event) => {
122
+ if (loading) {
123
+ event.preventDefault();
124
+ event.preventBaseUIHandler();
125
+ return;
126
+ }
127
+ onClick?.(event);
128
+ const el = event.currentTarget;
129
+ const trigger = el.hasAttribute("aria-haspopup") || el.hasAttribute("aria-expanded");
130
+ if (sound && !event.defaultPrevented && !trigger) cue("press", { yield: true });
131
+ },
132
+ ...props,
133
+ children: placement ? loadingContent(children, size ?? "default", loadingLabel, placement) : children
134
+ });
135
+ }
136
+ export { Button$1 as Button, buttonVariants };
@@ -0,0 +1,3 @@
1
+
2
+ import { Button, buttonVariants } from "./button.js";
3
+ export { Button, buttonVariants };