@pithyjs/ui-kit 0.1.0-beta.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 (417) hide show
  1. package/LICENSE +21 -0
  2. package/dist/animation/animate-in.d.ts +35 -0
  3. package/dist/animation/animate-in.d.ts.map +1 -0
  4. package/dist/animation/animate-in.js +71 -0
  5. package/dist/animation/animate-in.js.map +1 -0
  6. package/dist/atoms/actions/_icon-control.scss +53 -0
  7. package/dist/atoms/actions/button/Button.d.ts +93 -0
  8. package/dist/atoms/actions/button/Button.d.ts.map +1 -0
  9. package/dist/atoms/actions/button/Button.js +332 -0
  10. package/dist/atoms/actions/button/Button.js.map +1 -0
  11. package/dist/atoms/actions/button/button.scss +342 -0
  12. package/dist/atoms/actions/icon-button/IconButton.d.ts +47 -0
  13. package/dist/atoms/actions/icon-button/IconButton.d.ts.map +1 -0
  14. package/dist/atoms/actions/icon-button/IconButton.js +81 -0
  15. package/dist/atoms/actions/icon-button/IconButton.js.map +1 -0
  16. package/dist/atoms/actions/icon-button/icon-button.scss +20 -0
  17. package/dist/atoms/actions/icon-group/IconGroup.d.ts +60 -0
  18. package/dist/atoms/actions/icon-group/IconGroup.d.ts.map +1 -0
  19. package/dist/atoms/actions/icon-group/IconGroup.js +191 -0
  20. package/dist/atoms/actions/icon-group/IconGroup.js.map +1 -0
  21. package/dist/atoms/actions/icon-group/icon-group.scss +36 -0
  22. package/dist/atoms/actions/segmented-control/SegmentedControl.d.ts +49 -0
  23. package/dist/atoms/actions/segmented-control/SegmentedControl.d.ts.map +1 -0
  24. package/dist/atoms/actions/segmented-control/SegmentedControl.js +107 -0
  25. package/dist/atoms/actions/segmented-control/SegmentedControl.js.map +1 -0
  26. package/dist/atoms/actions/segmented-control/segmented-control.scss +90 -0
  27. package/dist/atoms/content/_mixins.scss +79 -0
  28. package/dist/atoms/content/action-tile/ActionTile.d.ts +27 -0
  29. package/dist/atoms/content/action-tile/ActionTile.d.ts.map +1 -0
  30. package/dist/atoms/content/action-tile/ActionTile.js +98 -0
  31. package/dist/atoms/content/action-tile/ActionTile.js.map +1 -0
  32. package/dist/atoms/content/action-tile/action-tile.scss +150 -0
  33. package/dist/atoms/content/badge/Badge.d.ts +57 -0
  34. package/dist/atoms/content/badge/Badge.d.ts.map +1 -0
  35. package/dist/atoms/content/badge/Badge.js +177 -0
  36. package/dist/atoms/content/badge/Badge.js.map +1 -0
  37. package/dist/atoms/content/badge/badge.scss +198 -0
  38. package/dist/atoms/content/heading/Heading.d.ts +53 -0
  39. package/dist/atoms/content/heading/Heading.d.ts.map +1 -0
  40. package/dist/atoms/content/heading/Heading.js +142 -0
  41. package/dist/atoms/content/heading/Heading.js.map +1 -0
  42. package/dist/atoms/content/heading/heading.scss +43 -0
  43. package/dist/atoms/content/icon/Icon.d.ts +68 -0
  44. package/dist/atoms/content/icon/Icon.d.ts.map +1 -0
  45. package/dist/atoms/content/icon/Icon.js +137 -0
  46. package/dist/atoms/content/icon/Icon.js.map +1 -0
  47. package/dist/atoms/content/icon/icon.scss +66 -0
  48. package/dist/atoms/content/icon/resolveIconSvg.d.ts +21 -0
  49. package/dist/atoms/content/icon/resolveIconSvg.d.ts.map +1 -0
  50. package/dist/atoms/content/icon/resolveIconSvg.js +73 -0
  51. package/dist/atoms/content/icon/resolveIconSvg.js.map +1 -0
  52. package/dist/atoms/content/image/Image.d.ts +81 -0
  53. package/dist/atoms/content/image/Image.d.ts.map +1 -0
  54. package/dist/atoms/content/image/Image.js +293 -0
  55. package/dist/atoms/content/image/Image.js.map +1 -0
  56. package/dist/atoms/content/image/image.scss +77 -0
  57. package/dist/atoms/content/text/Text.d.ts +58 -0
  58. package/dist/atoms/content/text/Text.d.ts.map +1 -0
  59. package/dist/atoms/content/text/Text.js +158 -0
  60. package/dist/atoms/content/text/Text.js.map +1 -0
  61. package/dist/atoms/content/text/text.scss +98 -0
  62. package/dist/atoms/content/tile/Tile.d.ts +66 -0
  63. package/dist/atoms/content/tile/Tile.d.ts.map +1 -0
  64. package/dist/atoms/content/tile/Tile.js +125 -0
  65. package/dist/atoms/content/tile/Tile.js.map +1 -0
  66. package/dist/atoms/content/tile/tile.scss +122 -0
  67. package/dist/atoms/feedback/tooltip/Tooltip.d.ts +44 -0
  68. package/dist/atoms/feedback/tooltip/Tooltip.d.ts.map +1 -0
  69. package/dist/atoms/feedback/tooltip/Tooltip.js +121 -0
  70. package/dist/atoms/feedback/tooltip/Tooltip.js.map +1 -0
  71. package/dist/atoms/feedback/tooltip/tooltip.scss +96 -0
  72. package/dist/atoms/forms/checkbox/Checkbox.d.ts +49 -0
  73. package/dist/atoms/forms/checkbox/Checkbox.d.ts.map +1 -0
  74. package/dist/atoms/forms/checkbox/Checkbox.js +269 -0
  75. package/dist/atoms/forms/checkbox/Checkbox.js.map +1 -0
  76. package/dist/atoms/forms/checkbox/CheckboxGroup.d.ts +50 -0
  77. package/dist/atoms/forms/checkbox/CheckboxGroup.d.ts.map +1 -0
  78. package/dist/atoms/forms/checkbox/CheckboxGroup.js +132 -0
  79. package/dist/atoms/forms/checkbox/CheckboxGroup.js.map +1 -0
  80. package/dist/atoms/forms/checkbox/checkbox.scss +506 -0
  81. package/dist/atoms/forms/file-picker/FilePicker.d.ts +23 -0
  82. package/dist/atoms/forms/file-picker/FilePicker.d.ts.map +1 -0
  83. package/dist/atoms/forms/file-picker/FilePicker.js +103 -0
  84. package/dist/atoms/forms/file-picker/FilePicker.js.map +1 -0
  85. package/dist/atoms/forms/file-picker/file-picker.scss +84 -0
  86. package/dist/atoms/forms/form-field/FormField.d.ts +39 -0
  87. package/dist/atoms/forms/form-field/FormField.d.ts.map +1 -0
  88. package/dist/atoms/forms/form-field/FormField.js +139 -0
  89. package/dist/atoms/forms/form-field/FormField.js.map +1 -0
  90. package/dist/atoms/forms/form-field/form-field.scss +46 -0
  91. package/dist/atoms/forms/input/Input.d.ts +81 -0
  92. package/dist/atoms/forms/input/Input.d.ts.map +1 -0
  93. package/dist/atoms/forms/input/Input.js +417 -0
  94. package/dist/atoms/forms/input/Input.js.map +1 -0
  95. package/dist/atoms/forms/input/input.scss +547 -0
  96. package/dist/atoms/forms/radio/Radio.d.ts +54 -0
  97. package/dist/atoms/forms/radio/Radio.d.ts.map +1 -0
  98. package/dist/atoms/forms/radio/Radio.js +278 -0
  99. package/dist/atoms/forms/radio/Radio.js.map +1 -0
  100. package/dist/atoms/forms/radio/RadioGroup.d.ts +54 -0
  101. package/dist/atoms/forms/radio/RadioGroup.d.ts.map +1 -0
  102. package/dist/atoms/forms/radio/RadioGroup.js +137 -0
  103. package/dist/atoms/forms/radio/RadioGroup.js.map +1 -0
  104. package/dist/atoms/forms/radio/radio.scss +459 -0
  105. package/dist/atoms/forms/select/Select.d.ts +57 -0
  106. package/dist/atoms/forms/select/Select.d.ts.map +1 -0
  107. package/dist/atoms/forms/select/Select.js +457 -0
  108. package/dist/atoms/forms/select/Select.js.map +1 -0
  109. package/dist/atoms/forms/select/select-dropdown.d.ts +49 -0
  110. package/dist/atoms/forms/select/select-dropdown.d.ts.map +1 -0
  111. package/dist/atoms/forms/select/select-dropdown.js +305 -0
  112. package/dist/atoms/forms/select/select-dropdown.js.map +1 -0
  113. package/dist/atoms/forms/select/select-keyboard.d.ts +14 -0
  114. package/dist/atoms/forms/select/select-keyboard.d.ts.map +1 -0
  115. package/dist/atoms/forms/select/select-keyboard.js +182 -0
  116. package/dist/atoms/forms/select/select-keyboard.js.map +1 -0
  117. package/dist/atoms/forms/select/select.scss +630 -0
  118. package/dist/atoms/forms/textarea/Textarea.d.ts +69 -0
  119. package/dist/atoms/forms/textarea/Textarea.d.ts.map +1 -0
  120. package/dist/atoms/forms/textarea/Textarea.js +394 -0
  121. package/dist/atoms/forms/textarea/Textarea.js.map +1 -0
  122. package/dist/atoms/forms/textarea/textarea.scss +486 -0
  123. package/dist/atoms/forms/toggle/Toggle.d.ts +47 -0
  124. package/dist/atoms/forms/toggle/Toggle.d.ts.map +1 -0
  125. package/dist/atoms/forms/toggle/Toggle.js +243 -0
  126. package/dist/atoms/forms/toggle/Toggle.js.map +1 -0
  127. package/dist/atoms/forms/toggle/toggle.scss +561 -0
  128. package/dist/compiler.d.ts +7 -0
  129. package/dist/compiler.d.ts.map +1 -0
  130. package/dist/compiler.js +18 -0
  131. package/dist/compiler.js.map +1 -0
  132. package/dist/icons/index.d.ts +14 -0
  133. package/dist/icons/index.d.ts.map +1 -0
  134. package/dist/icons/index.js +14 -0
  135. package/dist/icons/index.js.map +1 -0
  136. package/dist/icons/registry.d.ts +65 -0
  137. package/dist/icons/registry.d.ts.map +1 -0
  138. package/dist/icons/registry.js +126 -0
  139. package/dist/icons/registry.js.map +1 -0
  140. package/dist/index.d.ts +55 -0
  141. package/dist/index.d.ts.map +1 -0
  142. package/dist/index.js +64 -0
  143. package/dist/index.js.map +1 -0
  144. package/dist/layout/Grid.d.ts +78 -0
  145. package/dist/layout/Grid.d.ts.map +1 -0
  146. package/dist/layout/Grid.js +272 -0
  147. package/dist/layout/Grid.js.map +1 -0
  148. package/dist/layout/GridItem.d.ts +52 -0
  149. package/dist/layout/GridItem.d.ts.map +1 -0
  150. package/dist/layout/GridItem.js +99 -0
  151. package/dist/layout/GridItem.js.map +1 -0
  152. package/dist/layout/PageSection.d.ts +43 -0
  153. package/dist/layout/PageSection.d.ts.map +1 -0
  154. package/dist/layout/PageSection.js +75 -0
  155. package/dist/layout/PageSection.js.map +1 -0
  156. package/dist/layout/SmartContainer.d.ts +66 -0
  157. package/dist/layout/SmartContainer.d.ts.map +1 -0
  158. package/dist/layout/SmartContainer.js +194 -0
  159. package/dist/layout/SmartContainer.js.map +1 -0
  160. package/dist/layout/Stack.d.ts +65 -0
  161. package/dist/layout/Stack.d.ts.map +1 -0
  162. package/dist/layout/Stack.js +114 -0
  163. package/dist/layout/Stack.js.map +1 -0
  164. package/dist/organisms/content/Card.d.ts +93 -0
  165. package/dist/organisms/content/Card.d.ts.map +1 -0
  166. package/dist/organisms/content/Card.js +353 -0
  167. package/dist/organisms/content/Card.js.map +1 -0
  168. package/dist/organisms/content/_card-horizontal.scss +88 -0
  169. package/dist/organisms/content/_card-link.scss +49 -0
  170. package/dist/organisms/content/_card-overlay.scss +91 -0
  171. package/dist/organisms/content/_card-root.scss +99 -0
  172. package/dist/organisms/content/_card-slots.scss +143 -0
  173. package/dist/organisms/content/_card-states.scss +166 -0
  174. package/dist/organisms/content/_card-tokens.scss +22 -0
  175. package/dist/organisms/content/_card-variants.scss +31 -0
  176. package/dist/organisms/content/card.scss +15 -0
  177. package/dist/organisms/feedback/Modal.d.ts +39 -0
  178. package/dist/organisms/feedback/Modal.d.ts.map +1 -0
  179. package/dist/organisms/feedback/Modal.js +120 -0
  180. package/dist/organisms/feedback/Modal.js.map +1 -0
  181. package/dist/organisms/feedback/Popover.d.ts +30 -0
  182. package/dist/organisms/feedback/Popover.d.ts.map +1 -0
  183. package/dist/organisms/feedback/Popover.js +151 -0
  184. package/dist/organisms/feedback/Popover.js.map +1 -0
  185. package/dist/organisms/feedback/modal.scss +66 -0
  186. package/dist/organisms/feedback/popover.scss +27 -0
  187. package/dist/organisms/forms/DynamicForm.d.ts +118 -0
  188. package/dist/organisms/forms/DynamicForm.d.ts.map +1 -0
  189. package/dist/organisms/forms/DynamicForm.js +546 -0
  190. package/dist/organisms/forms/DynamicForm.js.map +1 -0
  191. package/dist/organisms/forms/Form.d.ts +62 -0
  192. package/dist/organisms/forms/Form.d.ts.map +1 -0
  193. package/dist/organisms/forms/Form.js +131 -0
  194. package/dist/organisms/forms/Form.js.map +1 -0
  195. package/dist/organisms/forms/dynamic-form.scss +91 -0
  196. package/dist/organisms/forms/form-helpers.d.ts +21 -0
  197. package/dist/organisms/forms/form-helpers.d.ts.map +1 -0
  198. package/dist/organisms/forms/form-helpers.js +57 -0
  199. package/dist/organisms/forms/form-helpers.js.map +1 -0
  200. package/dist/organisms/forms/form-state.d.ts +66 -0
  201. package/dist/organisms/forms/form-state.d.ts.map +1 -0
  202. package/dist/organisms/forms/form-state.js +156 -0
  203. package/dist/organisms/forms/form-state.js.map +1 -0
  204. package/dist/organisms/forms/form.scss +23 -0
  205. package/dist/organisms/forms/validation.d.ts +32 -0
  206. package/dist/organisms/forms/validation.d.ts.map +1 -0
  207. package/dist/organisms/forms/validation.js +118 -0
  208. package/dist/organisms/forms/validation.js.map +1 -0
  209. package/dist/organisms/navigation/Navbar.d.ts +66 -0
  210. package/dist/organisms/navigation/Navbar.d.ts.map +1 -0
  211. package/dist/organisms/navigation/Navbar.js +881 -0
  212. package/dist/organisms/navigation/Navbar.js.map +1 -0
  213. package/dist/organisms/navigation/_navbar-announcement.scss +62 -0
  214. package/dist/organisms/navigation/_navbar-brand.scss +69 -0
  215. package/dist/organisms/navigation/_navbar-container.scss +37 -0
  216. package/dist/organisms/navigation/_navbar-desktop.scss +116 -0
  217. package/dist/organisms/navigation/_navbar-drawer.scss +97 -0
  218. package/dist/organisms/navigation/_navbar-links.scss +143 -0
  219. package/dist/organisms/navigation/_navbar-menu.scss +193 -0
  220. package/dist/organisms/navigation/_navbar-root.scss +107 -0
  221. package/dist/organisms/navigation/_navbar-search.scss +83 -0
  222. package/dist/organisms/navigation/_navbar-toggle.scss +91 -0
  223. package/dist/organisms/navigation/_navbar-tokens.scss +15 -0
  224. package/dist/organisms/navigation/navbar.scss +17 -0
  225. package/dist/registry/categories.d.ts +6 -0
  226. package/dist/registry/categories.d.ts.map +1 -0
  227. package/dist/registry/categories.js +13 -0
  228. package/dist/registry/categories.js.map +1 -0
  229. package/dist/registry/components.d.ts +5 -0
  230. package/dist/registry/components.d.ts.map +1 -0
  231. package/dist/registry/components.js +95 -0
  232. package/dist/registry/components.js.map +1 -0
  233. package/dist/registry/index.d.ts +59 -0
  234. package/dist/registry/index.d.ts.map +1 -0
  235. package/dist/registry/index.js +79 -0
  236. package/dist/registry/index.js.map +1 -0
  237. package/dist/registry/levels.d.ts +6 -0
  238. package/dist/registry/levels.d.ts.map +1 -0
  239. package/dist/registry/levels.js +9 -0
  240. package/dist/registry/levels.js.map +1 -0
  241. package/dist/registry/registry-meta-types.d.ts +67 -0
  242. package/dist/registry/registry-meta-types.d.ts.map +1 -0
  243. package/dist/registry/registry-meta-types.js +6 -0
  244. package/dist/registry/registry-meta-types.js.map +1 -0
  245. package/dist/registry/registry-meta.d.ts +5 -0
  246. package/dist/registry/registry-meta.d.ts.map +1 -0
  247. package/dist/registry/registry-meta.js +731 -0
  248. package/dist/registry/registry-meta.js.map +1 -0
  249. package/dist/registry/renderer.d.ts +69 -0
  250. package/dist/registry/renderer.d.ts.map +1 -0
  251. package/dist/registry/renderer.js +311 -0
  252. package/dist/registry/renderer.js.map +1 -0
  253. package/dist/sections/_section-base.scss +204 -0
  254. package/dist/sections/contact/ContactSection.d.ts +55 -0
  255. package/dist/sections/contact/ContactSection.d.ts.map +1 -0
  256. package/dist/sections/contact/ContactSection.js +142 -0
  257. package/dist/sections/contact/ContactSection.js.map +1 -0
  258. package/dist/sections/contact/contact-section.scss +142 -0
  259. package/dist/sections/cta/CTASection.d.ts +52 -0
  260. package/dist/sections/cta/CTASection.d.ts.map +1 -0
  261. package/dist/sections/cta/CTASection.js +130 -0
  262. package/dist/sections/cta/CTASection.js.map +1 -0
  263. package/dist/sections/cta/cta-section.scss +131 -0
  264. package/dist/sections/entrance.d.ts +29 -0
  265. package/dist/sections/entrance.d.ts.map +1 -0
  266. package/dist/sections/entrance.js +69 -0
  267. package/dist/sections/entrance.js.map +1 -0
  268. package/dist/sections/features/FeaturesSection.d.ts +54 -0
  269. package/dist/sections/features/FeaturesSection.d.ts.map +1 -0
  270. package/dist/sections/features/FeaturesSection.js +139 -0
  271. package/dist/sections/features/FeaturesSection.js.map +1 -0
  272. package/dist/sections/features/features-section.scss +140 -0
  273. package/dist/sections/footer/FooterSection.d.ts +53 -0
  274. package/dist/sections/footer/FooterSection.d.ts.map +1 -0
  275. package/dist/sections/footer/FooterSection.js +147 -0
  276. package/dist/sections/footer/FooterSection.js.map +1 -0
  277. package/dist/sections/footer/footer-section.scss +131 -0
  278. package/dist/sections/hero/HeroSection.d.ts +66 -0
  279. package/dist/sections/hero/HeroSection.d.ts.map +1 -0
  280. package/dist/sections/hero/HeroSection.js +156 -0
  281. package/dist/sections/hero/HeroSection.js.map +1 -0
  282. package/dist/sections/hero/hero-section.scss +211 -0
  283. package/dist/shared/_form-animations.scss +283 -0
  284. package/dist/shared/_media-fit.scss +63 -0
  285. package/dist/shared/_mixins.scss +69 -0
  286. package/dist/shared/_tokens.scss +116 -0
  287. package/dist/shared/badge.d.ts +15 -0
  288. package/dist/shared/badge.d.ts.map +1 -0
  289. package/dist/shared/badge.js +15 -0
  290. package/dist/shared/badge.js.map +1 -0
  291. package/dist/shared/button.d.ts +22 -0
  292. package/dist/shared/button.d.ts.map +1 -0
  293. package/dist/shared/button.js +22 -0
  294. package/dist/shared/button.js.map +1 -0
  295. package/dist/shared/card.d.ts +21 -0
  296. package/dist/shared/card.d.ts.map +1 -0
  297. package/dist/shared/card.js +38 -0
  298. package/dist/shared/card.js.map +1 -0
  299. package/dist/shared/checkbox.d.ts +10 -0
  300. package/dist/shared/checkbox.d.ts.map +1 -0
  301. package/dist/shared/checkbox.js +28 -0
  302. package/dist/shared/checkbox.js.map +1 -0
  303. package/dist/shared/clickable.d.ts +34 -0
  304. package/dist/shared/clickable.d.ts.map +1 -0
  305. package/dist/shared/clickable.js +54 -0
  306. package/dist/shared/clickable.js.map +1 -0
  307. package/dist/shared/common.d.ts +31 -0
  308. package/dist/shared/common.d.ts.map +1 -0
  309. package/dist/shared/common.js +92 -0
  310. package/dist/shared/common.js.map +1 -0
  311. package/dist/shared/entrance-config.d.ts +46 -0
  312. package/dist/shared/entrance-config.d.ts.map +1 -0
  313. package/dist/shared/entrance-config.js +54 -0
  314. package/dist/shared/entrance-config.js.map +1 -0
  315. package/dist/shared/focusable.d.ts +8 -0
  316. package/dist/shared/focusable.d.ts.map +1 -0
  317. package/dist/shared/focusable.js +17 -0
  318. package/dist/shared/focusable.js.map +1 -0
  319. package/dist/shared/form-elements.d.ts +57 -0
  320. package/dist/shared/form-elements.d.ts.map +1 -0
  321. package/dist/shared/form-elements.js +95 -0
  322. package/dist/shared/form-elements.js.map +1 -0
  323. package/dist/shared/form-state.d.ts +52 -0
  324. package/dist/shared/form-state.d.ts.map +1 -0
  325. package/dist/shared/form-state.js +151 -0
  326. package/dist/shared/form-state.js.map +1 -0
  327. package/dist/shared/grid.d.ts +21 -0
  328. package/dist/shared/grid.d.ts.map +1 -0
  329. package/dist/shared/grid.js +187 -0
  330. package/dist/shared/grid.js.map +1 -0
  331. package/dist/shared/icon-slot.d.ts +22 -0
  332. package/dist/shared/icon-slot.d.ts.map +1 -0
  333. package/dist/shared/icon-slot.js +38 -0
  334. package/dist/shared/icon-slot.js.map +1 -0
  335. package/dist/shared/icon.d.ts +17 -0
  336. package/dist/shared/icon.d.ts.map +1 -0
  337. package/dist/shared/icon.js +18 -0
  338. package/dist/shared/icon.js.map +1 -0
  339. package/dist/shared/icons.d.ts +19 -0
  340. package/dist/shared/icons.d.ts.map +1 -0
  341. package/dist/shared/icons.js +22 -0
  342. package/dist/shared/icons.js.map +1 -0
  343. package/dist/shared/image.d.ts +35 -0
  344. package/dist/shared/image.d.ts.map +1 -0
  345. package/dist/shared/image.js +46 -0
  346. package/dist/shared/image.js.map +1 -0
  347. package/dist/shared/input.d.ts +12 -0
  348. package/dist/shared/input.d.ts.map +1 -0
  349. package/dist/shared/input.js +29 -0
  350. package/dist/shared/input.js.map +1 -0
  351. package/dist/shared/radio.d.ts +10 -0
  352. package/dist/shared/radio.d.ts.map +1 -0
  353. package/dist/shared/radio.js +29 -0
  354. package/dist/shared/radio.js.map +1 -0
  355. package/dist/shared/reconcile-list.d.ts +37 -0
  356. package/dist/shared/reconcile-list.d.ts.map +1 -0
  357. package/dist/shared/reconcile-list.js +95 -0
  358. package/dist/shared/reconcile-list.js.map +1 -0
  359. package/dist/shared/section.d.ts +23 -0
  360. package/dist/shared/section.d.ts.map +1 -0
  361. package/dist/shared/section.js +65 -0
  362. package/dist/shared/section.js.map +1 -0
  363. package/dist/shared/segmented.d.ts +17 -0
  364. package/dist/shared/segmented.d.ts.map +1 -0
  365. package/dist/shared/segmented.js +53 -0
  366. package/dist/shared/segmented.js.map +1 -0
  367. package/dist/shared/select.d.ts +18 -0
  368. package/dist/shared/select.d.ts.map +1 -0
  369. package/dist/shared/select.js +14 -0
  370. package/dist/shared/select.js.map +1 -0
  371. package/dist/shared/slots.d.ts +11 -0
  372. package/dist/shared/slots.d.ts.map +1 -0
  373. package/dist/shared/slots.js +33 -0
  374. package/dist/shared/slots.js.map +1 -0
  375. package/dist/shared/smart-container.d.ts +19 -0
  376. package/dist/shared/smart-container.d.ts.map +1 -0
  377. package/dist/shared/smart-container.js +29 -0
  378. package/dist/shared/smart-container.js.map +1 -0
  379. package/dist/shared/text.d.ts +29 -0
  380. package/dist/shared/text.d.ts.map +1 -0
  381. package/dist/shared/text.js +72 -0
  382. package/dist/shared/text.js.map +1 -0
  383. package/dist/shared/textarea.d.ts +6 -0
  384. package/dist/shared/textarea.d.ts.map +1 -0
  385. package/dist/shared/textarea.js +18 -0
  386. package/dist/shared/textarea.js.map +1 -0
  387. package/dist/shared/toggle.d.ts +6 -0
  388. package/dist/shared/toggle.d.ts.map +1 -0
  389. package/dist/shared/toggle.js +19 -0
  390. package/dist/shared/toggle.js.map +1 -0
  391. package/dist/shared/types.d.ts +41 -0
  392. package/dist/shared/types.d.ts.map +1 -0
  393. package/dist/shared/types.js +20 -0
  394. package/dist/shared/types.js.map +1 -0
  395. package/dist/structural/ErrorBoundary.d.ts +18 -0
  396. package/dist/structural/ErrorBoundary.d.ts.map +1 -0
  397. package/dist/structural/ErrorBoundary.js +119 -0
  398. package/dist/structural/ErrorBoundary.js.map +1 -0
  399. package/dist/structural/For.d.ts +37 -0
  400. package/dist/structural/For.d.ts.map +1 -0
  401. package/dist/structural/For.js +129 -0
  402. package/dist/structural/For.js.map +1 -0
  403. package/dist/structural/Lazy.d.ts +43 -0
  404. package/dist/structural/Lazy.d.ts.map +1 -0
  405. package/dist/structural/Lazy.js +47 -0
  406. package/dist/structural/Lazy.js.map +1 -0
  407. package/dist/structural/NavLink.d.ts +45 -0
  408. package/dist/structural/NavLink.d.ts.map +1 -0
  409. package/dist/structural/NavLink.js +37 -0
  410. package/dist/structural/NavLink.js.map +1 -0
  411. package/dist/structural/Show.d.ts +35 -0
  412. package/dist/structural/Show.d.ts.map +1 -0
  413. package/dist/structural/Show.js +34 -0
  414. package/dist/structural/Show.js.map +1 -0
  415. package/dist/structural/nav-link.scss +54 -0
  416. package/dist/styles/index.scss +58 -0
  417. package/package.json +64 -0
