@pearpages/pulp-react 0.0.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 (286) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +65 -0
  3. package/dist/ListboxOptions-DLsT-dkV.d.ts +11 -0
  4. package/dist/ToggleField-C-qKSgHh.d.ts +3 -0
  5. package/dist/accordion.css +90 -0
  6. package/dist/accordion.css.map +1 -0
  7. package/dist/accordion.d.ts +71 -0
  8. package/dist/accordion.js +6 -0
  9. package/dist/accordion.js.map +1 -0
  10. package/dist/alert.css +246 -0
  11. package/dist/alert.css.map +1 -0
  12. package/dist/alert.d.ts +46 -0
  13. package/dist/alert.js +10 -0
  14. package/dist/alert.js.map +1 -0
  15. package/dist/badge.css +89 -0
  16. package/dist/badge.css.map +1 -0
  17. package/dist/badge.d.ts +38 -0
  18. package/dist/badge.js +5 -0
  19. package/dist/badge.js.map +1 -0
  20. package/dist/button.css +162 -0
  21. package/dist/button.css.map +1 -0
  22. package/dist/button.d.ts +61 -0
  23. package/dist/button.js +8 -0
  24. package/dist/button.js.map +1 -0
  25. package/dist/calendar.css +128 -0
  26. package/dist/calendar.css.map +1 -0
  27. package/dist/calendar.d.ts +48 -0
  28. package/dist/calendar.js +6 -0
  29. package/dist/calendar.js.map +1 -0
  30. package/dist/card.css +66 -0
  31. package/dist/card.css.map +1 -0
  32. package/dist/card.d.ts +69 -0
  33. package/dist/card.js +5 -0
  34. package/dist/card.js.map +1 -0
  35. package/dist/checkbox.css +106 -0
  36. package/dist/checkbox.css.map +1 -0
  37. package/dist/checkbox.d.ts +41 -0
  38. package/dist/checkbox.js +7 -0
  39. package/dist/checkbox.js.map +1 -0
  40. package/dist/chunk-2PXTVZ7H.js +95 -0
  41. package/dist/chunk-2PXTVZ7H.js.map +1 -0
  42. package/dist/chunk-2ZP4ZBI5.js +43 -0
  43. package/dist/chunk-2ZP4ZBI5.js.map +1 -0
  44. package/dist/chunk-3GWESUGD.js +28 -0
  45. package/dist/chunk-3GWESUGD.js.map +1 -0
  46. package/dist/chunk-4HRNRTXI.js +25 -0
  47. package/dist/chunk-4HRNRTXI.js.map +1 -0
  48. package/dist/chunk-5SBKZS56.js +56 -0
  49. package/dist/chunk-5SBKZS56.js.map +1 -0
  50. package/dist/chunk-6I26MMQF.js +19 -0
  51. package/dist/chunk-6I26MMQF.js.map +1 -0
  52. package/dist/chunk-75GTNRBH.js +45 -0
  53. package/dist/chunk-75GTNRBH.js.map +1 -0
  54. package/dist/chunk-7DS4I7OJ.js +30 -0
  55. package/dist/chunk-7DS4I7OJ.js.map +1 -0
  56. package/dist/chunk-ASNTNTJW.js +27 -0
  57. package/dist/chunk-ASNTNTJW.js.map +1 -0
  58. package/dist/chunk-ASOQ2MVR.js +19 -0
  59. package/dist/chunk-ASOQ2MVR.js.map +1 -0
  60. package/dist/chunk-AWQHULJC.js +31 -0
  61. package/dist/chunk-AWQHULJC.js.map +1 -0
  62. package/dist/chunk-BBV4L5WO.js +43 -0
  63. package/dist/chunk-BBV4L5WO.js.map +1 -0
  64. package/dist/chunk-CZBCGLEM.js +9 -0
  65. package/dist/chunk-CZBCGLEM.js.map +1 -0
  66. package/dist/chunk-DWE374JX.js +65 -0
  67. package/dist/chunk-DWE374JX.js.map +1 -0
  68. package/dist/chunk-DXOOW6Q6.js +159 -0
  69. package/dist/chunk-DXOOW6Q6.js.map +1 -0
  70. package/dist/chunk-F3OFZGGE.js +116 -0
  71. package/dist/chunk-F3OFZGGE.js.map +1 -0
  72. package/dist/chunk-FH54XQ35.js +125 -0
  73. package/dist/chunk-FH54XQ35.js.map +1 -0
  74. package/dist/chunk-FXRSZUDH.js +38 -0
  75. package/dist/chunk-FXRSZUDH.js.map +1 -0
  76. package/dist/chunk-GTTXRDXV.js +181 -0
  77. package/dist/chunk-GTTXRDXV.js.map +1 -0
  78. package/dist/chunk-I4KC4V6A.js +31 -0
  79. package/dist/chunk-I4KC4V6A.js.map +1 -0
  80. package/dist/chunk-I5OZ63W7.js +50 -0
  81. package/dist/chunk-I5OZ63W7.js.map +1 -0
  82. package/dist/chunk-IDNGNQNV.js +41 -0
  83. package/dist/chunk-IDNGNQNV.js.map +1 -0
  84. package/dist/chunk-J5S2HVHO.js +67 -0
  85. package/dist/chunk-J5S2HVHO.js.map +1 -0
  86. package/dist/chunk-K5QGGQOV.js +84 -0
  87. package/dist/chunk-K5QGGQOV.js.map +1 -0
  88. package/dist/chunk-KPQGS4PG.js +77 -0
  89. package/dist/chunk-KPQGS4PG.js.map +1 -0
  90. package/dist/chunk-MI4QUKQS.js +8 -0
  91. package/dist/chunk-MI4QUKQS.js.map +1 -0
  92. package/dist/chunk-MRQWUCBA.js +57 -0
  93. package/dist/chunk-MRQWUCBA.js.map +1 -0
  94. package/dist/chunk-MXWXJZFS.js +48 -0
  95. package/dist/chunk-MXWXJZFS.js.map +1 -0
  96. package/dist/chunk-N7L66GMG.js +129 -0
  97. package/dist/chunk-N7L66GMG.js.map +1 -0
  98. package/dist/chunk-NAYFLTK6.js +32 -0
  99. package/dist/chunk-NAYFLTK6.js.map +1 -0
  100. package/dist/chunk-O6OBFL3Q.js +155 -0
  101. package/dist/chunk-O6OBFL3Q.js.map +1 -0
  102. package/dist/chunk-OGIQRHNF.js +52 -0
  103. package/dist/chunk-OGIQRHNF.js.map +1 -0
  104. package/dist/chunk-OUFAFINB.js +45 -0
  105. package/dist/chunk-OUFAFINB.js.map +1 -0
  106. package/dist/chunk-OXYP34CG.js +43 -0
  107. package/dist/chunk-OXYP34CG.js.map +1 -0
  108. package/dist/chunk-P5C2U5ZF.js +73 -0
  109. package/dist/chunk-P5C2U5ZF.js.map +1 -0
  110. package/dist/chunk-PM4YO67Q.js +53 -0
  111. package/dist/chunk-PM4YO67Q.js.map +1 -0
  112. package/dist/chunk-Q6J6BMSB.js +86 -0
  113. package/dist/chunk-Q6J6BMSB.js.map +1 -0
  114. package/dist/chunk-T76YSNTZ.js +33 -0
  115. package/dist/chunk-T76YSNTZ.js.map +1 -0
  116. package/dist/chunk-TGMDOQCL.js +53 -0
  117. package/dist/chunk-TGMDOQCL.js.map +1 -0
  118. package/dist/chunk-TVI5AXLE.js +41 -0
  119. package/dist/chunk-TVI5AXLE.js.map +1 -0
  120. package/dist/chunk-U6QRAD73.js +22 -0
  121. package/dist/chunk-U6QRAD73.js.map +1 -0
  122. package/dist/chunk-UX42PQLT.js +76 -0
  123. package/dist/chunk-UX42PQLT.js.map +1 -0
  124. package/dist/chunk-XDVS7HX7.js +100 -0
  125. package/dist/chunk-XDVS7HX7.js.map +1 -0
  126. package/dist/chunk-Y4TZA77G.js +57 -0
  127. package/dist/chunk-Y4TZA77G.js.map +1 -0
  128. package/dist/chunk-YUHS5S5Y.js +12 -0
  129. package/dist/chunk-YUHS5S5Y.js.map +1 -0
  130. package/dist/chunk-Z4PN6B2C.js +17 -0
  131. package/dist/chunk-Z4PN6B2C.js.map +1 -0
  132. package/dist/chunk-ZVDN3GRI.js +49 -0
  133. package/dist/chunk-ZVDN3GRI.js.map +1 -0
  134. package/dist/combobox.css +280 -0
  135. package/dist/combobox.css.map +1 -0
  136. package/dist/combobox.d.ts +75 -0
  137. package/dist/combobox.js +10 -0
  138. package/dist/combobox.js.map +1 -0
  139. package/dist/component-manifest.json +3370 -0
  140. package/dist/date-picker.css +267 -0
  141. package/dist/date-picker.css.map +1 -0
  142. package/dist/date-picker.d.ts +59 -0
  143. package/dist/date-picker.js +8 -0
  144. package/dist/date-picker.js.map +1 -0
  145. package/dist/dialog.css +62 -0
  146. package/dist/dialog.css.map +1 -0
  147. package/dist/dialog.d.ts +56 -0
  148. package/dist/dialog.js +3 -0
  149. package/dist/dialog.js.map +1 -0
  150. package/dist/field.css +28 -0
  151. package/dist/field.css.map +1 -0
  152. package/dist/field.d.ts +98 -0
  153. package/dist/field.js +5 -0
  154. package/dist/field.js.map +1 -0
  155. package/dist/floating-Bw-LN_QT.d.ts +5 -0
  156. package/dist/heading.css +30 -0
  157. package/dist/heading.css.map +1 -0
  158. package/dist/heading.d.ts +316 -0
  159. package/dist/heading.js +4 -0
  160. package/dist/heading.js.map +1 -0
  161. package/dist/icon-button.css +177 -0
  162. package/dist/icon-button.css.map +1 -0
  163. package/dist/icon-button.d.ts +29 -0
  164. package/dist/icon-button.js +9 -0
  165. package/dist/icon-button.js.map +1 -0
  166. package/dist/icon.css +25 -0
  167. package/dist/icon.css.map +1 -0
  168. package/dist/icon.d.ts +33 -0
  169. package/dist/icon.js +4 -0
  170. package/dist/icon.js.map +1 -0
  171. package/dist/index.css +2345 -0
  172. package/dist/index.css.map +1 -0
  173. package/dist/index.d.ts +42 -0
  174. package/dist/index.js +49 -0
  175. package/dist/index.js.map +1 -0
  176. package/dist/inline.css +63 -0
  177. package/dist/inline.css.map +1 -0
  178. package/dist/inline.d.ts +322 -0
  179. package/dist/inline.js +4 -0
  180. package/dist/inline.js.map +1 -0
  181. package/dist/listbox.css +95 -0
  182. package/dist/listbox.css.map +1 -0
  183. package/dist/listbox.d.ts +47 -0
  184. package/dist/listbox.js +7 -0
  185. package/dist/listbox.js.map +1 -0
  186. package/dist/menu.css +102 -0
  187. package/dist/menu.css.map +1 -0
  188. package/dist/menu.d.ts +76 -0
  189. package/dist/menu.js +9 -0
  190. package/dist/menu.js.map +1 -0
  191. package/dist/pagination.css +212 -0
  192. package/dist/pagination.css.map +1 -0
  193. package/dist/pagination.d.ts +52 -0
  194. package/dist/pagination.js +10 -0
  195. package/dist/pagination.js.map +1 -0
  196. package/dist/picker.css +209 -0
  197. package/dist/picker.css.map +1 -0
  198. package/dist/picker.d.ts +57 -0
  199. package/dist/picker.js +8 -0
  200. package/dist/picker.js.map +1 -0
  201. package/dist/popover.css +48 -0
  202. package/dist/popover.css.map +1 -0
  203. package/dist/popover.d.ts +68 -0
  204. package/dist/popover.js +7 -0
  205. package/dist/popover.js.map +1 -0
  206. package/dist/progress.css +83 -0
  207. package/dist/progress.css.map +1 -0
  208. package/dist/progress.d.ts +40 -0
  209. package/dist/progress.js +5 -0
  210. package/dist/progress.js.map +1 -0
  211. package/dist/radio.css +107 -0
  212. package/dist/radio.css.map +1 -0
  213. package/dist/radio.d.ts +68 -0
  214. package/dist/radio.js +6 -0
  215. package/dist/radio.js.map +1 -0
  216. package/dist/select.css +98 -0
  217. package/dist/select.css.map +1 -0
  218. package/dist/select.d.ts +39 -0
  219. package/dist/select.js +6 -0
  220. package/dist/select.js.map +1 -0
  221. package/dist/skeleton.css +59 -0
  222. package/dist/skeleton.css.map +1 -0
  223. package/dist/skeleton.d.ts +34 -0
  224. package/dist/skeleton.js +4 -0
  225. package/dist/skeleton.js.map +1 -0
  226. package/dist/slider.css +126 -0
  227. package/dist/slider.css.map +1 -0
  228. package/dist/slider.d.ts +61 -0
  229. package/dist/slider.js +5 -0
  230. package/dist/slider.js.map +1 -0
  231. package/dist/spinner.css +60 -0
  232. package/dist/spinner.css.map +1 -0
  233. package/dist/spinner.d.ts +34 -0
  234. package/dist/spinner.js +5 -0
  235. package/dist/spinner.js.map +1 -0
  236. package/dist/stack.css +60 -0
  237. package/dist/stack.css.map +1 -0
  238. package/dist/stack.d.ts +319 -0
  239. package/dist/stack.js +4 -0
  240. package/dist/stack.js.map +1 -0
  241. package/dist/switch.css +97 -0
  242. package/dist/switch.css.map +1 -0
  243. package/dist/switch.d.ts +35 -0
  244. package/dist/switch.js +7 -0
  245. package/dist/switch.js.map +1 -0
  246. package/dist/table.css +188 -0
  247. package/dist/table.css.map +1 -0
  248. package/dist/table.d.ts +137 -0
  249. package/dist/table.js +6 -0
  250. package/dist/table.js.map +1 -0
  251. package/dist/tabs.css +75 -0
  252. package/dist/tabs.css.map +1 -0
  253. package/dist/tabs.d.ts +73 -0
  254. package/dist/tabs.js +5 -0
  255. package/dist/tabs.js.map +1 -0
  256. package/dist/text-field.css +75 -0
  257. package/dist/text-field.css.map +1 -0
  258. package/dist/text-field.d.ts +43 -0
  259. package/dist/text-field.js +6 -0
  260. package/dist/text-field.js.map +1 -0
  261. package/dist/text.css +53 -0
  262. package/dist/text.css.map +1 -0
  263. package/dist/text.d.ts +331 -0
  264. package/dist/text.js +4 -0
  265. package/dist/text.js.map +1 -0
  266. package/dist/textarea.css +84 -0
  267. package/dist/textarea.css.map +1 -0
  268. package/dist/textarea.d.ts +40 -0
  269. package/dist/textarea.js +6 -0
  270. package/dist/textarea.js.map +1 -0
  271. package/dist/toast.css +300 -0
  272. package/dist/toast.css.map +1 -0
  273. package/dist/toast.d.ts +60 -0
  274. package/dist/toast.js +11 -0
  275. package/dist/toast.js.map +1 -0
  276. package/dist/tooltip.css +36 -0
  277. package/dist/tooltip.css.map +1 -0
  278. package/dist/tooltip.d.ts +34 -0
  279. package/dist/tooltip.js +5 -0
  280. package/dist/tooltip.js.map +1 -0
  281. package/dist/visually-hidden.css +15 -0
  282. package/dist/visually-hidden.css.map +1 -0
  283. package/dist/visually-hidden.d.ts +308 -0
  284. package/dist/visually-hidden.js +4 -0
  285. package/dist/visually-hidden.js.map +1 -0
  286. package/package.json +261 -0
