@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,99 @@
1
+ /// Card root article + layout wrapper
2
+ /// @group organisms/content
3
+
4
+ @use '@pithyjs/design-system/a11y/styles/mixins' as a11y;
5
+ @use '../../shared/tokens' as shared;
6
+
7
+ // ============================================
8
+ // Root (the <article>) — carries chrome + acts as the query container
9
+ // ============================================
10
+
11
+ .ui-card {
12
+ // Component-scoped tokens — every variant mutates these, never the global
13
+ // design-system primitives. Defaults match variant="default".
14
+ --_card-bg: var(--color-surface);
15
+ --_card-border-color: var(--color-border);
16
+ --_card-shadow: var(--shadow-xs);
17
+ --_card-radius: var(--radius-md);
18
+ --_card-padding: var(--space-md);
19
+
20
+ // Every card is a query container. `.ui-card-layout` (a descendant) uses
21
+ // @container to switch between vertical and horizontal layouts based on
22
+ // the card's own inline-size. An element cannot query itself — hence the
23
+ // nested layout wrapper.
24
+ container-type: inline-size;
25
+ // container-type: inline-size implies contain: inline-size layout style.
26
+ // We add paint containment explicitly for repaint isolation.
27
+ contain: layout paint;
28
+
29
+ position: relative;
30
+ isolation: isolate;
31
+
32
+ display: block;
33
+ inline-size: 100%;
34
+ min-inline-size: 0;
35
+
36
+ background-color: var(--_card-bg);
37
+ border: var(--border-width-hairline) solid var(--_card-border-color);
38
+ border-radius: var(--_card-radius);
39
+ box-shadow: var(--_card-shadow);
40
+ // Padding lives on `.ui-card-layout`, not on the article — both the
41
+ // layout's padding AND the media's negative-inset margin must resolve
42
+ // against the SAME container-query context. Since `--space-*` tokens
43
+ // use `cqw`, and the card is a query container (`container-type:
44
+ // inline-size`), the article's own `cqw` queries the OUTER container
45
+ // while descendants query the card. Keeping padding on the layout keeps
46
+ // both values in sync so media bleed aligns pixel-perfect.
47
+
48
+ color: var(--color-text);
49
+
50
+ @include a11y.motion-safe {
51
+ transition:
52
+ var(--motion-transition-background),
53
+ var(--motion-transition-border),
54
+ var(--motion-transition-shadow),
55
+ translate var(--motion-duration-normal) var(--motion-easing-standard);
56
+ }
57
+ }
58
+
59
+ // ============================================
60
+ // Layout wrapper — the flex/grid root
61
+ // ============================================
62
+
63
+ .ui-card-layout {
64
+ display: flex;
65
+ flex-direction: column;
66
+ gap: var(--space-sm);
67
+ min-inline-size: 0;
68
+ // Pass through the card's radius so nested slots that use
69
+ // `border-radius: inherit` (media, caption) resolve correctly.
70
+ border-radius: inherit;
71
+ // Padding belongs here (not on the article) so the value resolves against
72
+ // the same container-query context the media's negative-inset margin uses.
73
+ // Both read the card's inline-size, not the outer container's.
74
+ padding: var(--_card-padding);
75
+ // No `z-index` here on purpose — that would create a stacking context and
76
+ // trap interactive descendants' z-index below the pseudo-link overlay.
77
+ // Tree-order keeps layout below .ui-card-link (which comes after it in
78
+ // the DOM) and layout's descendants can freely raise above the link.
79
+ }
80
+
81
+ // ============================================
82
+ // Padding + Radius — mirror shared control sizes
83
+ // ============================================
84
+
85
+ @each $size in shared.$control-sizes {
86
+ .ui-card[data-padding='#{$size}'] {
87
+ --_card-padding: var(--space-#{$size});
88
+ }
89
+ .ui-card[data-radius='#{$size}'] {
90
+ --_card-radius: var(--radius-#{$size});
91
+ }
92
+ }
93
+
94
+ .ui-card[data-padding='none'] {
95
+ --_card-padding: 0;
96
+ }
97
+ .ui-card[data-radius='none'] {
98
+ --_card-radius: 0;
99
+ }
@@ -0,0 +1,143 @@
1
+ /// Card slot styles — media, header, body, footer, eyebrow
2
+ /// @group organisms/content
3
+
4
+ @use 'sass:map';
5
+ @use '@pithyjs/design-system/a11y/styles/mixins' as a11y;
6
+ @use '@pithyjs/design-system/typography/_generated/tokens' as typo;
7
+ @use '../../shared/tokens' as shared;
8
+
9
+ // ============================================
10
+ // Slots — media / header / body / footer
11
+ // ============================================
12
+
13
+ .ui-card-media {
14
+ overflow: hidden;
15
+ border-radius: inherit;
16
+ inline-size: 100%;
17
+ max-block-size: shared.$card-media-max-block;
18
+
19
+ > * {
20
+ display: block;
21
+ inline-size: 100%;
22
+ }
23
+
24
+ :where(img, video, picture, iframe, canvas) {
25
+ display: block;
26
+ inline-size: 100%;
27
+ block-size: auto;
28
+ max-block-size: shared.$card-media-max-block;
29
+ object-fit: contain;
30
+ }
31
+ }
32
+
33
+ // An explicit aspect ratio locks the media box and crops to fill it.
34
+ .ui-card-media[data-aspect] {
35
+ > * {
36
+ block-size: 100%;
37
+ }
38
+
39
+ :where(img, video, picture, iframe, canvas) {
40
+ block-size: 100%;
41
+ object-fit: cover;
42
+ }
43
+ }
44
+
45
+ // Vertical mode media bleed — negative-inset so media kisses the card's
46
+ // inline + top edges while body padding below remains. The `data-orientation`
47
+ // default is "vertical"; horizontal is handled inside the @container block.
48
+ .ui-card[data-orientation='vertical']:not([data-padding='none'])
49
+ .ui-card-media {
50
+ margin-block-start: calc(-1 * var(--_card-padding));
51
+ margin-inline: calc(-1 * var(--_card-padding));
52
+ inline-size: calc(100% + 2 * var(--_card-padding));
53
+ max-inline-size: none;
54
+ border-start-start-radius: inherit;
55
+ border-start-end-radius: inherit;
56
+ border-end-start-radius: 0;
57
+ border-end-end-radius: 0;
58
+ }
59
+
60
+ // Media → header/body gap boost — the layout's flex `gap: --space-sm` is
61
+ // Close Friends spacing (great for header↔body), but a full-bleed image is a
62
+ // distinct content cluster from the text block below it: Friends spacing
63
+ // (--space-md). We supplement the flex gap so the total visual gap equals
64
+ // --space-md without disturbing header↔body.
65
+ .ui-card[data-orientation='vertical'] .ui-card-media + .ui-card-header,
66
+ .ui-card[data-orientation='vertical'] .ui-card-media + .ui-card-body {
67
+ margin-block-start: calc(var(--space-md) - var(--space-sm));
68
+ }
69
+
70
+ // Aspect ratios
71
+ .ui-card-media[data-aspect='1/1'] {
72
+ aspect-ratio: 1 / 1;
73
+ }
74
+ .ui-card-media[data-aspect='4/3'] {
75
+ aspect-ratio: 4 / 3;
76
+ }
77
+ .ui-card-media[data-aspect='16/9'] {
78
+ aspect-ratio: 16 / 9;
79
+ }
80
+ .ui-card-media[data-aspect='3/2'] {
81
+ aspect-ratio: 3 / 2;
82
+ }
83
+ .ui-card-media[data-aspect='21/9'] {
84
+ aspect-ratio: 21 / 9;
85
+ }
86
+
87
+ .ui-card-header {
88
+ display: flex;
89
+ flex-direction: column;
90
+ gap: var(--space-xs); // eyebrow ↔ title ↔ meta: Lovers / Close Friends
91
+ }
92
+
93
+ // Eyebrow — primary-colored, uppercase, letter-spaced kicker above the
94
+ // heading. Mirrors the .ui-section-eyebrow pattern from section templates
95
+ // so card-in-section consumers read as one editorial voice.
96
+ .ui-card-eyebrow {
97
+ font-size: var(--font-size-xs);
98
+ font-weight: var(--font-weight-semibold);
99
+ letter-spacing: map.get(typo.$letter-spacings, 'widest');
100
+ text-transform: uppercase;
101
+ color: var(--color-primary);
102
+ // Tight rhythm: the eyebrow hugs the heading (Lovers spacing).
103
+ line-height: 1;
104
+ }
105
+
106
+ // Slide-in title underline for clickable cards — telegraphs "this card
107
+ // navigates" on hover/focus-within. Parent-triggered: the card's hover
108
+ // activates the heading's underline, not the heading's own :hover.
109
+ // Only the FIRST heading lights up so multi-heading layouts stay clean.
110
+ .ui-card[data-clickable='true']:not([data-disabled='true'])
111
+ .ui-card-header
112
+ :is(h1, h2, h3, h4, h5, h6):first-of-type {
113
+ display: inline-block;
114
+ max-inline-size: fit-content;
115
+ @include a11y.slide-underline($offset: -0.1em, $self-activate: false);
116
+ }
117
+
118
+ .ui-card[data-clickable='true']:not([data-disabled='true']):hover
119
+ .ui-card-header
120
+ :is(h1, h2, h3, h4, h5, h6):first-of-type,
121
+ .ui-card[data-clickable='true']:not([data-disabled='true']):focus-within
122
+ .ui-card-header
123
+ :is(h1, h2, h3, h4, h5, h6):first-of-type {
124
+ @include a11y.slide-underline-active;
125
+ }
126
+
127
+ .ui-card-body {
128
+ display: flex;
129
+ flex-direction: column;
130
+ gap: var(--space-sm); // paragraph rhythm: Close Friends
131
+ min-inline-size: 0;
132
+ }
133
+
134
+ .ui-card-footer {
135
+ display: flex;
136
+ flex-wrap: wrap;
137
+ align-items: center;
138
+ gap: var(--space-sm);
139
+ // Pin footer to the block-end of the layout column so grid-arranged cards
140
+ // line up at the base.
141
+ margin-block-start: auto;
142
+ padding-block-start: var(--space-sm);
143
+ }
@@ -0,0 +1,166 @@
1
+ /// Card interactive states — hover, selected, disabled, forced-colors, selection
2
+ /// @group organisms/content
3
+
4
+ @use '@pithyjs/design-system/a11y/styles/mixins' as a11y;
5
+
6
+ // ============================================
7
+ // Clickable hover / focus-within matrix
8
+ // ============================================
9
+
10
+ .ui-card[data-clickable='true']:not([data-disabled='true']) {
11
+ cursor: pointer;
12
+
13
+ &:hover,
14
+ &:focus-within {
15
+ --_card-border-color: color-mix(
16
+ in oklch,
17
+ var(--color-primary) 25%,
18
+ var(--color-border)
19
+ );
20
+
21
+ @include a11y.motion-safe {
22
+ translate: 0 calc(-1 * var(--motion-distance-subtle));
23
+ }
24
+ }
25
+ }
26
+
27
+ // Interactive-by-content: cards tagged `data-interactive="true"` at mount
28
+ // because they contain a focusable descendant (button, anchor, form
29
+ // control). The inner control makes the whole card an interaction zone,
30
+ // so hover / focus-within lift the card the same way `data-clickable`
31
+ // does. Static cards (pure content, no focusable children) stay flat —
32
+ // lifting every card on hover cheapens the motion. Selected-state rules
33
+ // below compound `[data-selected="true"]` to win on specificity when a
34
+ // selected card is also hovered.
35
+ .ui-card[data-interactive='true']:not([data-disabled='true']):hover,
36
+ .ui-card[data-interactive='true']:not([data-disabled='true']):focus-within {
37
+ --_card-border-color: color-mix(
38
+ in oklch,
39
+ var(--color-primary) 25%,
40
+ var(--color-border)
41
+ );
42
+ --_card-shadow: var(--shadow-md);
43
+
44
+ @include a11y.motion-safe {
45
+ translate: 0 calc(-1 * var(--motion-distance-subtle));
46
+ }
47
+ }
48
+
49
+ .ui-card[data-clickable='true']:not(
50
+ [data-disabled='true']
51
+ )[data-variant='default']:hover,
52
+ .ui-card[data-clickable='true']:not(
53
+ [data-disabled='true']
54
+ )[data-variant='default']:focus-within {
55
+ --_card-shadow: var(--shadow-md);
56
+ }
57
+
58
+ .ui-card[data-clickable='true']:not(
59
+ [data-disabled='true']
60
+ )[data-variant='outlined']:hover,
61
+ .ui-card[data-clickable='true']:not(
62
+ [data-disabled='true']
63
+ )[data-variant='outlined']:focus-within {
64
+ --_card-shadow: var(--shadow-sm);
65
+ }
66
+
67
+ .ui-card[data-clickable='true']:not(
68
+ [data-disabled='true']
69
+ )[data-variant='elevated']:hover,
70
+ .ui-card[data-clickable='true']:not(
71
+ [data-disabled='true']
72
+ )[data-variant='elevated']:focus-within {
73
+ --_card-shadow: var(--shadow-xl);
74
+ }
75
+
76
+ .ui-card[data-clickable='true']:not(
77
+ [data-disabled='true']
78
+ )[data-variant='subtle']:hover,
79
+ .ui-card[data-clickable='true']:not(
80
+ [data-disabled='true']
81
+ )[data-variant='subtle']:focus-within {
82
+ --_card-shadow: var(--shadow-sm);
83
+ // Subtle stays flat — prevents list jitter.
84
+ translate: none;
85
+ }
86
+
87
+ .ui-card[data-clickable='true']:not(
88
+ [data-disabled='true']
89
+ )[data-variant='ghost']:hover,
90
+ .ui-card[data-clickable='true']:not(
91
+ [data-disabled='true']
92
+ )[data-variant='ghost']:focus-within {
93
+ --_card-bg: var(--color-surface-variant);
94
+ --_card-border-color: var(--color-border);
95
+ }
96
+
97
+ // ============================================
98
+ // Selected
99
+ // ============================================
100
+
101
+ .ui-card[data-selected='true'] {
102
+ --_card-selected-ring-width: var(--border-width-thin);
103
+ --_card-border-color: var(--color-primary);
104
+ // Inner ring (belt-and-suspenders emphasis alongside the colored border).
105
+ box-shadow:
106
+ inset 0 0 0 var(--_card-selected-ring-width) var(--color-primary),
107
+ var(--_card-shadow);
108
+ }
109
+
110
+ // Selected cards respond to hover/focus-within even when not `data-clickable` —
111
+ // the inner action button makes every selected card interactive, so the card
112
+ // should telegraph that on pointer/focus: thicker primary ring, richer shadow,
113
+ // subtle lift. `:not([data-disabled="true"])` both guards the disabled case
114
+ // AND raises specificity to match the `[data-interactive="true"]` hover rule
115
+ // above, so the selected treatment wins by rule order when both apply.
116
+ .ui-card[data-selected='true']:not([data-disabled='true']):hover,
117
+ .ui-card[data-selected='true']:not([data-disabled='true']):focus-within {
118
+ --_card-selected-ring-width: var(--border-width-medium);
119
+ --_card-shadow: var(--shadow-lg);
120
+
121
+ @include a11y.motion-safe {
122
+ translate: 0 calc(-1 * var(--motion-distance-subtle));
123
+ }
124
+ }
125
+
126
+ // ============================================
127
+ // Disabled
128
+ // ============================================
129
+
130
+ .ui-card[data-disabled='true'] {
131
+ opacity: var(--state-disabled-opacity);
132
+ cursor: not-allowed;
133
+ // Kill hover motion — inert already blocks interaction, but motion-safe
134
+ // transitions would still fire without this override.
135
+ translate: none;
136
+ }
137
+
138
+ // ============================================
139
+ // Forced colors
140
+ // ============================================
141
+
142
+ @include a11y.forced-colors {
143
+ .ui-card {
144
+ border: 1px solid ButtonText; // stylelint-disable-line scale-unlimited/declaration-strict-value -- CSS system color required
145
+ box-shadow: none;
146
+ }
147
+
148
+ .ui-card[data-selected='true'] {
149
+ border: 2px solid Highlight; // stylelint-disable-line scale-unlimited/declaration-strict-value -- CSS system color required
150
+ box-shadow: none;
151
+ }
152
+
153
+ .ui-card-link:focus-visible {
154
+ @include a11y.focus-outline(Highlight);
155
+ }
156
+ }
157
+
158
+ // ============================================
159
+ // Selection tint
160
+ // ============================================
161
+
162
+ .ui-card::selection,
163
+ .ui-card *::selection {
164
+ background-color: color-mix(in oklch, var(--color-primary) 20%, transparent);
165
+ color: var(--color-text);
166
+ }
@@ -0,0 +1,22 @@
1
+ /// Card internal sizing tokens
2
+ /// Shared by partials that need the horizontal breakpoint and media column values.
3
+ ///
4
+ /// @group organisms/content
5
+
6
+ @use 'sass:map';
7
+ @use '@pithyjs/design-system/layout/_generated/tokens' as layout;
8
+
9
+ // Horizontal orientation activates above this container width.
10
+ // Mobile-first: the layout is vertical everywhere until it has room to
11
+ // breathe; at >= $card-horizontal-min it switches to a 2-column grid.
12
+ $card-horizontal-min: map.get(layout.$container-breakpoints, 'sm');
13
+
14
+ // Horizontal-orientation media column — clamp(min, preferred, max).
15
+ // $card-media-min keeps the thumbnail legible on the narrow side of the
16
+ // horizontal range; $card-media-max prevents oversized media in wide
17
+ // cards; $card-media-preferred lets the column scale fluidly between them.
18
+ // Named here (rather than inlined) so sizing stays auditable and the
19
+ // component contract exposes a single source of truth.
20
+ $card-media-min: 8rem;
21
+ $card-media-preferred: 32%;
22
+ $card-media-max: 14rem;
@@ -0,0 +1,31 @@
1
+ /// Card variant token overrides
2
+ /// @group organisms/content
3
+
4
+ // ============================================
5
+ // Variants — mutate the --_card-* tokens only
6
+ // ============================================
7
+
8
+ .ui-card[data-variant='outlined'] {
9
+ --_card-bg: var(--color-surface);
10
+ --_card-border-color: var(--color-border);
11
+ --_card-shadow: 0 0 transparent;
12
+ }
13
+
14
+ .ui-card[data-variant='elevated'] {
15
+ --_card-bg: var(--color-surface);
16
+ // Always carry a hairline — shadow is presence, border is edge.
17
+ --_card-border-color: var(--color-border);
18
+ --_card-shadow: var(--shadow-md);
19
+ }
20
+
21
+ .ui-card[data-variant='subtle'] {
22
+ --_card-bg: var(--color-surface-variant);
23
+ --_card-border-color: var(--color-border);
24
+ --_card-shadow: 0 0 transparent;
25
+ }
26
+
27
+ .ui-card[data-variant='ghost'] {
28
+ --_card-bg: transparent;
29
+ --_card-border-color: transparent;
30
+ --_card-shadow: 0 0 transparent;
31
+ }
@@ -0,0 +1,15 @@
1
+ /// Card organism styles
2
+ /// Content container with named slots (media, header, body, footer),
3
+ /// five variants, two orientations, and a pseudo-link overlay for
4
+ /// full-card navigation.
5
+ ///
6
+ /// @group organisms/content
7
+
8
+ @forward 'card-tokens';
9
+ @forward 'card-root';
10
+ @forward 'card-variants';
11
+ @forward 'card-slots';
12
+ @forward 'card-horizontal';
13
+ @forward 'card-overlay';
14
+ @forward 'card-link';
15
+ @forward 'card-states';
@@ -0,0 +1,39 @@
1
+ /** @codex
2
+ {
3
+ "id": "pithy.ui-kit.modal",
4
+ "title": "<Modal> Dialog Component",
5
+ "category": "feature",
6
+ "risk": "high"
7
+ }
8
+ */
9
+ import { type Reactive } from '../../shared/clickable';
10
+ /** @codexApi {"parent":"pithy.ui-kit.modal","name":"ModalProps","stability":"stable","signature":"interface ModalProps"} */
11
+ export interface ModalProps {
12
+ open: Reactive<boolean>;
13
+ onClose: () => void;
14
+ /** Accessible name. Used as `aria-label` unless `titleId` is provided. Required. */
15
+ title: string;
16
+ /** Id of a visible title inside the content — wired as `aria-labelledby`. */
17
+ titleId?: string;
18
+ /** Sets `id` on the dialog element — enables `aria-controls` on the trigger. */
19
+ dialogId?: string;
20
+ /** Pick the element that receives initial focus. Defaults to the first focusable. */
21
+ initialFocus?: (dialogEl: HTMLElement) => HTMLElement | null;
22
+ closeOnBackdrop?: boolean;
23
+ closeOnEscape?: boolean;
24
+ backdropClass?: string;
25
+ /**
26
+ * Content factory, re-invoked on every open so the dialog reflects fresh
27
+ * state. When omitted, the template slot (`renderChildren`) is used once.
28
+ */
29
+ content?: () => {
30
+ el: Node;
31
+ destroy: () => void;
32
+ };
33
+ }
34
+ /** @codexApi {"parent":"pithy.ui-kit.modal","name":"Modal","stability":"stable","signature":"(props: ModalProps) => { el: HTMLElement; destroy: () => void }"} */
35
+ export declare function Modal(props: ModalProps): {
36
+ el: HTMLElement;
37
+ destroy: () => void;
38
+ };
39
+ //# sourceMappingURL=Modal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Modal.d.ts","sourceRoot":"","sources":["../../../src/organisms/feedback/Modal.ts"],"names":[],"mappings":"AAAA;;;;;;;EAOE;AAIF,OAAO,EAAgB,KAAK,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAErE,4HAA4H;AAC5H,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IACxB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,oFAAoF;IACpF,KAAK,EAAE,MAAM,CAAC;IACd,6EAA6E;IAC7E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gFAAgF;IAChF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qFAAqF;IACrF,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,WAAW,KAAK,WAAW,GAAG,IAAI,CAAC;IAC7D,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM;QAAE,EAAE,EAAE,IAAI,CAAC;QAAC,OAAO,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC;CACnD;AAED,kKAAkK;AAClK,wBAAgB,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG;IACxC,EAAE,EAAE,WAAW,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CA0HA"}
@@ -0,0 +1,120 @@
1
+ /** @codex
2
+ {
3
+ "id": "pithy.ui-kit.modal",
4
+ "title": "<Modal> Dialog Component",
5
+ "category": "feature",
6
+ "risk": "high"
7
+ }
8
+ */
9
+ import { renderChildren, FocusTrap } from '@pithyjs/core';
10
+ import { effect } from '@pithyjs/signals';
11
+ import { readReactive } from '../../shared/clickable';
12
+ /** @codexApi {"parent":"pithy.ui-kit.modal","name":"Modal","stability":"stable","signature":"(props: ModalProps) => { el: HTMLElement; destroy: () => void }"} */
13
+ export function Modal(props) {
14
+ const { open, onClose, title, titleId, dialogId, initialFocus, closeOnBackdrop = true, closeOnEscape = true, backdropClass, content, } = props;
15
+ const name = title?.trim() ?? '';
16
+ if (import.meta.env?.DEV && !name && !titleId) {
17
+ console.warn('[<Modal>] `title` is required for an accessible name.');
18
+ }
19
+ const backdrop = document.createElement('div');
20
+ backdrop.className = 'ui-modal-backdrop';
21
+ if (backdropClass)
22
+ backdrop.classList.add(backdropClass);
23
+ backdrop.hidden = true;
24
+ const dialog = document.createElement('div');
25
+ dialog.className = 'ui-modal';
26
+ dialog.setAttribute('role', 'dialog');
27
+ dialog.setAttribute('aria-modal', 'true');
28
+ if (titleId)
29
+ dialog.setAttribute('aria-labelledby', titleId);
30
+ else if (name)
31
+ dialog.setAttribute('aria-label', name);
32
+ if (dialogId)
33
+ dialog.id = dialogId;
34
+ backdrop.appendChild(dialog);
35
+ const staticContent = content ? null : renderChildren();
36
+ if (staticContent)
37
+ dialog.appendChild(staticContent.el);
38
+ let activeContent = null;
39
+ let trap = null;
40
+ let onKey = null;
41
+ let onBackdrop = null;
42
+ let mounted = false;
43
+ const mount = () => {
44
+ if (content) {
45
+ activeContent = content();
46
+ dialog.appendChild(activeContent.el);
47
+ }
48
+ onBackdrop = (e) => {
49
+ if (closeOnBackdrop && e.target === backdrop)
50
+ onClose?.();
51
+ };
52
+ backdrop.addEventListener('pointerdown', onBackdrop);
53
+ // Listen on window in capture with stopImmediatePropagation so the modal
54
+ // wins Escape over other document-capture handlers (e.g. the Doctor
55
+ // panel) — stopPropagation alone wouldn't stop same-target listeners.
56
+ onKey = (e) => {
57
+ if (closeOnEscape && e.key === 'Escape') {
58
+ e.preventDefault();
59
+ e.stopImmediatePropagation();
60
+ onClose?.();
61
+ }
62
+ };
63
+ window.addEventListener('keydown', onKey, true);
64
+ backdrop.hidden = false;
65
+ document.body.appendChild(backdrop);
66
+ trap = new FocusTrap(dialog, {
67
+ initialFocus: initialFocus?.(dialog) ?? undefined,
68
+ escapeDeactivates: false,
69
+ clickOutsideDeactivates: false,
70
+ });
71
+ trap.activate();
72
+ mounted = true;
73
+ };
74
+ const unmount = () => {
75
+ if (onKey) {
76
+ window.removeEventListener('keydown', onKey, true);
77
+ onKey = null;
78
+ }
79
+ trap?.deactivate();
80
+ trap = null;
81
+ if (onBackdrop) {
82
+ backdrop.removeEventListener('pointerdown', onBackdrop);
83
+ onBackdrop = null;
84
+ }
85
+ backdrop.hidden = true;
86
+ backdrop.remove();
87
+ if (activeContent) {
88
+ activeContent.destroy();
89
+ activeContent = null;
90
+ dialog.replaceChildren();
91
+ }
92
+ mounted = false;
93
+ };
94
+ let disposed = false;
95
+ // Defer mount/unmount to a microtask so the content factory's signal reads
96
+ // (e.g. the publish gate) run outside this effect's tracking scope —
97
+ // otherwise the effect would subscribe to them and re-run on unrelated
98
+ // edits. Only open() is tracked here.
99
+ const disposeEffect = effect(() => {
100
+ const isOpen = readReactive(open);
101
+ queueMicrotask(() => {
102
+ if (disposed)
103
+ return;
104
+ if (isOpen && !mounted)
105
+ mount();
106
+ else if (!isOpen && mounted)
107
+ unmount();
108
+ });
109
+ });
110
+ return {
111
+ el: backdrop,
112
+ destroy: () => {
113
+ disposed = true;
114
+ disposeEffect();
115
+ unmount();
116
+ staticContent?.destroy();
117
+ },
118
+ };
119
+ }
120
+ //# sourceMappingURL=Modal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Modal.js","sourceRoot":"","sources":["../../../src/organisms/feedback/Modal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /** @codex
2
+ {
3
+ "id": "pithy.ui-kit.popover",
4
+ "title": "<Popover> Anchored Overlay Component",
5
+ "category": "feature",
6
+ "risk": "high"
7
+ }
8
+ */
9
+ import { type Reactive } from '../../shared/clickable';
10
+ /** @codexApi {"parent":"pithy.ui-kit.popover","name":"PopoverProps","stability":"stable","signature":"interface PopoverProps"} */
11
+ export interface PopoverProps {
12
+ open: Reactive<boolean>;
13
+ anchorRef: () => HTMLElement | null | undefined;
14
+ onClose: () => void;
15
+ content: () => {
16
+ el: HTMLElement;
17
+ destroy: () => void;
18
+ };
19
+ align?: 'right' | 'center' | 'start';
20
+ gap?: number;
21
+ menuId?: string;
22
+ zIndex?: string;
23
+ backdropClass?: string;
24
+ initialFocus?: (menuEl: HTMLElement) => HTMLElement | null;
25
+ }
26
+ /** @codexApi {"parent":"pithy.ui-kit.popover","name":"Popover","stability":"stable","signature":"(props: PopoverProps) => { destroy: () => void }"} */
27
+ export declare function Popover(props: PopoverProps): {
28
+ destroy: () => void;
29
+ };
30
+ //# sourceMappingURL=Popover.d.ts.map