@@ -0,0 +1,506 @@
1
+ /// Checkbox component styles — premium edition.
2
+ /// Native input is visually hidden; the .ui-checkbox-box element renders the
3
+ /// box in CSS, while the checkmark and indeterminate dash are rendered by an
4
+ /// inline SVG mark element (.ui-checkbox-mark).
5
+ ///
6
+ /// @group atoms/forms
7
+
8
+ @use 'sass:map';
9
+ @use '@pithyjs/design-system/a11y/styles/mixins' as a11y;
10
+ @use '@pithyjs/design-system/borders/styles/tokens' as borders;
11
+ @use '../../../shared/tokens' as shared;
12
+ @use '../../../shared/form-animations' as form-anim;
13
+
14
+ // ============================================
15
+ // Wrapper <label>
16
+ // ============================================
17
+
18
+ .ui-checkbox {
19
+ // Single color family per state — declared on the wrapper so both the
20
+ // box and the label inherit it. Overridden by [data-success] / [data-error].
21
+ --_cmp-color: var(--color-primary);
22
+ --_cmp-color-hover: var(--color-primary-hover);
23
+
24
+ @include a11y.touch-target-pseudo; // WCAG 2.5.5 — 44×44 invisible hit area
25
+
26
+ display: inline-flex;
27
+ align-items: center;
28
+ gap: var(--space-xs); // Lovers — box ↔ label
29
+ cursor: pointer;
30
+ position: relative;
31
+ user-select: none;
32
+ color: var(--color-text);
33
+
34
+ @include a11y.motion-safe {
35
+ transition: var(--motion-transition-color);
36
+ }
37
+ }
38
+
39
+ // Field wrapper (when helper/error is rendered)
40
+ // No gap — child .ui-form-helper / .ui-form-error already carry
41
+ // margin-block-start: var(--space-xs), consistent with other form atoms.
42
+ .ui-checkbox-field {
43
+ display: inline-flex;
44
+ flex-direction: column;
45
+ }
46
+
47
+ // ============================================
48
+ // Native input — visually hidden but functional
49
+ // ============================================
50
+
51
+ .ui-checkbox-input {
52
+ // sr-only — keeps the input in the layout (focusable, click-forwards via
53
+ // <label>), but visually hidden so the custom box renders the state.
54
+ position: absolute;
55
+ inline-size: 1px;
56
+ block-size: 1px;
57
+ padding: 0;
58
+ margin: 0;
59
+ overflow: hidden;
60
+ clip: rect(0 0 0 0);
61
+ clip-path: inset(50%);
62
+ white-space: nowrap;
63
+ border: 0;
64
+ }
65
+
66
+ // ============================================
67
+ // Custom box
68
+ // ============================================
69
+
70
+ .ui-checkbox-box {
71
+ // Colored micro-shadow — switched on by checked / indeterminate, off by
72
+ // default. Uses the CSS `transparent` keyword (not a raw color value) so
73
+ // the focus rule can layer the ring on top with a comma list.
74
+ --_cmp-shadow: 0 0 transparent;
75
+
76
+ display: inline-flex;
77
+ align-items: center;
78
+ justify-content: center;
79
+ flex-shrink: 0;
80
+ inline-size: var(--_cmp-box-size);
81
+ block-size: var(--_cmp-box-size);
82
+ background-color: var(--color-surface);
83
+ border: borders.border(control);
84
+ border-radius: var(--radius-sm);
85
+ position: relative;
86
+ color: var(--color-on-primary);
87
+ box-shadow: var(--_cmp-shadow);
88
+
89
+ @include a11y.motion-safe {
90
+ transition:
91
+ var(--motion-transition-background),
92
+ var(--motion-transition-border),
93
+ var(--motion-transition-color),
94
+ box-shadow var(--motion-duration-normal) var(--motion-easing-entrance);
95
+ }
96
+
97
+ // Box pop on check — fires every time the box transitions to the
98
+ // checked / indeterminate state. Springy easing gives the tactile feel.
99
+ // The animation is triggered when the wrapper matches a :has()
100
+ // selector for a descendant .ui-checkbox-input:checked or :indeterminate,
101
+ // so consumers don't need to wire JS.
102
+ // fill-mode: both is set in the form-pop animation shorthand.
103
+ }
104
+
105
+ // ============================================
106
+ // SVG mark (checkmark + indeterminate dash)
107
+ // ============================================
108
+
109
+ .ui-checkbox-mark {
110
+ position: absolute;
111
+ inset: 0;
112
+ inline-size: 100%;
113
+ block-size: 100%;
114
+ pointer-events: none;
115
+ overflow: visible;
116
+ }
117
+
118
+ .ui-checkbox-mark-check,
119
+ .ui-checkbox-mark-dash {
120
+ // pathLength=1 normalises every path to a unit length, so the same
121
+ // dash plumbing works for any future shape.
122
+ stroke-dasharray: 1;
123
+ stroke-dashoffset: 1;
124
+
125
+ @include a11y.motion-safe {
126
+ transition: stroke-dashoffset var(--motion-duration-normal)
127
+ var(--motion-easing-entrance);
128
+ }
129
+ }
130
+
131
+ // ============================================
132
+ // Visible label text
133
+ // ============================================
134
+
135
+ .ui-checkbox-label {
136
+ font-size: var(--_cmp-font-size);
137
+ line-height: var(--leading-snug);
138
+ color: inherit;
139
+
140
+ // Branded selection — matches the active state color so an error checkbox
141
+ // selects in danger, success in success, default in primary.
142
+ &::selection {
143
+ background-color: color-mix(
144
+ in oklch,
145
+ var(--_cmp-color) calc(var(--state-selected-opacity) * 100%),
146
+ transparent
147
+ );
148
+ color: inherit;
149
+ }
150
+ }
151
+
152
+ // ============================================
153
+ // Sizes — set custom props per control size
154
+ // ============================================
155
+
156
+ @each $size in shared.$control-sizes {
157
+ .ui-checkbox[data-size='#{$size}'] {
158
+ --_cmp-box-size: #{map.get(shared.$control-indicator-sizes, $size)};
159
+ --_cmp-font-size: #{map.get(shared.$control-font-sizes, $size)};
160
+ }
161
+ }
162
+
163
+ // ============================================
164
+ // Checked state
165
+ // ============================================
166
+
167
+ .ui-checkbox:has(.ui-checkbox-input:checked) .ui-checkbox-box {
168
+ background-color: var(--_cmp-color);
169
+ border-color: var(--_cmp-color);
170
+ // Colored micro-shadow under the box — gives the check visual weight.
171
+ // Uses --shadow-base-* tokens for offset / blur consistency with the rest
172
+ // of the kit, then color-mixes the active state color in at the configured
173
+ // shadow opacity.
174
+ --_cmp-shadow: 0 var(--shadow-base-offset-y) var(--shadow-base-blur)
175
+ calc(var(--shadow-base-offset-y) * -1)
176
+ color-mix(
177
+ in oklch,
178
+ var(--_cmp-color) #{shared.$checked-glow-opacity},
179
+ transparent
180
+ );
181
+
182
+ .ui-checkbox-mark-check {
183
+ stroke-dashoffset: 0;
184
+ }
185
+ }
186
+
187
+ // Box pop fires every time we transition into checked / indeterminate.
188
+ // Animation lives in the shared form-animations mixin so Radio + Toggle
189
+ // inherit it for free.
190
+ @include form-anim.form-pop(
191
+ '.ui-checkbox:has(.ui-checkbox-input:checked) .ui-checkbox-box'
192
+ );
193
+ @include form-anim.form-pop(
194
+ '.ui-checkbox:has(.ui-checkbox-input:indeterminate) .ui-checkbox-box'
195
+ );
196
+
197
+ // ============================================
198
+ // Indeterminate state — replaces checkmark with a horizontal dash
199
+ // ============================================
200
+
201
+ .ui-checkbox:has(.ui-checkbox-input:indeterminate) .ui-checkbox-box {
202
+ background-color: var(--_cmp-color);
203
+ border-color: var(--_cmp-color);
204
+ --_cmp-shadow: 0 var(--shadow-base-offset-y) var(--shadow-base-blur)
205
+ calc(var(--shadow-base-offset-y) * -1)
206
+ color-mix(
207
+ in oklch,
208
+ var(--_cmp-color) #{shared.$checked-glow-opacity},
209
+ transparent
210
+ );
211
+
212
+ .ui-checkbox-mark-dash {
213
+ stroke-dashoffset: 0;
214
+ }
215
+ }
216
+
217
+ // ============================================
218
+ // Hover (not disabled / not readonly)
219
+ // ============================================
220
+
221
+ .ui-checkbox:hover:not([data-disabled]):not([data-readonly]):not(
222
+ :has(.ui-checkbox-input:disabled)
223
+ )
224
+ .ui-checkbox-box {
225
+ border-color: var(--_cmp-color);
226
+ }
227
+
228
+ .ui-checkbox:hover:not([data-disabled]):not([data-readonly]):not(
229
+ :has(.ui-checkbox-input:disabled)
230
+ ):has(.ui-checkbox-input:checked)
231
+ .ui-checkbox-box,
232
+ .ui-checkbox:hover:not([data-disabled]):not([data-readonly]):not(
233
+ :has(.ui-checkbox-input:disabled)
234
+ ):has(.ui-checkbox-input:indeterminate)
235
+ .ui-checkbox-box {
236
+ background-color: var(--_cmp-color-hover);
237
+ border-color: var(--_cmp-color-hover);
238
+ }
239
+
240
+ // ============================================
241
+ // Focus — bridge native input focus to the box
242
+ // ============================================
243
+
244
+ .ui-checkbox:has(.ui-checkbox-input:focus-visible) .ui-checkbox-box {
245
+ outline: none;
246
+ --ring-offset: #{shared.$focus-ring-offset};
247
+ // Layer the focus ring on top of the colored micro-shadow so a focused
248
+ // checked checkbox shows both ring and glow.
249
+ box-shadow: borders.ring(), var(--_cmp-shadow);
250
+ }
251
+
252
+ // ============================================
253
+ // Active / pressed feedback
254
+ // ============================================
255
+
256
+ .ui-checkbox:not([data-disabled]):not([data-readonly]):not(
257
+ :has(.ui-checkbox-input:disabled)
258
+ ):active
259
+ .ui-checkbox-box {
260
+ @include a11y.state-background(pressed, var(--_cmp-color));
261
+
262
+ // Immediate tactile compression while the pointer is held — release
263
+ // hands off to the box-pop animation defined below.
264
+ @include a11y.motion-safe {
265
+ transform: scale(var(--motion-scale-big));
266
+ transition: transform var(--motion-duration-fast)
267
+ var(--motion-easing-standard);
268
+ }
269
+ }
270
+
271
+ // ============================================
272
+ // Success state
273
+ // ============================================
274
+
275
+ .ui-checkbox[data-success] {
276
+ --_cmp-color: var(--color-success);
277
+ --_cmp-color-hover: var(--color-success-hover, var(--color-success));
278
+ }
279
+
280
+ .ui-checkbox[data-success] .ui-checkbox-box {
281
+ border-color: var(--_cmp-color);
282
+ }
283
+
284
+ .ui-checkbox[data-success]:has(.ui-checkbox-input:focus-visible)
285
+ .ui-checkbox-box {
286
+ --ring-color: var(--color-success);
287
+ box-shadow: borders.ring(), var(--_cmp-shadow);
288
+ }
289
+
290
+ // ============================================
291
+ // Error state (after success — source order wins)
292
+ // ============================================
293
+
294
+ .ui-checkbox[data-error] {
295
+ --_cmp-color: var(--color-danger);
296
+ --_cmp-color-hover: var(--color-danger-hover, var(--color-danger));
297
+ }
298
+
299
+ .ui-checkbox[data-error] .ui-checkbox-box {
300
+ border-color: var(--_cmp-color);
301
+ }
302
+
303
+ .ui-checkbox[data-error]:has(.ui-checkbox-input:focus-visible)
304
+ .ui-checkbox-box {
305
+ --ring-color: var(--color-danger);
306
+ box-shadow: borders.ring(), var(--_cmp-shadow);
307
+ }
308
+
309
+ .ui-checkbox[data-error] .ui-checkbox-label {
310
+ color: var(--color-danger);
311
+ }
312
+
313
+ // ============================================
314
+ // Error shake animation
315
+ // ============================================
316
+
317
+ @include form-anim.form-shake('.ui-checkbox-shake');
318
+
319
+ // ============================================
320
+ // Disabled state
321
+ // ============================================
322
+
323
+ .ui-checkbox[data-disabled] {
324
+ opacity: var(--state-disabled-opacity);
325
+ // Desaturate so the colors actually look deactivated, not just dimmed.
326
+ // Combined with opacity, this gives the proper "this control is off" feel.
327
+ filter: saturate(shared.$disabled-saturation);
328
+ cursor: not-allowed;
329
+
330
+ .ui-checkbox-input {
331
+ cursor: not-allowed;
332
+ }
333
+ }
334
+
335
+ // Fieldset[disabled] cascade — when a checkbox is disabled via a parent
336
+ // <fieldset disabled>, the native input is :disabled but the wrapper has no
337
+ // [data-disabled] attribute. Opacity is already handled by the group's
338
+ // .ui-checkbox-group[data-disabled] rule; we only add cursor + desaturation
339
+ // so individual checkboxes look properly deactivated.
340
+ .ui-checkbox:not([data-disabled]):has(.ui-checkbox-input:disabled) {
341
+ filter: saturate(shared.$disabled-saturation);
342
+ cursor: not-allowed;
343
+
344
+ .ui-checkbox-input {
345
+ cursor: not-allowed;
346
+ }
347
+ }
348
+
349
+ // ============================================
350
+ // Readonly state — looks normal, blocks toggling
351
+ // ============================================
352
+
353
+ .ui-checkbox[data-readonly] {
354
+ cursor: default;
355
+
356
+ .ui-checkbox-input {
357
+ cursor: default;
358
+ }
359
+
360
+ // Only override the unchecked background — checked/indeterminate keep
361
+ // their --color-primary fill so the checkmark stays legible.
362
+ .ui-checkbox-input:not(:checked):not(:indeterminate) + .ui-checkbox-box {
363
+ background-color: var(--color-surface-variant);
364
+ }
365
+ }
366
+
367
+ // ============================================
368
+ // Required indicator on label text
369
+ // ============================================
370
+
371
+ .ui-checkbox[data-required] .ui-checkbox-label::after {
372
+ content: ' *';
373
+ color: var(--color-danger);
374
+ font-weight: var(--font-weight-medium);
375
+ }
376
+
377
+ // ============================================
378
+ // Loading spinner — overlays the box
379
+ // ============================================
380
+
381
+ // Hide the checkmark / dash entirely while loading — the spinner is the
382
+ // only signal, regardless of checked state.
383
+ .ui-checkbox.ui-checkbox-loading .ui-checkbox-mark {
384
+ opacity: 0;
385
+ }
386
+
387
+ // Subtle border tint so the user can see something is happening even
388
+ // before the spinner picks up against the surface. Only when not in
389
+ // error/success state — those keep their semantic border color.
390
+ .ui-checkbox.ui-checkbox-loading:not([data-error]):not([data-success])
391
+ .ui-checkbox-box {
392
+ border-color: var(--color-primary);
393
+ }
394
+
395
+ // Spinner color: primary on the empty surface, on-primary when the box is
396
+ // filled (checked / indeterminate). Error and success swap accordingly.
397
+ .ui-checkbox.ui-checkbox-loading .ui-checkbox-box {
398
+ --_cmp-spinner-color: var(--color-primary);
399
+ }
400
+
401
+ .ui-checkbox.ui-checkbox-loading:has(.ui-checkbox-input:checked)
402
+ .ui-checkbox-box,
403
+ .ui-checkbox.ui-checkbox-loading:has(.ui-checkbox-input:indeterminate)
404
+ .ui-checkbox-box {
405
+ --_cmp-spinner-color: var(--color-on-primary);
406
+ }
407
+
408
+ .ui-checkbox[data-error].ui-checkbox-loading .ui-checkbox-box {
409
+ --_cmp-spinner-color: var(--color-danger);
410
+ }
411
+
412
+ // Scoped with :not([data-error]) so error always wins when both flags
413
+ // are set (matches the box border/bg precedence contract).
414
+ .ui-checkbox[data-success]:not([data-error]).ui-checkbox-loading
415
+ .ui-checkbox-box {
416
+ --_cmp-spinner-color: var(--color-success);
417
+ }
418
+
419
+ .ui-checkbox.ui-checkbox-loading .ui-checkbox-box::before {
420
+ content: '';
421
+ position: absolute;
422
+ inset: shared.$spinner-inset;
423
+ border: var(--border-width-medium) solid var(--_cmp-spinner-color);
424
+ border-inline-end-color: transparent;
425
+ border-radius: 50%;
426
+
427
+ @include a11y.motion-safe {
428
+ animation: var(--motion-animation-spin) var(--motion-duration-deliberate)
429
+ linear infinite;
430
+ }
431
+
432
+ @include a11y.motion-reduced {
433
+ border-inline-end-color: var(--_cmp-spinner-color);
434
+ opacity: shared.$spinner-reduced-opacity;
435
+ }
436
+ }
437
+
438
+ // Helper + error text use shared .ui-form-helper / .ui-form-error classes
439
+ // from src/shared/_form-animations.scss — no per-component styles needed.
440
+
441
+ // ============================================
442
+ // Forced colors
443
+ // ============================================
444
+
445
+ @include a11y.forced-colors {
446
+ .ui-checkbox-box {
447
+ border: var(--border-width-hairline) solid ButtonText;
448
+ background: Field;
449
+ }
450
+
451
+ .ui-checkbox:has(.ui-checkbox-input:checked) .ui-checkbox-box,
452
+ .ui-checkbox:has(.ui-checkbox-input:indeterminate) .ui-checkbox-box {
453
+ background: Highlight;
454
+ border-color: Highlight;
455
+ color: HighlightText;
456
+ }
457
+
458
+ .ui-checkbox[data-disabled],
459
+ .ui-checkbox:not([data-disabled]):has(.ui-checkbox-input:disabled) {
460
+ color: GrayText;
461
+
462
+ .ui-checkbox-box {
463
+ border-color: GrayText;
464
+ }
465
+ }
466
+
467
+ .ui-checkbox:has(.ui-checkbox-input:focus-visible) .ui-checkbox-box {
468
+ @include a11y.focus-outline(Highlight);
469
+ }
470
+ }
471
+
472
+ // ============================================
473
+ // CheckboxGroup — fieldset wrapper
474
+ // ============================================
475
+
476
+ .ui-checkbox-group {
477
+ display: flex;
478
+ flex-direction: column;
479
+ gap: var(--space-sm); // Close Friends — controls in a group
480
+ border: none;
481
+ margin: 0;
482
+ padding: 0;
483
+ min-inline-size: 0;
484
+ }
485
+
486
+ .ui-checkbox-group-legend {
487
+ display: block;
488
+ font-size: var(--font-size-sm);
489
+ font-weight: var(--font-weight-medium);
490
+ color: var(--color-text);
491
+ margin-block-end: var(--space-xs);
492
+ padding: 0;
493
+ }
494
+
495
+ // Helper / error text reuses shared .ui-form-helper / .ui-form-error classes
496
+ // from _form-animations.scss — no group-specific overrides needed.
497
+
498
+ .ui-checkbox-group[data-disabled] {
499
+ opacity: var(--state-disabled-opacity);
500
+ }
501
+
502
+ @include a11y.forced-colors {
503
+ .ui-checkbox-group[data-error] .ui-checkbox-group-legend {
504
+ color: inherit;
505
+ }
506
+ }
@@ -0,0 +1,23 @@
1
+ /** @codex { "id": "pithy.ui-kit.file-picker", "title": "<FilePicker> Form Atom", "category": "feature", "risk": "low" } */
2
+ import './file-picker.scss';
3
+ /** @codexApi {"parent":"pithy.ui-kit.file-picker","name":"FilePickerProps","stability":"experimental","signature":"interface FilePickerProps"} */
4
+ export interface FilePickerProps {
5
+ /** Called when the user selects a valid file. May be async (e.g. upload). */
6
+ onSelect: (file: File) => void | Promise<void>;
7
+ /** Accept filter, passed to the input and used for validation (default `"image/*"`). */
8
+ accept?: string;
9
+ /** Maximum file size in bytes (default 5 MB). */
10
+ maxSizeBytes?: number;
11
+ /** Render an image preview of the selected file (default `true`; image files only). */
12
+ showPreview?: boolean;
13
+ /** Drop-zone hint text. */
14
+ hint?: string;
15
+ /** Accessible label for the drop zone. */
16
+ ariaLabel?: string;
17
+ }
18
+ /** @codexApi {"parent":"pithy.ui-kit.file-picker","name":"FilePicker","stability":"experimental","signature":"(props: FilePickerProps) => { el: Node; destroy: () => void }"} */
19
+ export declare function FilePicker({ onSelect, accept, maxSizeBytes, showPreview, hint, ariaLabel, }: FilePickerProps): {
20
+ el: HTMLElement | DocumentFragment;
21
+ destroy: () => void;
22
+ };
23
+ //# sourceMappingURL=FilePicker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FilePicker.d.ts","sourceRoot":"","sources":["../../../../src/atoms/forms/file-picker/FilePicker.ts"],"names":[],"mappings":"AAAA,2HAA2H;AAK3H,OAAO,oBAAoB,CAAC;AAI5B,kJAAkJ;AAClJ,MAAM,WAAW,eAAe;IAC9B,6EAA6E;IAC7E,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,wFAAwF;IACxF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uFAAuF;IACvF,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,2BAA2B;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAkBD,iLAAiL;AACjL,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,MAAkB,EAClB,YAAqC,EACrC,WAAkB,EAClB,IAAkC,EAClC,SAAkD,GACnD,EAAE,eAAe;;;EAmFjB"}
@@ -0,0 +1,103 @@
1
+ /** @codex { "id": "pithy.ui-kit.file-picker", "title": "<FilePicker> Form Atom", "category": "feature", "risk": "low" } */
2
+ import { html, onDestroy } from '@pithyjs/core';
3
+ import { signal } from '@pithyjs/signals';
4
+ import './file-picker.scss';
5
+ const DEFAULT_MAX_SIZE_BYTES = 5 * 1024 * 1024; // 5 MB
6
+ function matchesAccept(file, accept) {
7
+ const tokens = accept
8
+ .split(',')
9
+ .map(t => t.trim().toLowerCase())
10
+ .filter(Boolean);
11
+ if (tokens.length === 0)
12
+ return true;
13
+ const type = file.type.toLowerCase();
14
+ const name = file.name.toLowerCase();
15
+ return tokens.some(tok => {
16
+ if (tok === '*' || tok === '*/*')
17
+ return true;
18
+ if (tok.endsWith('/*'))
19
+ return type.startsWith(tok.slice(0, -1));
20
+ if (tok.startsWith('.'))
21
+ return name.endsWith(tok);
22
+ return type === tok;
23
+ });
24
+ }
25
+ /** @codexApi {"parent":"pithy.ui-kit.file-picker","name":"FilePicker","stability":"experimental","signature":"(props: FilePickerProps) => { el: Node; destroy: () => void }"} */
26
+ export function FilePicker({ onSelect, accept = 'image/*', maxSizeBytes = DEFAULT_MAX_SIZE_BYTES, showPreview = true, hint = 'Click or drag a file here', ariaLabel = 'Upload file — click or drag and drop', }) {
27
+ const previewURL = signal(null);
28
+ const errorMsg = signal('');
29
+ const isDragOver = signal(false);
30
+ let selectionToken = 0;
31
+ // Object-URL for the preview is created outside the template's reactive
32
+ // tracking, so it needs explicit revoke on replace + teardown.
33
+ let currentPreviewURL = null;
34
+ function revokePreview() {
35
+ if (currentPreviewURL) {
36
+ URL.revokeObjectURL(currentPreviewURL);
37
+ currentPreviewURL = null;
38
+ }
39
+ }
40
+ function handleFile(file) {
41
+ const token = ++selectionToken;
42
+ errorMsg.set('');
43
+ revokePreview();
44
+ previewURL.set(null);
45
+ if (!matchesAccept(file, accept)) {
46
+ errorMsg.set('This file type is not accepted.');
47
+ return;
48
+ }
49
+ if (file.size > maxSizeBytes) {
50
+ errorMsg.set(`File is too large. Maximum size is ${maxSizeBytes / 1024 / 1024} MB.`);
51
+ return;
52
+ }
53
+ if (showPreview && file.type.startsWith('image/')) {
54
+ currentPreviewURL = URL.createObjectURL(file);
55
+ previewURL.set(currentPreviewURL);
56
+ }
57
+ Promise.resolve(onSelect(file)).catch(() => {
58
+ if (token === selectionToken)
59
+ errorMsg.set('Upload failed. Please try again.');
60
+ });
61
+ }
62
+ const handleInputChange = (e) => {
63
+ const input = e.target;
64
+ if (input.files && input.files.length > 0)
65
+ handleFile(input.files[0]);
66
+ input.value = '';
67
+ };
68
+ const handleDragOver = () => isDragOver.set(true);
69
+ const handleDragEnter = () => isDragOver.set(true);
70
+ const handleDragLeave = () => isDragOver.set(false);
71
+ const handleDrop = (e) => {
72
+ isDragOver.set(false);
73
+ const file = e.dataTransfer?.files[0];
74
+ if (file)
75
+ handleFile(file);
76
+ };
77
+ const hasPreview = () => previewURL() !== null;
78
+ const previewSrc = () => previewURL() ?? '';
79
+ const hasError = () => errorMsg().length > 0;
80
+ onDestroy(revokePreview);
81
+ return html `
82
+ <div class="ui-file-picker u-vstack u-gap-xs">
83
+ <label class="ui-file-picker-zone"
84
+ [class.ui-file-picker-zone-over]="isDragOver()"
85
+ @dragover.prevent="handleDragOver"
86
+ @dragenter.prevent="handleDragEnter"
87
+ @dragleave="handleDragLeave"
88
+ @drop.prevent="handleDrop">
89
+ <span @if="!hasPreview()" class="ui-file-picker-hint">{{ hint }}</span>
90
+ <span @if="hasPreview()" class="ui-file-picker-preview">
91
+ <Image src="previewSrc" alt="'Selected file preview'" fit="'contain'" />
92
+ </span>
93
+ <input type="file"
94
+ [accept]="accept"
95
+ class="ui-file-picker-input"
96
+ [aria-label]="ariaLabel"
97
+ @change="handleInputChange" />
98
+ </label>
99
+ <span @if="hasError()" class="ui-file-picker-error" aria-live="assertive">{{ errorMsg() }}</span>
100
+ </div>
101
+ `;
102
+ }
103
+ //# sourceMappingURL=FilePicker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FilePicker.js","sourceRoot":"","sources":["../../../../src/atoms/forms/file-picker/FilePicker.ts"],"names":[],"mappings":"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"}