@@ -0,0 +1,45 @@
1
+ import { VisuallyHidden } from './chunk-Z4PN6B2C.js';
2
+ import { classes } from './chunk-MI4QUKQS.js';
3
+ import { useId } from 'react';
4
+ import { jsxs, jsx } from 'react/jsx-runtime';
5
+
6
+ // src/progress/Progress.module.css
7
+ var Progress_default = {
8
+ progress: "Progress_progress",
9
+ header: "Progress_header",
10
+ label: "Progress_label",
11
+ value: "Progress_value",
12
+ track: "Progress_track",
13
+ indicator: "Progress_indicator"};
14
+ function Progress({ value, max = 100, label, hideLabel = false, valueText, tone = "primary", size = "md", className, ref, ...rest }) {
15
+ const id = useId();
16
+ const labelId = `${id}-label`;
17
+ const indeterminate = value === void 0;
18
+ const percent = indeterminate ? 0 : Math.min(100, Math.max(0, value / max * 100));
19
+ const text = indeterminate ? void 0 : valueText ?? `${Math.round(percent)}%`;
20
+ const fill = { "--_value": `${percent}%` };
21
+ return /* @__PURE__ */ jsxs("div", { ...rest, ref, className: classes(Progress_default.progress, className), "data-size": size, "data-tone": tone, "data-indeterminate": indeterminate ? "" : void 0, children: [
22
+ /* @__PURE__ */ jsxs("div", { className: Progress_default.header, children: [
23
+ hideLabel ? /* @__PURE__ */ jsx(VisuallyHidden, { id: labelId, children: label }) : /* @__PURE__ */ jsx("span", { id: labelId, className: Progress_default.label, children: label }),
24
+ text && !hideLabel && /* @__PURE__ */ jsx("span", { className: Progress_default.value, children: text })
25
+ ] }),
26
+ /* @__PURE__ */ jsx(
27
+ "div",
28
+ {
29
+ role: "progressbar",
30
+ "aria-labelledby": labelId,
31
+ "aria-valuemin": 0,
32
+ "aria-valuemax": max,
33
+ "aria-valuenow": indeterminate ? void 0 : value,
34
+ "aria-valuetext": text,
35
+ className: Progress_default.track,
36
+ children: /* @__PURE__ */ jsx("div", { className: Progress_default.indicator, style: fill })
37
+ }
38
+ )
39
+ ] });
40
+ }
41
+ Progress.displayName = "Progress";
42
+
43
+ export { Progress };
44
+ //# sourceMappingURL=chunk-75GTNRBH.js.map
45
+ //# sourceMappingURL=chunk-75GTNRBH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/progress/Progress.module.css","../src/progress/Progress.tsx"],"names":["progress","header","label","value","track","indicator"],"mappings":";;;;;;AAAA,IAAA,gBAAA,GAAA;AAAA,EAGG,QAAA,EAAAA,mBAAAA;AAAA,EAeA,MAAA,EAAAC,iBAAAA;AAAA,EAOA,KAAA,EAAAC,gBAAAA;AAAA,EAIA,KAAA,EAAAC,gBAAAA;AAAA,EAKA,KAAA,EAAAC,gBAAAA;AAAA,EAOA,SAAA,EAAAC,oBAUY,CAAA;ACbR,SAAS,SAAS,EAAE,KAAA,EAAO,GAAA,GAAM,GAAA,EAAK,OAAO,SAAA,GAAY,KAAA,EAAO,SAAA,EAAW,IAAA,GAAO,WAAW,IAAA,GAAO,IAAA,EAAM,WAAW,GAAA,EAAK,GAAG,MAAK,EAAkB;AACzJ,EAAA,MAAM,KAAK,KAAA,EAAM;AACjB,EAAA,MAAM,OAAA,GAAU,GAAG,EAAE,CAAA,MAAA,CAAA;AACrB,EAAA,MAAM,gBAAgB,KAAA,KAAU,MAAA;AAChC,EAAA,MAAM,OAAA,GAAU,aAAA,GAAgB,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,GAAA,EAAK,IAAA,CAAK,GAAA,CAAI,CAAA,EAAI,KAAA,GAAQ,GAAA,GAAO,GAAG,CAAC,CAAA;AAClF,EAAA,MAAM,IAAA,GAAO,gBAAgB,MAAA,GAAa,SAAA,IAAa,GAAG,IAAA,CAAK,KAAA,CAAM,OAAO,CAAC,CAAA,CAAA,CAAA;AAE7E,EAAA,MAAM,IAAA,GAAO,EAAE,UAAA,EAAY,CAAA,EAAG,OAAO,CAAA,CAAA,CAAA,EAAI;AAEzC,EAAA,4BACG,KAAA,EAAA,EAAK,GAAG,MAAM,GAAA,EAAU,SAAA,EAAW,QAAQ,gBAAA,CAAO,QAAA,EAAU,SAAS,CAAA,EAAG,aAAW,IAAA,EAAM,WAAA,EAAW,MAAM,oBAAA,EAAoB,aAAA,GAAgB,KAAK,MAAA,EAClJ,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,gBAAA,CAAO,MAAA,EACpB,QAAA,EAAA;AAAA,MAAA,SAAA,mBACC,GAAA,CAAC,cAAA,EAAA,EAAe,EAAA,EAAI,OAAA,EAAU,QAAA,EAAA,KAAA,EAAM,CAAA,mBAEpC,GAAA,CAAC,MAAA,EAAA,EAAK,EAAA,EAAI,OAAA,EAAS,SAAA,EAAW,gBAAA,CAAO,OAClC,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,MAED,IAAA,IAAQ,CAAC,SAAA,oBAAa,GAAA,CAAC,UAAK,SAAA,EAAW,gBAAA,CAAO,OAAQ,QAAA,EAAA,IAAA,EAAK;AAAA,KAAA,EAC9D,CAAA;AAAA,oBACA,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,aAAA;AAAA,QACL,iBAAA,EAAiB,OAAA;AAAA,QACjB,eAAA,EAAe,CAAA;AAAA,QACf,eAAA,EAAe,GAAA;AAAA,QACf,eAAA,EAAe,gBAAgB,MAAA,GAAY,KAAA;AAAA,QAC3C,gBAAA,EAAgB,IAAA;AAAA,QAChB,WAAW,gBAAA,CAAO,KAAA;AAAA,QAGlB,8BAAC,KAAA,EAAA,EAAI,SAAA,EAAW,gBAAA,CAAO,SAAA,EAAW,OAAO,IAAA,EAAM;AAAA;AAAA;AACjD,GAAA,EACF,CAAA;AAEJ;AAEA,QAAA,CAAS,WAAA,GAAc,UAAA","file":"chunk-75GTNRBH.js","sourcesContent":["/* Every value is a token (--progress-*). The fill width is the per-instance --_value custom property. */\n\n@layer components {\n .progress {\n --_height: var(--progress-height-md);\n --_indicator: var(--progress-indicator-primary);\n\n display: flex;\n flex-direction: column;\n gap: var(--progress-gap);\n font-family: var(--font-family-body);\n\n &[data-size=\"sm\"] { --_height: var(--progress-height-sm); }\n &[data-tone=\"success\"] { --_indicator: var(--progress-indicator-success); }\n &[data-tone=\"warning\"] { --_indicator: var(--progress-indicator-warning); }\n &[data-tone=\"error\"] { --_indicator: var(--progress-indicator-error); }\n }\n\n .header {\n display: flex;\n justify-content: space-between;\n gap: var(--space-3);\n font-size: var(--progress-label-font-size);\n }\n\n .label {\n color: var(--progress-label-fg);\n }\n\n .value {\n color: var(--progress-value-fg);\n font-variant-numeric: tabular-nums;\n }\n\n .track {\n overflow: hidden;\n block-size: var(--_height);\n border-radius: var(--progress-radius);\n background-color: var(--progress-track);\n }\n\n .indicator {\n block-size: 100%;\n inline-size: var(--_value, 0%);\n border-radius: var(--progress-radius);\n background-color: var(--_indicator);\n transition: inline-size var(--progress-duration) var(--motion-easing-standard);\n }\n\n .progress[data-indeterminate] .indicator {\n inline-size: 40%;\n animation: slide calc(4 * var(--progress-duration)) var(--motion-easing-standard) infinite;\n }\n\n @keyframes slide {\n from {\n translate: -100% 0;\n }\n\n to {\n translate: 250% 0;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .progress[data-indeterminate] .indicator {\n inline-size: 50%;\n animation: none;\n }\n }\n}\n","import { useId, type CSSProperties, type HTMLAttributes, type ReactNode, type Ref } from 'react';\nimport { classes } from '../internal/classes';\nimport { VisuallyHidden } from '../visually-hidden';\nimport styles from './Progress.module.css';\n\nexport type ProgressTone = 'primary' | 'success' | 'warning' | 'error';\nexport type ProgressSize = 'sm' | 'md';\n\nexport interface ProgressProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {\n /** Current value; omit for indeterminate. */\n value?: number;\n /** @default 100 */\n max?: number;\n /** Required: what is progressing. Visible unless `hideLabel`. */\n label: ReactNode;\n /** Keep the label for assistive technology only. @default false */\n hideLabel?: boolean;\n /** Human-readable value (\"3 of 10 files\"); defaults to a percentage. */\n valueText?: string;\n /** @default 'primary' */\n tone?: ProgressTone;\n /** @default 'md' */\n size?: ProgressSize;\n ref?: Ref<HTMLDivElement>;\n}\n\n/**\n * A determinate or indeterminate progress bar. The bar is `role=\"progressbar\"`\n * labelled by the visible (or visually hidden) label; the fill width is the\n * one place in the library that carries a per-instance inline value, set as\n * a custom property. Indeterminate motion stops under reduced motion.\n *\n * @status stable\n * @category Feedback\n * @accessibility `role=\"progressbar\"` labelled by the required `label` (visible or visually hidden), with `aria-valuenow`/`aria-valuemin`/`aria-valuemax` when determinate and `aria-valuetext` from `valueText`. Indeterminate bars omit `aria-valuenow`.\n * @do Set `valueText` when the percentage is not the meaningful reading (\"3 of 5 files\").\n * @dont Use it for an unknown wait shorter than a few seconds; use Spinner.\n */\nexport function Progress({ value, max = 100, label, hideLabel = false, valueText, tone = 'primary', size = 'md', className, ref, ...rest }: ProgressProps) {\n const id = useId();\n const labelId = `${id}-label`;\n const indeterminate = value === undefined;\n const percent = indeterminate ? 0 : Math.min(100, Math.max(0, (value / max) * 100));\n const text = indeterminate ? undefined : (valueText ?? `${Math.round(percent)}%`);\n // The single per-instance value the bar needs. A stylesheet cannot enumerate percentages.\n const fill = { '--_value': `${percent}%` } as CSSProperties;\n\n return (\n <div {...rest} ref={ref} className={classes(styles.progress, className)} data-size={size} data-tone={tone} data-indeterminate={indeterminate ? '' : undefined}>\n <div className={styles.header}>\n {hideLabel ? (\n <VisuallyHidden id={labelId}>{label}</VisuallyHidden>\n ) : (\n <span id={labelId} className={styles.label}>\n {label}\n </span>\n )}\n {text && !hideLabel && <span className={styles.value}>{text}</span>}\n </div>\n <div\n role=\"progressbar\"\n aria-labelledby={labelId}\n aria-valuemin={0}\n aria-valuemax={max}\n aria-valuenow={indeterminate ? undefined : value}\n aria-valuetext={text}\n className={styles.track}\n >\n {/* eslint-disable-next-line react/forbid-dom-props -- per-instance fill width, see the component JSDoc */}\n <div className={styles.indicator} style={fill} />\n </div>\n </div>\n );\n}\n\nProgress.displayName = 'Progress';\n"]}
@@ -0,0 +1,30 @@
1
+ import { classes } from './chunk-MI4QUKQS.js';
2
+ import { createElement } from 'react';
3
+
4
+ // src/stack/Stack.module.css
5
+ var Stack_default = {
6
+ stack: "Stack_stack"
7
+ };
8
+
9
+ // src/stack/Stack.tsx
10
+ function Stack({ as = "div", gap = 3, align, justify, className, ref, children, ...rest }) {
11
+ return createElement(
12
+ as,
13
+ {
14
+ ...rest,
15
+ ref,
16
+ // Safari drops list semantics when list-style is none; say it explicitly.
17
+ role: rest.role ?? (as === "ul" || as === "ol" ? "list" : void 0),
18
+ className: classes(Stack_default.stack, className),
19
+ "data-gap": gap,
20
+ "data-align": align,
21
+ "data-justify": justify
22
+ },
23
+ children
24
+ );
25
+ }
26
+ Stack.displayName = "Stack";
27
+
28
+ export { Stack };
29
+ //# sourceMappingURL=chunk-7DS4I7OJ.js.map
30
+ //# sourceMappingURL=chunk-7DS4I7OJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/stack/Stack.module.css","../src/stack/Stack.tsx"],"names":["stack"],"mappings":";;;;AAAA,IAAA,aAAA,GAAA;AAAA,EAGG,KAAA,EAAAA;AAAA,CAAA;;;AC8BI,SAAS,KAAA,CAAM,EAAE,EAAA,GAAK,KAAA,EAAO,GAAA,GAAM,CAAA,EAAG,KAAA,EAAO,OAAA,EAAS,SAAA,EAAW,GAAA,EAAK,QAAA,EAAU,GAAG,MAAK,EAAe;AAC5G,EAAA,OAAO,aAAA;AAAA,IACL,EAAA;AAAA,IACA;AAAA,MACE,GAAG,IAAA;AAAA,MACH,GAAA;AAAA;AAAA,MAEA,MAAM,IAAA,CAAK,IAAA,KAAS,OAAO,IAAA,IAAQ,EAAA,KAAO,OAAO,MAAA,GAAS,MAAA,CAAA;AAAA,MAC1D,SAAA,EAAW,OAAA,CAAQ,aAAA,CAAO,KAAA,EAAO,SAAS,CAAA;AAAA,MAC1C,UAAA,EAAY,GAAA;AAAA,MACZ,YAAA,EAAc,KAAA;AAAA,MACd,cAAA,EAAgB;AAAA,KAElB;AAAA,IACA;AAAA,GACF;AACF;AAEA,KAAA,CAAM,WAAA,GAAc,OAAA","file":"chunk-7DS4I7OJ.js","sourcesContent":["/* Every value is a token (--stack-gap-*). Gap, alignment and justification are data attributes. */\n\n@layer components {\n .stack {\n display: flex;\n flex-direction: column;\n gap: var(--stack-gap-3);\n margin: 0;\n padding: 0;\n list-style: none;\n\n &[data-gap=\"1\"] { gap: var(--stack-gap-1); }\n &[data-gap=\"2\"] { gap: var(--stack-gap-2); }\n &[data-gap=\"3\"] { gap: var(--stack-gap-3); }\n &[data-gap=\"4\"] { gap: var(--stack-gap-4); }\n &[data-gap=\"5\"] { gap: var(--stack-gap-5); }\n &[data-gap=\"6\"] { gap: var(--stack-gap-6); }\n &[data-gap=\"7\"] { gap: var(--stack-gap-7); }\n &[data-gap=\"8\"] { gap: var(--stack-gap-8); }\n &[data-align=\"start\"] { align-items: flex-start; }\n &[data-align=\"center\"] { align-items: center; }\n &[data-align=\"end\"] { align-items: flex-end; }\n &[data-align=\"stretch\"] { align-items: stretch; }\n &[data-justify=\"start\"] { justify-content: flex-start; }\n &[data-justify=\"center\"] { justify-content: center; }\n &[data-justify=\"end\"] { justify-content: flex-end; }\n &[data-justify=\"between\"] { justify-content: space-between; }\n }\n}\n","import { createElement, type HTMLAttributes, type ReactNode, type Ref } from 'react';\nimport { classes } from '../internal/classes';\nimport styles from './Stack.module.css';\n\nexport type StackGap = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;\nexport type StackAlign = 'start' | 'center' | 'end' | 'stretch';\nexport type StackJustify = 'start' | 'center' | 'end' | 'between';\nexport type StackElement = 'div' | 'section' | 'nav' | 'ul' | 'ol' | 'li';\n\nexport interface StackProps extends HTMLAttributes<HTMLElement> {\n /** @default 'div' */\n as?: StackElement;\n /** Step on the spacing scale (`--space-1` … `--space-8`). @default 3 */\n gap?: StackGap;\n align?: StackAlign;\n justify?: StackJustify;\n\n ref?: Ref<HTMLElement>;\n children: ReactNode;\n}\n\n/**\n * A flex column whose gap is a step on the spacing scale, so consumers\n * compose layout from tokens instead of writing padding and margins.\n * Rendered as `ul`/`ol` it keeps `role=\"list\"` explicitly, because Safari\n * stops announcing a list once `list-style` is removed.\n *\n * @status stable\n * @category Layout\n * @accessibility Layout only: no role unless rendered as `ul`/`ol`, where `role=\"list\"` is kept explicitly because Safari drops list semantics without markers.\n * @do Use `as=\"ul\"` for a list of like items so the count is announced.\n * @dont Use it to space unrelated regions; it is one flex column.\n */\nexport function Stack({ as = 'div', gap = 3, align, justify, className, ref, children, ...rest }: StackProps) {\n return createElement(\n as,\n {\n ...rest,\n ref,\n // Safari drops list semantics when list-style is none; say it explicitly.\n role: rest.role ?? (as === 'ul' || as === 'ol' ? 'list' : undefined),\n className: classes(styles.stack, className),\n 'data-gap': gap,\n 'data-align': align,\n 'data-justify': justify,\n\n },\n children,\n );\n}\n\nStack.displayName = 'Stack';\n"]}
@@ -0,0 +1,27 @@
1
+ import { classes } from './chunk-MI4QUKQS.js';
2
+ import { jsx } from 'react/jsx-runtime';
3
+
4
+ // src/icon/Icon.module.css
5
+ var Icon_default = {
6
+ icon: "Icon_icon"
7
+ };
8
+ function Icon({ children, size = "md", label, className, ref, ...rest }) {
9
+ return /* @__PURE__ */ jsx(
10
+ "span",
11
+ {
12
+ ...rest,
13
+ ref,
14
+ className: classes(Icon_default.icon, className),
15
+ "data-size": size,
16
+ role: label ? "img" : void 0,
17
+ "aria-label": label,
18
+ "aria-hidden": label ? void 0 : true,
19
+ children
20
+ }
21
+ );
22
+ }
23
+ Icon.displayName = "Icon";
24
+
25
+ export { Icon };
26
+ //# sourceMappingURL=chunk-ASNTNTJW.js.map
27
+ //# sourceMappingURL=chunk-ASNTNTJW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/icon/Icon.module.css","../src/icon/Icon.tsx"],"names":["icon"],"mappings":";;;;AAAA,IAAA,YAAA,GAAA;AAAA,EAGG,IAAA,EAAAA;AAAA,CAAA;AC2BI,SAAS,IAAA,CAAK,EAAE,QAAA,EAAU,IAAA,GAAO,IAAA,EAAM,OAAO,SAAA,EAAW,GAAA,EAAK,GAAG,IAAA,EAAK,EAAc;AACzF,EAAA,uBACE,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACE,GAAG,IAAA;AAAA,MACJ,GAAA;AAAA,MACA,SAAA,EAAW,OAAA,CAAQ,YAAA,CAAO,IAAA,EAAM,SAAS,CAAA;AAAA,MACzC,WAAA,EAAW,IAAA;AAAA,MACX,IAAA,EAAM,QAAQ,KAAA,GAAQ,MAAA;AAAA,MACtB,YAAA,EAAY,KAAA;AAAA,MACZ,aAAA,EAAa,QAAQ,MAAA,GAAY,IAAA;AAAA,MAEhC;AAAA;AAAA,GACH;AAEJ;AAEA,IAAA,CAAK,WAAA,GAAc,MAAA","file":"chunk-ASNTNTJW.js","sourcesContent":["/* Every value is a token (--icon-*). The child SVG fills the box; colour is currentColor. */\n\n@layer components {\n .icon {\n display: inline-flex;\n flex: none;\n inline-size: 1em;\n block-size: 1em;\n font-size: var(--icon-size-md);\n vertical-align: middle;\n\n &[data-size=\"sm\"] { font-size: var(--icon-size-sm); }\n &[data-size=\"lg\"] { font-size: var(--icon-size-lg); }\n &[data-size=\"inherit\"] { font-size: inherit; }\n\n & > * {\n inline-size: 100%;\n block-size: 100%;\n }\n }\n}\n","import type { HTMLAttributes, ReactNode, Ref } from 'react';\nimport { classes } from '../internal/classes';\nimport styles from './Icon.module.css';\n\nexport type IconSize = 'sm' | 'md' | 'lg';\n\nexport interface IconProps extends Omit<HTMLAttributes<HTMLSpanElement>, 'children'> {\n /** Any SVG (for instance from `@pearpages/pulp-icons`); it is sized to the icon box. */\n children: ReactNode;\n /** `inherit` follows the surrounding font size, for icons inside text-sized controls. @default 'md' */\n size?: IconSize | 'inherit';\n /**\n * Accessible name. Without it the icon is decorative and hidden from\n * assistive technology; with it the icon is an image with that name.\n */\n label?: string;\n ref?: Ref<HTMLSpanElement>;\n}\n\n/**\n * Sizes any SVG to the icon scale and settles its accessibility: decorative\n * by default, an image when given a `label`. Colour is `currentColor`, so an\n * icon inherits the text tone around it.\n *\n * @status stable\n * @category Utilities\n * @accessibility `aria-hidden` by default (decorative); `role=\"img\"` with `aria-label` when `label` is given. Sized in `em` so it follows the text around it.\n * @do Give `label` only when the icon carries meaning the text around it does not.\n * @dont Use a labelled icon as the only name of a control; use IconButton.\n */\nexport function Icon({ children, size = 'md', label, className, ref, ...rest }: IconProps) {\n return (\n <span\n {...rest}\n ref={ref}\n className={classes(styles.icon, className)}\n data-size={size}\n role={label ? 'img' : undefined}\n aria-label={label}\n aria-hidden={label ? undefined : true}\n >\n {children}\n </span>\n );\n}\n\nIcon.displayName = 'Icon';\n"]}
@@ -0,0 +1,19 @@
1
+ import { classes } from './chunk-MI4QUKQS.js';
2
+ import { jsx } from 'react/jsx-runtime';
3
+
4
+ // src/skeleton/Skeleton.module.css
5
+ var Skeleton_default = {
6
+ skeleton: "Skeleton_skeleton",
7
+ lines: "Skeleton_lines"
8
+ };
9
+ function Skeleton({ shape = "text", lines = 1, size = "md", className, ref, ...rest }) {
10
+ if (shape === "text" && lines > 1) {
11
+ return /* @__PURE__ */ jsx("span", { ...rest, ref, "aria-hidden": "true", className: classes(Skeleton_default.lines, className), "data-shape": "text", children: Array.from({ length: lines }, (_, index) => /* @__PURE__ */ jsx("span", { className: Skeleton_default.skeleton, "data-shape": "text", "data-last": index === lines - 1 ? "" : void 0 }, index)) });
12
+ }
13
+ return /* @__PURE__ */ jsx("span", { ...rest, ref, "aria-hidden": "true", className: classes(Skeleton_default.skeleton, className), "data-shape": shape, "data-size": size });
14
+ }
15
+ Skeleton.displayName = "Skeleton";
16
+
17
+ export { Skeleton };
18
+ //# sourceMappingURL=chunk-ASOQ2MVR.js.map
19
+ //# sourceMappingURL=chunk-ASOQ2MVR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/skeleton/Skeleton.module.css","../src/skeleton/Skeleton.tsx"],"names":["skeleton","lines"],"mappings":";;;;AAAA,IAAA,gBAAA,GAAA;AAAA,EAGG,QAAA,EAAAA,mBAAAA;AAAA,EAiCA,KAAA,EAAAC;AAAA,CAAA;ACLI,SAAS,QAAA,CAAS,EAAE,KAAA,GAAQ,MAAA,EAAQ,KAAA,GAAQ,CAAA,EAAG,IAAA,GAAO,IAAA,EAAM,SAAA,EAAW,GAAA,EAAK,GAAG,IAAA,EAAK,EAAkB;AAC3G,EAAA,IAAI,KAAA,KAAU,MAAA,IAAU,KAAA,GAAQ,CAAA,EAAG;AACjC,IAAA,2BACG,MAAA,EAAA,EAAM,GAAG,IAAA,EAAM,GAAA,EAAU,eAAY,MAAA,EAAO,SAAA,EAAW,OAAA,CAAQ,gBAAA,CAAO,OAAO,SAAS,CAAA,EAAG,cAAW,MAAA,EAClG,QAAA,EAAA,KAAA,CAAM,KAAK,EAAE,MAAA,EAAQ,KAAA,EAAM,EAAG,CAAC,CAAA,EAAG,KAAA,yBAChC,MAAA,EAAA,EAAiB,SAAA,EAAW,iBAAO,QAAA,EAAU,YAAA,EAAW,MAAA,EAAO,WAAA,EAAW,UAAU,KAAA,GAAQ,CAAA,GAAI,KAAK,MAAA,EAAA,EAA3F,KAAsG,CAClH,CAAA,EACH,CAAA;AAAA,EAEJ;AACA,EAAA,2BAAQ,MAAA,EAAA,EAAM,GAAG,IAAA,EAAM,GAAA,EAAU,eAAY,MAAA,EAAO,SAAA,EAAW,OAAA,CAAQ,gBAAA,CAAO,UAAU,SAAS,CAAA,EAAG,YAAA,EAAY,KAAA,EAAO,aAAW,IAAA,EAAM,CAAA;AAC1I;AAEA,QAAA,CAAS,WAAA,GAAc,UAAA","file":"chunk-ASOQ2MVR.js","sourcesContent":["/* Every value is a token (--skeleton-*). Shimmer is a moving background-image; off under reduced motion. */\n\n@layer components {\n .skeleton {\n --_size: var(--skeleton-circle-md);\n\n display: block;\n inline-size: 100%;\n border-radius: var(--skeleton-radius);\n background-color: var(--skeleton-base);\n background-image: linear-gradient(90deg, var(--skeleton-base), var(--skeleton-highlight), var(--skeleton-base));\n background-size: 200% 100%;\n animation: shimmer calc(6 * var(--skeleton-duration)) linear infinite;\n\n &[data-shape=\"text\"] {\n block-size: var(--skeleton-text-height);\n }\n\n &[data-shape=\"rect\"] {\n block-size: var(--skeleton-circle-lg);\n }\n\n &[data-shape=\"circle\"] {\n inline-size: var(--_size);\n block-size: var(--_size);\n border-radius: var(--radius-full);\n }\n\n &[data-size=\"sm\"] { --_size: var(--skeleton-circle-sm); }\n &[data-size=\"lg\"] { --_size: var(--skeleton-circle-lg); }\n\n &[data-last] {\n inline-size: 60%;\n }\n }\n\n .lines {\n display: flex;\n flex-direction: column;\n gap: var(--skeleton-gap);\n inline-size: 100%;\n }\n\n @keyframes shimmer {\n from {\n background-position: 200% 0;\n }\n\n to {\n background-position: -200% 0;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .skeleton {\n animation: none;\n background-image: none;\n }\n }\n}\n","import type { HTMLAttributes, Ref } from 'react';\nimport { classes } from '../internal/classes';\nimport styles from './Skeleton.module.css';\n\nexport type SkeletonShape = 'text' | 'rect' | 'circle';\nexport type SkeletonSize = 'sm' | 'md' | 'lg';\n\nexport interface SkeletonProps extends Omit<HTMLAttributes<HTMLSpanElement>, 'children'> {\n /** @default 'text' */\n shape?: SkeletonShape;\n /** Number of text lines; the last is shorter. @default 1 */\n lines?: number;\n /** Circle diameter, from the control scale. @default 'md' */\n size?: SkeletonSize;\n ref?: Ref<HTMLSpanElement>;\n}\n\n/**\n * A placeholder for content that is loading. Decorative: hidden from\n * assistive technology, so mark the *container* `aria-busy` and announce\n * the loaded state there. Width for text and rect is the consumer's (pass\n * a `className`); the shimmer runs only when motion is allowed.\n *\n * @status stable\n * @category Feedback\n * @accessibility `aria-hidden`: a placeholder has nothing to announce. Mark the container `aria-busy` while loading and clear it when content arrives; the shimmer stops under reduced motion.\n * @do Match the shape of the content it stands in for.\n * Set `aria-busy` on the region, not on the skeleton.\n * @dont Show it for content that arrives in under a few hundred milliseconds.\n * Animate it when the user prefers reduced motion; the CSS already stops it.\n */\nexport function Skeleton({ shape = 'text', lines = 1, size = 'md', className, ref, ...rest }: SkeletonProps) {\n if (shape === 'text' && lines > 1) {\n return (\n <span {...rest} ref={ref} aria-hidden=\"true\" className={classes(styles.lines, className)} data-shape=\"text\">\n {Array.from({ length: lines }, (_, index) => (\n <span key={index} className={styles.skeleton} data-shape=\"text\" data-last={index === lines - 1 ? '' : undefined} />\n ))}\n </span>\n );\n }\n return <span {...rest} ref={ref} aria-hidden=\"true\" className={classes(styles.skeleton, className)} data-shape={shape} data-size={size} />;\n}\n\nSkeleton.displayName = 'Skeleton';\n"]}
@@ -0,0 +1,31 @@
1
+ import { classes } from './chunk-MI4QUKQS.js';
2
+ import { createElement } from 'react';
3
+
4
+ // src/inline/Inline.module.css
5
+ var Inline_default = {
6
+ inline: "Inline_inline"
7
+ };
8
+
9
+ // src/inline/Inline.tsx
10
+ function Inline({ as = "div", gap = 3, align, justify, wrap = true, className, ref, children, ...rest }) {
11
+ return createElement(
12
+ as,
13
+ {
14
+ ...rest,
15
+ ref,
16
+ // Safari drops list semantics when list-style is none; say it explicitly.
17
+ role: rest.role ?? (as === "ul" || as === "ol" ? "list" : void 0),
18
+ className: classes(Inline_default.inline, className),
19
+ "data-gap": gap,
20
+ "data-align": align,
21
+ "data-justify": justify,
22
+ "data-wrap": wrap ? "" : void 0
23
+ },
24
+ children
25
+ );
26
+ }
27
+ Inline.displayName = "Inline";
28
+
29
+ export { Inline };
30
+ //# sourceMappingURL=chunk-AWQHULJC.js.map
31
+ //# sourceMappingURL=chunk-AWQHULJC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/inline/Inline.module.css","../src/inline/Inline.tsx"],"names":["inline"],"mappings":";;;;AAAA,IAAA,cAAA,GAAA;AAAA,EAGG,MAAA,EAAAA;AAAA,CAAA;;;AC+BI,SAAS,MAAA,CAAO,EAAE,EAAA,GAAK,KAAA,EAAO,MAAM,CAAA,EAAG,KAAA,EAAO,OAAA,EAAS,IAAA,GAAO,MAAM,SAAA,EAAW,GAAA,EAAK,QAAA,EAAU,GAAG,MAAK,EAAgB;AAC3H,EAAA,OAAO,aAAA;AAAA,IACL,EAAA;AAAA,IACA;AAAA,MACE,GAAG,IAAA;AAAA,MACH,GAAA;AAAA;AAAA,MAEA,MAAM,IAAA,CAAK,IAAA,KAAS,OAAO,IAAA,IAAQ,EAAA,KAAO,OAAO,MAAA,GAAS,MAAA,CAAA;AAAA,MAC1D,SAAA,EAAW,OAAA,CAAQ,cAAA,CAAO,MAAA,EAAQ,SAAS,CAAA;AAAA,MAC3C,UAAA,EAAY,GAAA;AAAA,MACZ,YAAA,EAAc,KAAA;AAAA,MACd,cAAA,EAAgB,OAAA;AAAA,MAChB,WAAA,EAAa,OAAO,EAAA,GAAK;AAAA,KAC3B;AAAA,IACA;AAAA,GACF;AACF;AAEA,MAAA,CAAO,WAAA,GAAc,QAAA","file":"chunk-AWQHULJC.js","sourcesContent":["/* Every value is a token (--inline-gap-*). Gap, alignment and justification are data attributes. */\n\n@layer components {\n .inline {\n display: flex;\n flex-flow: row nowrap;\n gap: var(--inline-gap-3);\n margin: 0;\n padding: 0;\n list-style: none;\n\n &[data-gap=\"1\"] { gap: var(--inline-gap-1); }\n &[data-gap=\"2\"] { gap: var(--inline-gap-2); }\n &[data-gap=\"3\"] { gap: var(--inline-gap-3); }\n &[data-gap=\"4\"] { gap: var(--inline-gap-4); }\n &[data-gap=\"5\"] { gap: var(--inline-gap-5); }\n &[data-gap=\"6\"] { gap: var(--inline-gap-6); }\n &[data-gap=\"7\"] { gap: var(--inline-gap-7); }\n &[data-gap=\"8\"] { gap: var(--inline-gap-8); }\n &[data-align=\"start\"] { align-items: flex-start; }\n &[data-align=\"center\"] { align-items: center; }\n &[data-align=\"end\"] { align-items: flex-end; }\n &[data-align=\"stretch\"] { align-items: stretch; }\n &[data-justify=\"start\"] { justify-content: flex-start; }\n &[data-justify=\"center\"] { justify-content: center; }\n &[data-justify=\"end\"] { justify-content: flex-end; }\n &[data-justify=\"between\"] { justify-content: space-between; }\n &[data-wrap] { flex-wrap: wrap; }\n }\n}\n","import { createElement, type HTMLAttributes, type ReactNode, type Ref } from 'react';\nimport { classes } from '../internal/classes';\nimport styles from './Inline.module.css';\n\nexport type InlineGap = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;\nexport type InlineAlign = 'start' | 'center' | 'end' | 'stretch';\nexport type InlineJustify = 'start' | 'center' | 'end' | 'between';\nexport type InlineElement = 'div' | 'section' | 'nav' | 'ul' | 'ol' | 'li';\n\nexport interface InlineProps extends HTMLAttributes<HTMLElement> {\n /** @default 'div' */\n as?: InlineElement;\n /** Step on the spacing scale (`--space-1` … `--space-8`). @default 3 */\n gap?: InlineGap;\n align?: InlineAlign;\n justify?: InlineJustify;\n /** Wrap onto new lines when the row overflows. @default true */\n wrap?: boolean;\n ref?: Ref<HTMLElement>;\n children: ReactNode;\n}\n\n/**\n * A flex row whose gap is a step on the spacing scale, so consumers\n * compose layout from tokens instead of writing padding and margins.\n * Rendered as `ul`/`ol` it keeps `role=\"list\"` explicitly, because Safari\n * stops announcing a list once `list-style` is removed.\n *\n * @status stable\n * @category Layout\n * @accessibility Layout only: no role unless rendered as `ul`/`ol`, where `role=\"list\"` is kept explicitly because Safari drops list semantics without markers.\n * @do Use `as=\"ul\"` for a list of like items so the count is announced.\n * @dont Use it to space unrelated regions; it is one flex row.\n */\nexport function Inline({ as = 'div', gap = 3, align, justify, wrap = true, className, ref, children, ...rest }: InlineProps) {\n return createElement(\n as,\n {\n ...rest,\n ref,\n // Safari drops list semantics when list-style is none; say it explicitly.\n role: rest.role ?? (as === 'ul' || as === 'ol' ? 'list' : undefined),\n className: classes(styles.inline, className),\n 'data-gap': gap,\n 'data-align': align,\n 'data-justify': justify,\n 'data-wrap': wrap ? '' : undefined,\n },\n children,\n );\n}\n\nInline.displayName = 'Inline';\n"]}
@@ -0,0 +1,43 @@
1
+ import { Field } from './chunk-2PXTVZ7H.js';
2
+ import { classes } from './chunk-MI4QUKQS.js';
3
+ import { jsxs, jsx } from 'react/jsx-runtime';
4
+
5
+ function ToggleField({
6
+ label,
7
+ description,
8
+ error,
9
+ size,
10
+ disabled,
11
+ required,
12
+ id,
13
+ className,
14
+ rootClassName,
15
+ rowClassName,
16
+ control,
17
+ "aria-describedby": describedBy
18
+ }) {
19
+ const invalid = error !== void 0 && error !== null && error !== false && error !== "";
20
+ return /* @__PURE__ */ jsxs(
21
+ Field,
22
+ {
23
+ id,
24
+ invalid,
25
+ disabled: Boolean(disabled),
26
+ required: Boolean(required),
27
+ className: classes(rootClassName, className),
28
+ "data-size": size,
29
+ children: [
30
+ /* @__PURE__ */ jsxs("div", { className: rowClassName, children: [
31
+ /* @__PURE__ */ jsx(Field.Control, { "aria-describedby": describedBy, children: control }),
32
+ /* @__PURE__ */ jsx(Field.Label, { children: label })
33
+ ] }),
34
+ description && /* @__PURE__ */ jsx(Field.Description, { children: description }),
35
+ invalid && /* @__PURE__ */ jsx(Field.Error, { children: error })
36
+ ]
37
+ }
38
+ );
39
+ }
40
+
41
+ export { ToggleField };
42
+ //# sourceMappingURL=chunk-BBV4L5WO.js.map
43
+ //# sourceMappingURL=chunk-BBV4L5WO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/internal/ToggleField.tsx"],"names":[],"mappings":";;;;AA0BO,SAAS,WAAA,CAAY;AAAA,EAC1B,KAAA;AAAA,EACA,WAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,EAAA;AAAA,EACA,SAAA;AAAA,EACA,aAAA;AAAA,EACA,YAAA;AAAA,EACA,OAAA;AAAA,EACA,kBAAA,EAAoB;AACtB,CAAA,EAAqB;AACnB,EAAA,MAAM,UAAU,KAAA,KAAU,MAAA,IAAa,UAAU,IAAA,IAAQ,KAAA,KAAU,SAAS,KAAA,KAAU,EAAA;AACtF,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,EAAA;AAAA,MACA,OAAA;AAAA,MACA,QAAA,EAAU,QAAQ,QAAQ,CAAA;AAAA,MAC1B,QAAA,EAAU,QAAQ,QAAQ,CAAA;AAAA,MAC1B,SAAA,EAAW,OAAA,CAAQ,aAAA,EAAe,SAAS,CAAA;AAAA,MAC3C,WAAA,EAAW,IAAA;AAAA,MAEX,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAW,YAAA,EACd,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,KAAA,CAAM,OAAA,EAAN,EAAc,kBAAA,EAAkB,aAAc,QAAA,EAAA,OAAA,EAAQ,CAAA;AAAA,0BACvD,GAAA,CAAC,KAAA,CAAM,KAAA,EAAN,EAAa,QAAA,EAAA,KAAA,EAAM;AAAA,SAAA,EACtB,CAAA;AAAA,QACC,WAAA,oBAAe,GAAA,CAAC,KAAA,CAAM,WAAA,EAAN,EAAmB,QAAA,EAAA,WAAA,EAAY,CAAA;AAAA,QAC/C,OAAA,oBAAW,GAAA,CAAC,KAAA,CAAM,KAAA,EAAN,EAAa,QAAA,EAAA,KAAA,EAAM;AAAA;AAAA;AAAA,GAClC;AAEJ","file":"chunk-BBV4L5WO.js","sourcesContent":["import type { ReactNode } from 'react';\nimport { Field } from '../field';\nimport { classes } from './classes';\n\nexport type ToggleSize = 'sm' | 'md' | 'lg';\n\nexport interface ToggleFieldProps {\n /** Visible inline label. */\n label: ReactNode;\n description?: ReactNode;\n error?: ReactNode;\n size: ToggleSize;\n disabled?: boolean;\n required?: boolean;\n id?: string;\n className?: string;\n /** The Field root class of the concrete control (checkbox, switch). */\n rootClassName: string | undefined;\n /** The class of the row holding the control and its label. */\n rowClassName: string | undefined;\n /** The single `<input>` element; Field.Control wires it. */\n control: ReactNode;\n 'aria-describedby'?: string;\n}\n\n/** Field wiring for a control whose label sits beside it: Checkbox, Switch. */\nexport function ToggleField({\n label,\n description,\n error,\n size,\n disabled,\n required,\n id,\n className,\n rootClassName,\n rowClassName,\n control,\n 'aria-describedby': describedBy,\n}: ToggleFieldProps) {\n const invalid = error !== undefined && error !== null && error !== false && error !== '';\n return (\n <Field\n id={id}\n invalid={invalid}\n disabled={Boolean(disabled)}\n required={Boolean(required)}\n className={classes(rootClassName, className)}\n data-size={size}\n >\n <div className={rowClassName}>\n <Field.Control aria-describedby={describedBy}>{control}</Field.Control>\n <Field.Label>{label}</Field.Label>\n </div>\n {description && <Field.Description>{description}</Field.Description>}\n {invalid && <Field.Error>{error}</Field.Error>}\n </Field>\n );\n}\n"]}
@@ -0,0 +1,9 @@
1
+ // src/internal/selection.ts
2
+ function selectionToIds(selection, all) {
3
+ const keys = selection === "all" ? all() : selection;
4
+ return Array.from(keys, String);
5
+ }
6
+
7
+ export { selectionToIds };
8
+ //# sourceMappingURL=chunk-CZBCGLEM.js.map
9
+ //# sourceMappingURL=chunk-CZBCGLEM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/internal/selection.ts"],"names":[],"mappings":";AAOO,SAAS,cAAA,CAAe,WAAsB,GAAA,EAAoC;AACvF,EAAA,MAAM,IAAA,GAAO,SAAA,KAAc,KAAA,GAAQ,GAAA,EAAI,GAAI,SAAA;AAC3C,EAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAA,EAAM,MAAM,CAAA;AAChC","file":"chunk-CZBCGLEM.js","sourcesContent":["import type { Key, Selection } from 'react-aria-components';\n\n/**\n * React Aria reports a selection as a Set of keys or the literal `'all'`\n * (Ctrl/Cmd+A in a multiple-selection collection). pulp's contract is a\n * plain array of ids, so `'all'` is resolved against the ids the caller knows.\n */\nexport function selectionToIds(selection: Selection, all: () => Iterable<Key>): string[] {\n const keys = selection === 'all' ? all() : selection;\n return Array.from(keys, String);\n}\n"]}
@@ -0,0 +1,65 @@
1
+ import { ToggleField } from './chunk-BBV4L5WO.js';
2
+ import { useCallback } from 'react';
3
+ import { jsx } from 'react/jsx-runtime';
4
+
5
+ // src/checkbox/Checkbox.module.css
6
+ var Checkbox_default = {
7
+ checkbox: "Checkbox_checkbox",
8
+ row: "Checkbox_row",
9
+ input: "Checkbox_input"
10
+ };
11
+ function Checkbox({
12
+ label,
13
+ description,
14
+ error,
15
+ size = "md",
16
+ indeterminate = false,
17
+ required,
18
+ disabled,
19
+ id,
20
+ className,
21
+ ref,
22
+ "aria-describedby": describedBy,
23
+ ...rest
24
+ }) {
25
+ const setRef = useCallback(
26
+ (element) => {
27
+ if (element) element.indeterminate = indeterminate;
28
+ if (typeof ref === "function") ref(element);
29
+ else if (ref) ref.current = element;
30
+ },
31
+ [indeterminate, ref]
32
+ );
33
+ return /* @__PURE__ */ jsx(
34
+ ToggleField,
35
+ {
36
+ label,
37
+ description,
38
+ error,
39
+ size,
40
+ required,
41
+ disabled,
42
+ id,
43
+ className,
44
+ rootClassName: Checkbox_default.checkbox,
45
+ rowClassName: Checkbox_default.row,
46
+ "aria-describedby": describedBy,
47
+ control: /* @__PURE__ */ jsx(
48
+ "input",
49
+ {
50
+ ...rest,
51
+ ref: setRef,
52
+ type: "checkbox",
53
+ className: Checkbox_default.input,
54
+ "aria-checked": indeterminate ? "mixed" : void 0,
55
+ "data-indeterminate": indeterminate ? "" : void 0
56
+ }
57
+ )
58
+ }
59
+ );
60
+ }
61
+ Checkbox.displayName = "Checkbox";
62
+
63
+ export { Checkbox };
64
+ //# sourceMappingURL=chunk-DWE374JX.js.map
65
+ //# sourceMappingURL=chunk-DWE374JX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/checkbox/Checkbox.module.css","../src/checkbox/Checkbox.tsx"],"names":["checkbox","row","input"],"mappings":";;;;;AAAA,IAAA,gBAAA,GAAA;AAAA,EAOG,QAAA,EAAAA,mBAAAA;AAAA,EAWA,GAAA,EAAAC,cAAAA;AAAA,EAMA,KAAA,EAAAC;AAAA,CAAA;ACaI,SAAS,QAAA,CAAS;AAAA,EACvB,KAAA;AAAA,EACA,WAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA,GAAO,IAAA;AAAA,EACP,aAAA,GAAgB,KAAA;AAAA,EAChB,QAAA;AAAA,EACA,QAAA;AAAA,EACA,EAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAA;AAAA,EACA,kBAAA,EAAoB,WAAA;AAAA,EACpB,GAAG;AACL,CAAA,EAAkB;AAEhB,EAAA,MAAM,MAAA,GAAS,WAAA;AAAA,IACb,CAAC,OAAA,KAAqC;AACpC,MAAA,IAAI,OAAA,UAAiB,aAAA,GAAgB,aAAA;AACrC,MAAA,IAAI,OAAO,GAAA,KAAQ,UAAA,EAAY,GAAA,CAAI,OAAO,CAAA;AAAA,WAAA,IACjC,GAAA,MAAS,OAAA,GAAU,OAAA;AAAA,IAC9B,CAAA;AAAA,IACA,CAAC,eAAe,GAAG;AAAA,GACrB;AAEA,EAAA,uBACE,GAAA;AAAA,IAAC,WAAA;AAAA,IAAA;AAAA,MACC,KAAA;AAAA,MACA,WAAA;AAAA,MACA,KAAA;AAAA,MACA,IAAA;AAAA,MACA,QAAA;AAAA,MACA,QAAA;AAAA,MACA,EAAA;AAAA,MACA,SAAA;AAAA,MACA,eAAe,gBAAA,CAAO,QAAA;AAAA,MACtB,cAAc,gBAAA,CAAO,GAAA;AAAA,MACrB,kBAAA,EAAkB,WAAA;AAAA,MAClB,OAAA,kBACE,GAAA;AAAA,QAAC,OAAA;AAAA,QAAA;AAAA,UACE,GAAG,IAAA;AAAA,UACJ,GAAA,EAAK,MAAA;AAAA,UACL,IAAA,EAAK,UAAA;AAAA,UACL,WAAW,gBAAA,CAAO,KAAA;AAAA,UAClB,cAAA,EAAc,gBAAgB,OAAA,GAAU,MAAA;AAAA,UACxC,oBAAA,EAAoB,gBAAgB,EAAA,GAAK;AAAA;AAAA;AAC3C;AAAA,GAEJ;AAEJ;AAEA,QAAA,CAAS,WAAA,GAAc,UAAA","file":"chunk-DWE374JX.js","sourcesContent":["/*\n * Every value is a token (--checkbox-*). Size and invalid state are resolved\n * into private custom properties on the root, so the input has one rule per\n * property and no selector ordering to maintain.\n */\n\n@layer components {\n .checkbox {\n --_size: var(--checkbox-size-md);\n --_border: var(--checkbox-border);\n\n font-family: var(--font-family-body);\n\n &[data-size=\"sm\"] { --_size: var(--checkbox-size-sm); }\n &[data-size=\"lg\"] { --_size: var(--checkbox-size-lg); }\n &[data-invalid] { --_border: var(--checkbox-border-invalid); }\n }\n\n .row {\n display: flex;\n align-items: center;\n gap: var(--checkbox-gap);\n }\n\n .input {\n display: grid;\n flex: none;\n place-content: center;\n inline-size: var(--_size);\n block-size: var(--_size);\n margin: 0;\n border: var(--size-hairline) solid var(--_border);\n border-radius: var(--checkbox-radius);\n background-color: var(--checkbox-bg);\n appearance: none;\n cursor: pointer;\n transition:\n background-color var(--checkbox-motion-duration) var(--motion-easing-standard),\n border-color var(--checkbox-motion-duration) var(--motion-easing-standard);\n\n /* Sized from the box, not in percent: a grid item's percentage resolves against an auto area and collapses. */\n &::after {\n content: \"\";\n inline-size: calc(var(--_size) * 0.3);\n block-size: calc(var(--_size) * 0.55);\n border-style: solid;\n border-color: var(--checkbox-check);\n border-width: 0 var(--checkbox-check-width) var(--checkbox-check-width) 0;\n rotate: 45deg;\n translate: 0 -10%;\n opacity: 0;\n }\n\n &:checked,\n &:indeterminate {\n border-color: var(--checkbox-bg-checked);\n background-color: var(--checkbox-bg-checked);\n\n &::after {\n opacity: 1;\n }\n }\n\n &:indeterminate::after {\n inline-size: calc(var(--_size) * 0.55);\n block-size: 0;\n border-width: 0 0 var(--checkbox-check-width);\n rotate: 0deg;\n translate: 0 0;\n }\n\n &:focus-visible {\n outline: var(--checkbox-focus-ring-width) solid var(--checkbox-focus-ring);\n outline-offset: var(--checkbox-focus-ring-offset);\n }\n\n &:disabled {\n cursor: not-allowed;\n opacity: 0.55;\n }\n\n &:hover:not(:disabled, :checked, :indeterminate) {\n border-color: var(--checkbox-border-hover);\n }\n\n &:hover:not(:disabled):is(:checked, :indeterminate) {\n border-color: var(--checkbox-bg-checked-hover);\n background-color: var(--checkbox-bg-checked-hover);\n }\n }\n}\n","import { useCallback, type InputHTMLAttributes, type ReactNode, type Ref } from 'react';\nimport { ToggleField, type ToggleSize } from '../internal/ToggleField';\nimport styles from './Checkbox.module.css';\n\nexport type CheckboxSize = ToggleSize;\n\nexport interface CheckboxProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type'> {\n /** Visible label beside the box. */\n label: ReactNode;\n description?: ReactNode;\n /** Presence marks the control invalid and announces the message. */\n error?: ReactNode;\n /** @default 'md' */\n size?: CheckboxSize;\n /** The \"some selected\" state; visual and `aria-checked=\"mixed\"`, independent of `checked`. @default false */\n indeterminate?: boolean;\n /** The `<input>` element. */\n ref?: Ref<HTMLInputElement>;\n /** Applied to the wrapper, not the input. */\n className?: string;\n}\n\n/**\n * A native checkbox drawn with tokens: `appearance: none` on the input, the\n * box and tick in CSS, so keyboard, forms and assistive technology are the\n * browser's own. Label, description and error come from Field. Controlled and\n * uncontrolled behave like the native input. State is the native `:checked`\n * and `:indeterminate`, plus `data-indeterminate` on the input.\n *\n * @status stable\n * @category Forms\n * @accessibility A native `input type=\"checkbox\"` with `appearance: none`; label, description and error wire through Field. `indeterminate` sets the DOM property and `aria-checked=\"mixed\"`. Keyboard: Space toggles.\n * @do Use `indeterminate` for a parent whose children are partly selected.\n * Group related checkboxes under a `fieldset`.\n * @dont Use it for an immediate setting; use Switch.\n * Hide the label; the description does not name the control.\n */\nexport function Checkbox({\n label,\n description,\n error,\n size = 'md',\n indeterminate = false,\n required,\n disabled,\n id,\n className,\n ref,\n 'aria-describedby': describedBy,\n ...rest\n}: CheckboxProps) {\n // `indeterminate` is a property, not an attribute: set it on the element as it mounts and whenever it changes.\n const setRef = useCallback(\n (element: HTMLInputElement | null) => {\n if (element) element.indeterminate = indeterminate;\n if (typeof ref === 'function') ref(element);\n else if (ref) ref.current = element;\n },\n [indeterminate, ref],\n );\n\n return (\n <ToggleField\n label={label}\n description={description}\n error={error}\n size={size}\n required={required}\n disabled={disabled}\n id={id}\n className={className}\n rootClassName={styles.checkbox}\n rowClassName={styles.row}\n aria-describedby={describedBy}\n control={\n <input\n {...rest}\n ref={setRef}\n type=\"checkbox\"\n className={styles.input}\n aria-checked={indeterminate ? 'mixed' : undefined}\n data-indeterminate={indeterminate ? '' : undefined}\n />\n }\n />\n );\n}\n\nCheckbox.displayName = 'Checkbox';\n"]}
@@ -0,0 +1,159 @@
1
+ import { Alert } from './chunk-PM4YO67Q.js';
2
+ import { Button } from './chunk-KPQGS4PG.js';
3
+ import { classes } from './chunk-MI4QUKQS.js';
4
+ import { createContext, useContext, useState, useRef, useEffect, useCallback, useMemo } from 'react';
5
+ import { createPortal } from 'react-dom';
6
+ import { jsx, jsxs } from 'react/jsx-runtime';
7
+
8
+ var ToastContext = createContext(null);
9
+ function useToast() {
10
+ const context = useContext(ToastContext);
11
+ if (!context) throw new Error("useToast must be used inside <ToastProvider>");
12
+ return context;
13
+ }
14
+
15
+ // src/toast/Toast.module.css
16
+ var Toast_default = {
17
+ region: "Toast_region",
18
+ list: "Toast_list",
19
+ item: "Toast_item",
20
+ toast: "Toast_toast"
21
+ };
22
+ function ToastProvider({ placement = "bottom-end", max = 5, duration = 6e3, label = "Notifications", children }) {
23
+ const [items, setItems] = useState([]);
24
+ const [paused, setPaused] = useState(false);
25
+ const timers = useRef(/* @__PURE__ */ new Map());
26
+ const counter = useRef(0);
27
+ const [container] = useState(() => {
28
+ if (typeof document === "undefined") return void 0;
29
+ const element = document.createElement("div");
30
+ element.dataset.pulpToasts = "";
31
+ return element;
32
+ });
33
+ useEffect(() => {
34
+ if (!container) return;
35
+ document.body.append(container);
36
+ return () => container.remove();
37
+ }, [container]);
38
+ const dismiss = useCallback((id) => {
39
+ const timer = timers.current.get(id);
40
+ if (timer?.handle !== void 0) clearTimeout(timer.handle);
41
+ timers.current.delete(id);
42
+ setItems((current) => current.filter((item) => item.id !== id));
43
+ }, []);
44
+ const dismissAll = useCallback(() => {
45
+ for (const timer of timers.current.values()) if (timer.handle !== void 0) clearTimeout(timer.handle);
46
+ timers.current.clear();
47
+ setItems([]);
48
+ }, []);
49
+ const start = useCallback(
50
+ (id, remaining) => {
51
+ if (!Number.isFinite(remaining)) return;
52
+ timers.current.set(id, { remaining, startedAt: Date.now(), handle: setTimeout(() => dismiss(id), remaining) });
53
+ },
54
+ [dismiss]
55
+ );
56
+ const toast = useCallback(
57
+ (options) => {
58
+ counter.current += 1;
59
+ const id = `toast-${counter.current}`;
60
+ const ttl = options.duration ?? (options.tone === "error" ? Infinity : duration);
61
+ setItems((current) => {
62
+ const next = [...current, { ...options, id }];
63
+ const overflow = next.length - max;
64
+ if (overflow > 0) {
65
+ for (const old of next.slice(0, overflow)) {
66
+ const timer = timers.current.get(old.id);
67
+ if (timer?.handle !== void 0) clearTimeout(timer.handle);
68
+ timers.current.delete(old.id);
69
+ }
70
+ return next.slice(overflow);
71
+ }
72
+ return next;
73
+ });
74
+ if (!paused) start(id, ttl);
75
+ else timers.current.set(id, { remaining: ttl, startedAt: Date.now(), handle: void 0 });
76
+ return id;
77
+ },
78
+ [duration, max, paused, start]
79
+ );
80
+ useEffect(() => {
81
+ const map = timers.current;
82
+ if (paused) {
83
+ for (const [id, timer] of map) {
84
+ if (timer.handle === void 0) continue;
85
+ clearTimeout(timer.handle);
86
+ map.set(id, { ...timer, remaining: Math.max(0, timer.remaining - (Date.now() - timer.startedAt)), handle: void 0 });
87
+ }
88
+ } else {
89
+ for (const [id, timer] of map) {
90
+ if (timer.handle !== void 0 || !Number.isFinite(timer.remaining)) continue;
91
+ map.set(id, { ...timer, startedAt: Date.now(), handle: setTimeout(() => dismiss(id), timer.remaining) });
92
+ }
93
+ }
94
+ }, [paused, dismiss]);
95
+ useEffect(() => {
96
+ const map = timers.current;
97
+ return () => {
98
+ for (const timer of map.values()) if (timer.handle !== void 0) clearTimeout(timer.handle);
99
+ };
100
+ }, []);
101
+ const value = useMemo(() => ({ toast, dismiss, dismissAll }), [toast, dismiss, dismissAll]);
102
+ const onKeyDown = (event) => {
103
+ if (event.key !== "Escape") return;
104
+ const item = event.target.closest("[data-toast-id]");
105
+ if (item?.dataset.toastId) {
106
+ event.preventDefault();
107
+ dismiss(item.dataset.toastId);
108
+ }
109
+ };
110
+ const region = /* @__PURE__ */ jsx(
111
+ "section",
112
+ {
113
+ role: "region",
114
+ "aria-label": label,
115
+ "aria-live": "polite",
116
+ className: classes(Toast_default.region),
117
+ "data-placement": placement,
118
+ onMouseEnter: () => setPaused(true),
119
+ onMouseLeave: () => setPaused(false),
120
+ onFocus: () => setPaused(true),
121
+ onBlur: (event) => {
122
+ if (!event.currentTarget.contains(event.relatedTarget)) setPaused(false);
123
+ },
124
+ onKeyDown,
125
+ children: /* @__PURE__ */ jsx("ol", { className: Toast_default.list, children: items.map((item) => /* @__PURE__ */ jsx("li", { className: Toast_default.item, "data-toast-id": item.id, "data-tone": item.tone ?? "info", children: /* @__PURE__ */ jsx(
126
+ Alert,
127
+ {
128
+ tone: item.tone,
129
+ title: item.title,
130
+ live: "off",
131
+ className: Toast_default.toast,
132
+ onDismiss: () => dismiss(item.id),
133
+ action: item.action && /* @__PURE__ */ jsx(
134
+ Button,
135
+ {
136
+ size: "sm",
137
+ variant: "secondary",
138
+ onClick: () => {
139
+ item.action?.onClick();
140
+ dismiss(item.id);
141
+ },
142
+ children: item.action.label
143
+ }
144
+ ),
145
+ children: item.description
146
+ }
147
+ ) }, item.id)) })
148
+ }
149
+ );
150
+ return /* @__PURE__ */ jsxs(ToastContext.Provider, { value, children: [
151
+ children,
152
+ container ? createPortal(region, container) : null
153
+ ] });
154
+ }
155
+ ToastProvider.displayName = "ToastProvider";
156
+
157
+ export { ToastProvider, useToast };
158
+ //# sourceMappingURL=chunk-DXOOW6Q6.js.map
159
+ //# sourceMappingURL=chunk-DXOOW6Q6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/toast/context.ts","../src/toast/Toast.module.css","../src/toast/Toast.tsx"],"names":["region","list","item","toast"],"mappings":"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","file":"chunk-DXOOW6Q6.js","sourcesContent":["import { createContext, useContext, type ReactNode } from 'react';\nimport type { AlertTone } from '../alert';\n\nexport interface ToastOptions {\n title: ReactNode;\n description?: ReactNode;\n /** @default 'info' */\n tone?: AlertTone;\n /** Milliseconds before auto-dismiss; `Infinity` keeps it until dismissed. Errors default to `Infinity`. */\n duration?: number;\n action?: { label: string; onClick: () => void };\n}\n\nexport interface ToastItem extends ToastOptions {\n id: string;\n}\n\nexport interface ToastContextValue {\n /** Shows a toast and returns its id. */\n toast: (options: ToastOptions) => string;\n dismiss: (id: string) => void;\n dismissAll: () => void;\n}\n\nexport const ToastContext = createContext<ToastContextValue | null>(null);\n\n/** The toast API. Must be used inside `ToastProvider`. */\nexport function useToast(): ToastContextValue {\n const context = useContext(ToastContext);\n if (!context) throw new Error('useToast must be used inside <ToastProvider>');\n return context;\n}\n","/* Every value is a token (--toast-*). The region is fixed; placement is a data attribute. */\n\n@layer components {\n .region {\n --_top: auto;\n --_end: var(--toast-offset);\n --_bottom: var(--toast-offset);\n --_start: auto;\n\n position: fixed;\n z-index: var(--toast-layer);\n inset: var(--_top) var(--_end) var(--_bottom) var(--_start);\n inline-size: min(var(--toast-width), 100vw);\n padding: 0;\n pointer-events: none;\n\n &[data-placement=\"top-end\"] {\n --_top: var(--toast-offset);\n --_bottom: auto;\n }\n\n &[data-placement=\"top-center\"] {\n --_top: var(--toast-offset);\n --_bottom: auto;\n --_start: 0;\n --_end: 0;\n\n margin-inline: auto;\n }\n }\n\n .list {\n display: flex;\n flex-direction: column;\n gap: var(--toast-gap);\n margin: 0;\n padding: 0;\n list-style: none;\n }\n\n .item {\n pointer-events: auto;\n animation: enter var(--toast-motion-duration) var(--motion-easing-standard);\n }\n\n .toast {\n border-radius: var(--toast-radius);\n box-shadow: var(--toast-shadow);\n }\n\n @keyframes enter {\n from {\n opacity: 0;\n translate: 0 var(--space-2);\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .item {\n animation: none;\n }\n }\n}\n","import { useCallback, useEffect, useMemo, useRef, useState, type KeyboardEvent, type ReactNode } from 'react';\nimport { createPortal } from 'react-dom';\nimport { Alert } from '../alert';\nimport { Button } from '../button';\nimport { classes } from '../internal/classes';\nimport { ToastContext, type ToastItem, type ToastOptions } from './context';\nimport styles from './Toast.module.css';\n\nexport type ToastPlacement = 'bottom-end' | 'top-end' | 'top-center';\n\nexport interface ToastProviderProps {\n /** @default 'bottom-end' */\n placement?: ToastPlacement;\n /** Most toasts shown at once; the oldest is dismissed first. @default 5 */\n max?: number;\n /** Default auto-dismiss time in milliseconds. @default 6000 */\n duration?: number;\n /** Accessible name of the region. @default 'Notifications' */\n label?: string;\n children: ReactNode;\n}\n\ninterface Timer {\n remaining: number;\n startedAt: number;\n handle: ReturnType<typeof setTimeout> | undefined;\n}\n\n/**\n * Mount once near the app root. Owns a portal element with a polite live\n * region; `useToast()` adds notifications to it. Timers pause while the\n * region is hovered or holds focus, Escape dismisses the focused toast, and\n * error toasts stay until dismissed. Each toast is an Alert.\n *\n * @status stable\n * @category Feedback\n * @accessibility Owns a `region` named \"Notifications\" with `aria-live=\"polite\"`; each toast is an Alert with its live role off (the region announces). Timers pause while the region is hovered or holds focus; Escape dismisses the focused toast; error toasts stay until dismissed.\n * @do Mount it once near the app root.\n * Keep messages to one sentence; put detail behind an `action`.\n * @dont Use a toast for an error the user must fix in a form; show it at the field.\n * Stack more than a few; the cap drops the oldest.\n */\nexport function ToastProvider({ placement = 'bottom-end', max = 5, duration = 6000, label = 'Notifications', children }: ToastProviderProps) {\n const [items, setItems] = useState<ToastItem[]>([]);\n const [paused, setPaused] = useState(false);\n const timers = useRef(new Map<string, Timer>());\n const counter = useRef(0);\n\n const [container] = useState<HTMLDivElement | undefined>(() => {\n if (typeof document === 'undefined') return undefined;\n const element = document.createElement('div');\n element.dataset.pulpToasts = '';\n return element;\n });\n\n useEffect(() => {\n if (!container) return;\n document.body.append(container);\n return () => container.remove();\n }, [container]);\n\n const dismiss = useCallback((id: string) => {\n const timer = timers.current.get(id);\n if (timer?.handle !== undefined) clearTimeout(timer.handle);\n timers.current.delete(id);\n setItems((current) => current.filter((item) => item.id !== id));\n }, []);\n\n const dismissAll = useCallback(() => {\n for (const timer of timers.current.values()) if (timer.handle !== undefined) clearTimeout(timer.handle);\n timers.current.clear();\n setItems([]);\n }, []);\n\n const start = useCallback(\n (id: string, remaining: number) => {\n if (!Number.isFinite(remaining)) return;\n timers.current.set(id, { remaining, startedAt: Date.now(), handle: setTimeout(() => dismiss(id), remaining) });\n },\n [dismiss],\n );\n\n const toast = useCallback(\n (options: ToastOptions) => {\n counter.current += 1;\n const id = `toast-${counter.current}`;\n const ttl = options.duration ?? (options.tone === 'error' ? Infinity : duration);\n setItems((current) => {\n const next = [...current, { ...options, id }];\n const overflow = next.length - max;\n if (overflow > 0) {\n for (const old of next.slice(0, overflow)) {\n const timer = timers.current.get(old.id);\n if (timer?.handle !== undefined) clearTimeout(timer.handle);\n timers.current.delete(old.id);\n }\n return next.slice(overflow);\n }\n return next;\n });\n if (!paused) start(id, ttl);\n else timers.current.set(id, { remaining: ttl, startedAt: Date.now(), handle: undefined });\n return id;\n },\n [duration, max, paused, start],\n );\n\n // Pause: freeze every timer with its remaining time. Resume: restart them.\n useEffect(() => {\n const map = timers.current;\n if (paused) {\n for (const [id, timer] of map) {\n if (timer.handle === undefined) continue;\n clearTimeout(timer.handle);\n map.set(id, { ...timer, remaining: Math.max(0, timer.remaining - (Date.now() - timer.startedAt)), handle: undefined });\n }\n } else {\n for (const [id, timer] of map) {\n if (timer.handle !== undefined || !Number.isFinite(timer.remaining)) continue;\n map.set(id, { ...timer, startedAt: Date.now(), handle: setTimeout(() => dismiss(id), timer.remaining) });\n }\n }\n }, [paused, dismiss]);\n\n useEffect(() => {\n const map = timers.current;\n return () => {\n for (const timer of map.values()) if (timer.handle !== undefined) clearTimeout(timer.handle);\n };\n }, []);\n\n const value = useMemo(() => ({ toast, dismiss, dismissAll }), [toast, dismiss, dismissAll]);\n\n const onKeyDown = (event: KeyboardEvent<HTMLElement>) => {\n if (event.key !== 'Escape') return;\n const item = (event.target as HTMLElement).closest<HTMLElement>('[data-toast-id]');\n if (item?.dataset.toastId) {\n event.preventDefault();\n dismiss(item.dataset.toastId);\n }\n };\n\n const region = (\n <section\n role=\"region\"\n aria-label={label}\n aria-live=\"polite\"\n className={classes(styles.region)}\n data-placement={placement}\n onMouseEnter={() => setPaused(true)}\n onMouseLeave={() => setPaused(false)}\n onFocus={() => setPaused(true)}\n onBlur={(event) => {\n if (!event.currentTarget.contains(event.relatedTarget as Node | null)) setPaused(false);\n }}\n onKeyDown={onKeyDown}\n >\n <ol className={styles.list}>\n {items.map((item) => (\n <li key={item.id} className={styles.item} data-toast-id={item.id} data-tone={item.tone ?? 'info'}>\n <Alert\n tone={item.tone}\n title={item.title}\n live=\"off\"\n className={styles.toast}\n onDismiss={() => dismiss(item.id)}\n action={\n item.action && (\n <Button\n size=\"sm\"\n variant=\"secondary\"\n onClick={() => {\n item.action?.onClick();\n dismiss(item.id);\n }}\n >\n {item.action.label}\n </Button>\n )\n }\n >\n {item.description}\n </Alert>\n </li>\n ))}\n </ol>\n </section>\n );\n\n return (\n <ToastContext.Provider value={value}>\n {children}\n {container ? createPortal(region, container) : null}\n </ToastContext.Provider>\n );\n}\n\nToastProvider.displayName = 'ToastProvider';\n"]}