@torpor/ui 0.2.0 → 0.3.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 (312) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/dist/Accordion/Accordion.torp +44 -25
  3. package/dist/Accordion/AccordionContent.torp +18 -12
  4. package/dist/Accordion/AccordionHeader.torp +15 -8
  5. package/dist/Accordion/AccordionItem.torp +34 -17
  6. package/dist/Accordion/AccordionTrigger.torp +17 -10
  7. package/dist/Accordion/AccordionTypes.ts +6 -3
  8. package/dist/Accordion/index.d.ts +100 -35
  9. package/dist/Breadcrumb/Breadcrumb.torp +18 -10
  10. package/dist/Breadcrumb/BreadcrumbItem.torp +14 -7
  11. package/dist/Breadcrumb/BreadcrumbSeparator.torp +10 -3
  12. package/dist/Breadcrumb/index.d.ts +50 -21
  13. package/dist/Calendar/Calendar.torp +21 -14
  14. package/dist/Calendar/CalendarDay.torp +12 -4
  15. package/dist/Calendar/index.d.ts +16 -18
  16. package/dist/Contextual/Contextual.torp +125 -0
  17. package/dist/{Popover/PopoverContentContextual.torp → Contextual/ContextualContent.torp} +21 -12
  18. package/dist/Contextual/ContextualTrigger.torp +66 -0
  19. package/dist/Contextual/ContextualTypes.ts +30 -0
  20. package/dist/Contextual/index.d.ts +90 -0
  21. package/dist/Contextual/index.js +14 -0
  22. package/dist/Contextual/index.js.map +1 -0
  23. package/dist/Dialog/Dialog.torp +49 -73
  24. package/dist/Dialog/DialogBody.torp +15 -9
  25. package/dist/Dialog/DialogButton.torp +27 -13
  26. package/dist/Dialog/DialogFooter.torp +11 -3
  27. package/dist/Dialog/DialogHeader.torp +15 -8
  28. package/dist/Dialog/DialogTypes.ts +3 -2
  29. package/dist/Dialog/index.d.ts +83 -35
  30. package/dist/Disclosure/Disclosure.torp +34 -25
  31. package/dist/Disclosure/DisclosureContent.torp +18 -12
  32. package/dist/Disclosure/DisclosureHeader.torp +16 -9
  33. package/dist/Disclosure/DisclosureTrigger.torp +15 -8
  34. package/dist/Disclosure/DisclosureTypes.ts +0 -1
  35. package/dist/Disclosure/index.d.ts +67 -28
  36. package/dist/Drawer/Drawer.torp +109 -68
  37. package/dist/Drawer/DrawerContent.torp +80 -0
  38. package/dist/Drawer/DrawerOverlay.torp +38 -0
  39. package/dist/Drawer/DrawerTrigger.torp +35 -0
  40. package/dist/Drawer/DrawerTypes.ts +24 -0
  41. package/dist/Drawer/index.d.ts +96 -8
  42. package/dist/Drawer/index.js +13 -1
  43. package/dist/Form/Field.torp +91 -0
  44. package/dist/Form/Form.torp +129 -0
  45. package/dist/Form/FormTypes.ts +30 -0
  46. package/dist/Form/Input.torp +97 -0
  47. package/dist/Form/Label.torp +31 -0
  48. package/dist/Form/Message.torp +35 -0
  49. package/dist/Form/StandardSchemaV1.ts +70 -0
  50. package/dist/Form/index.d.ts +131 -0
  51. package/dist/Form/index.js +22 -0
  52. package/dist/Form/index.js.map +1 -0
  53. package/dist/Menu/Menu.torp +25 -15
  54. package/dist/Menu/MenuButton.torp +30 -13
  55. package/dist/Menu/MenuCheck.torp +29 -14
  56. package/dist/Menu/MenuGroup.torp +14 -6
  57. package/dist/Menu/MenuIndicator.torp +14 -7
  58. package/dist/Menu/MenuPopout.torp +23 -15
  59. package/dist/Menu/MenuPopoutContent.torp +17 -10
  60. package/dist/Menu/MenuPopoutTrigger.torp +23 -16
  61. package/dist/Menu/MenuRadio.torp +27 -16
  62. package/dist/Menu/MenuRadioGroup.torp +34 -15
  63. package/dist/Menu/MenuSeparator.torp +11 -3
  64. package/dist/Menu/MenuTypes.ts +7 -5
  65. package/dist/Menu/index.d.ts +176 -77
  66. package/dist/MenuBar/MenuBar.torp +24 -16
  67. package/dist/MenuBar/MenuBarItem.torp +24 -16
  68. package/dist/MenuBar/MenuBarItemContent.torp +18 -11
  69. package/dist/MenuBar/MenuBarItemTrigger.torp +15 -9
  70. package/dist/MenuBar/index.d.ts +79 -28
  71. package/dist/Modal/Modal.torp +118 -0
  72. package/dist/Modal/ModalContent.torp +77 -0
  73. package/dist/Modal/ModalOverlay.torp +38 -0
  74. package/dist/Modal/ModalTrigger.torp +50 -0
  75. package/dist/Modal/ModalTypes.ts +22 -0
  76. package/dist/Modal/index.d.ts +108 -0
  77. package/dist/Modal/index.js +33 -0
  78. package/dist/Modal/index.js.map +1 -0
  79. package/dist/Modal/showModal.ts +19 -0
  80. package/dist/Modal/showPrompt.ts +23 -0
  81. package/dist/NavMenu/NavMenu.torp +18 -10
  82. package/dist/NavMenu/NavMenuButton.torp +15 -10
  83. package/dist/NavMenu/NavMenuElement.torp +19 -11
  84. package/dist/NavMenu/NavMenuGroup.torp +13 -6
  85. package/dist/NavMenu/NavMenuGroupHeader.torp +15 -8
  86. package/dist/NavMenu/NavMenuLink.torp +21 -16
  87. package/dist/NavMenu/NavMenuPopout.torp +34 -18
  88. package/dist/NavMenu/NavMenuPopoutButton.torp +23 -18
  89. package/dist/NavMenu/NavMenuPopoutContent.torp +23 -13
  90. package/dist/NavMenu/NavMenuSeparator.torp +10 -3
  91. package/dist/NavMenu/index.d.ts +153 -70
  92. package/dist/Notification/Notification.torp +35 -16
  93. package/dist/Notification/NotificationClose.torp +10 -3
  94. package/dist/Notification/NotificationContainer.torp +11 -3
  95. package/dist/Notification/NotificationContent.torp +11 -3
  96. package/dist/Notification/index.d.ts +46 -28
  97. package/dist/Popover/Popover.torp +48 -28
  98. package/dist/Popover/PopoverContent.torp +42 -8
  99. package/dist/Popover/PopoverTrigger.torp +32 -3
  100. package/dist/Popover/PopoverTypes.ts +1 -1
  101. package/dist/Popover/index.d.ts +48 -111
  102. package/dist/Popover/index.js +1 -163
  103. package/dist/Popover/index.js.map +1 -1
  104. package/dist/TabGroup/TabContent.torp +20 -11
  105. package/dist/TabGroup/TabGroup.torp +58 -40
  106. package/dist/TabGroup/TabGroupTypes.ts +10 -5
  107. package/dist/TabGroup/TabHeader.torp +26 -10
  108. package/dist/TabGroup/TabList.torp +14 -7
  109. package/dist/TabGroup/TabTrigger.torp +17 -10
  110. package/dist/TabGroup/index.d.ts +101 -35
  111. package/dist/icons/ArrowDown.torp +5 -3
  112. package/dist/icons/ArrowLeft.torp +5 -3
  113. package/dist/icons/ArrowRight.torp +5 -3
  114. package/dist/icons/ArrowUp.torp +5 -3
  115. package/dist/icons/Bars.torp +5 -3
  116. package/dist/icons/Check.torp +5 -3
  117. package/dist/icons/ChevronDown.torp +5 -3
  118. package/dist/icons/ChevronLeft.torp +5 -3
  119. package/dist/icons/ChevronRight.torp +5 -3
  120. package/dist/icons/ChevronUp.torp +5 -3
  121. package/dist/icons/Cross.torp +5 -3
  122. package/dist/icons/IconTypes.ts +6 -0
  123. package/dist/icons/Loading.torp +5 -3
  124. package/dist/icons/Minus.torp +5 -3
  125. package/dist/icons/Plus.torp +5 -3
  126. package/dist/icons/index.d.ts +271 -126
  127. package/dist/index.d.ts +17 -4
  128. package/dist/metafile-esm.json +1 -1
  129. package/dist/motion/fade.ts +15 -6
  130. package/dist/motion/grow.ts +23 -0
  131. package/dist/motion/index.d.ts +19 -2
  132. package/dist/motion/index.js +93 -3
  133. package/dist/motion/index.js.map +1 -1
  134. package/dist/motion/measure.ts +28 -0
  135. package/dist/motion/slide.ts +45 -0
  136. package/dist/mount/clickPopover.ts +51 -0
  137. package/dist/mount/contextPopover.ts +51 -0
  138. package/dist/mount/hoverPopover.ts +58 -0
  139. package/package.json +28 -12
  140. package/scripts/postbuild.ts +11 -1
  141. package/src/Accordion/Accordion.torp +44 -25
  142. package/src/Accordion/AccordionContent.torp +18 -12
  143. package/src/Accordion/AccordionHeader.torp +15 -8
  144. package/src/Accordion/AccordionItem.torp +34 -17
  145. package/src/Accordion/AccordionTrigger.torp +17 -10
  146. package/src/Accordion/AccordionTypes.ts +6 -3
  147. package/src/Breadcrumb/Breadcrumb.torp +18 -10
  148. package/src/Breadcrumb/BreadcrumbItem.torp +14 -7
  149. package/src/Breadcrumb/BreadcrumbSeparator.torp +10 -3
  150. package/src/Calendar/Calendar.torp +21 -14
  151. package/src/Calendar/CalendarDay.torp +12 -4
  152. package/src/Contextual/Contextual.torp +125 -0
  153. package/src/{Popover/PopoverContentContextual.torp → Contextual/ContextualContent.torp} +21 -12
  154. package/src/Contextual/ContextualTrigger.torp +66 -0
  155. package/src/Contextual/ContextualTypes.ts +30 -0
  156. package/src/Contextual/index.ts +5 -0
  157. package/src/Dialog/Dialog.torp +49 -73
  158. package/src/Dialog/DialogBody.torp +15 -9
  159. package/src/Dialog/DialogButton.torp +27 -13
  160. package/src/Dialog/DialogFooter.torp +11 -3
  161. package/src/Dialog/DialogHeader.torp +15 -8
  162. package/src/Dialog/DialogTypes.ts +3 -2
  163. package/src/Disclosure/Disclosure.torp +34 -25
  164. package/src/Disclosure/DisclosureContent.torp +18 -12
  165. package/src/Disclosure/DisclosureHeader.torp +16 -9
  166. package/src/Disclosure/DisclosureTrigger.torp +15 -8
  167. package/src/Disclosure/DisclosureTypes.ts +0 -1
  168. package/src/Drawer/Drawer.torp +109 -68
  169. package/src/Drawer/DrawerContent.torp +80 -0
  170. package/src/Drawer/DrawerOverlay.torp +38 -0
  171. package/src/Drawer/DrawerTrigger.torp +35 -0
  172. package/src/Drawer/DrawerTypes.ts +24 -0
  173. package/src/Drawer/index.ts +4 -1
  174. package/src/Form/Field.torp +91 -0
  175. package/src/Form/Form.torp +129 -0
  176. package/src/Form/FormTypes.ts +30 -0
  177. package/src/Form/Input.torp +97 -0
  178. package/src/Form/Label.torp +31 -0
  179. package/src/Form/Message.torp +35 -0
  180. package/src/Form/StandardSchemaV1.ts +70 -0
  181. package/src/Form/index.ts +7 -0
  182. package/src/Menu/Menu.torp +25 -15
  183. package/src/Menu/MenuButton.torp +30 -13
  184. package/src/Menu/MenuCheck.torp +29 -14
  185. package/src/Menu/MenuGroup.torp +14 -6
  186. package/src/Menu/MenuIndicator.torp +14 -7
  187. package/src/Menu/MenuPopout.torp +23 -15
  188. package/src/Menu/MenuPopoutContent.torp +17 -10
  189. package/src/Menu/MenuPopoutTrigger.torp +23 -16
  190. package/src/Menu/MenuRadio.torp +27 -16
  191. package/src/Menu/MenuRadioGroup.torp +34 -15
  192. package/src/Menu/MenuSeparator.torp +11 -3
  193. package/src/Menu/MenuTypes.ts +7 -5
  194. package/src/MenuBar/MenuBar.torp +24 -16
  195. package/src/MenuBar/MenuBarItem.torp +24 -16
  196. package/src/MenuBar/MenuBarItemContent.torp +18 -11
  197. package/src/MenuBar/MenuBarItemTrigger.torp +15 -9
  198. package/src/Modal/Modal.torp +118 -0
  199. package/src/Modal/ModalContent.torp +77 -0
  200. package/src/Modal/ModalOverlay.torp +38 -0
  201. package/src/Modal/ModalTrigger.torp +50 -0
  202. package/src/Modal/ModalTypes.ts +22 -0
  203. package/src/Modal/index.ts +10 -0
  204. package/src/Modal/showModal.ts +19 -0
  205. package/src/Modal/showPrompt.ts +23 -0
  206. package/src/NavMenu/NavMenu.torp +18 -10
  207. package/src/NavMenu/NavMenuButton.torp +15 -10
  208. package/src/NavMenu/NavMenuElement.torp +19 -11
  209. package/src/NavMenu/NavMenuGroup.torp +13 -6
  210. package/src/NavMenu/NavMenuGroupHeader.torp +15 -8
  211. package/src/NavMenu/NavMenuLink.torp +21 -16
  212. package/src/NavMenu/NavMenuPopout.torp +34 -18
  213. package/src/NavMenu/NavMenuPopoutButton.torp +23 -18
  214. package/src/NavMenu/NavMenuPopoutContent.torp +23 -13
  215. package/src/NavMenu/NavMenuSeparator.torp +10 -3
  216. package/src/Notification/Notification.torp +35 -16
  217. package/src/Notification/NotificationClose.torp +10 -3
  218. package/src/Notification/NotificationContainer.torp +11 -3
  219. package/src/Notification/NotificationContent.torp +11 -3
  220. package/src/Popover/Popover.torp +48 -28
  221. package/src/Popover/PopoverContent.torp +42 -8
  222. package/src/Popover/PopoverTrigger.torp +32 -3
  223. package/src/Popover/PopoverTypes.ts +1 -1
  224. package/src/Popover/index.ts +1 -24
  225. package/src/Slider/Slider.torp +3 -3
  226. package/src/TabGroup/TabContent.torp +20 -11
  227. package/src/TabGroup/TabGroup.torp +58 -40
  228. package/src/TabGroup/TabGroupTypes.ts +10 -5
  229. package/src/TabGroup/TabHeader.torp +26 -10
  230. package/src/TabGroup/TabList.torp +14 -7
  231. package/src/TabGroup/TabTrigger.torp +17 -10
  232. package/src/icons/ArrowDown.torp +5 -3
  233. package/src/icons/ArrowLeft.torp +5 -3
  234. package/src/icons/ArrowRight.torp +5 -3
  235. package/src/icons/ArrowUp.torp +5 -3
  236. package/src/icons/Bars.torp +5 -3
  237. package/src/icons/Check.torp +5 -3
  238. package/src/icons/ChevronDown.torp +5 -3
  239. package/src/icons/ChevronLeft.torp +5 -3
  240. package/src/icons/ChevronRight.torp +5 -3
  241. package/src/icons/ChevronUp.torp +5 -3
  242. package/src/icons/Cross.torp +5 -3
  243. package/src/icons/IconTypes.ts +6 -0
  244. package/src/icons/Loading.torp +5 -3
  245. package/src/icons/Minus.torp +5 -3
  246. package/src/icons/Plus.torp +5 -3
  247. package/src/motion/fade.ts +15 -6
  248. package/src/motion/grow.ts +23 -0
  249. package/src/motion/index.ts +4 -1
  250. package/src/motion/measure.ts +28 -0
  251. package/src/motion/slide.ts +45 -0
  252. package/src/mount/clickPopover.ts +51 -0
  253. package/src/mount/contextPopover.ts +51 -0
  254. package/src/mount/hoverPopover.ts +58 -0
  255. package/test/Accordion/components/AccordionAccessibility.torp +1 -1
  256. package/test/Accordion/components/AccordionKeyboard.torp +1 -1
  257. package/test/Accordion/components/AccordionList.torp +1 -1
  258. package/test/Accordion/components/AccordionMultiple.torp +2 -2
  259. package/test/Accordion/components/AccordionSingle.torp +2 -2
  260. package/test/Dialog/accessibility-modal.test.ts +2 -2
  261. package/test/Dialog/components/DialogAccessibility.torp +8 -14
  262. package/test/Dialog/components/DialogFunction.torp +20 -4
  263. package/test/Dialog/components/DialogModal.torp +30 -0
  264. package/test/Dialog/components/DialogVariable.torp +7 -7
  265. package/test/Disclosure/accessibility.test.ts +3 -2
  266. package/test/Disclosure/components/DisclosureTest.torp +1 -1
  267. package/test/Disclosure/toggle.test.ts +3 -2
  268. package/test/Form/components/FieldTest.torp +25 -0
  269. package/test/Form/components/FormTest.torp +31 -0
  270. package/test/Form/components/InputTest.torp +9 -0
  271. package/test/Form/field.test.ts +34 -0
  272. package/test/Form/form.test.ts +34 -0
  273. package/test/Form/input.test.ts +19 -0
  274. package/test/Menu/accessibility.test.ts +3 -2
  275. package/test/Menu/basic.test.ts +11 -10
  276. package/test/Menu/components/MenuAccessibility.torp +5 -5
  277. package/test/Menu/components/MenuBasic.torp +5 -5
  278. package/test/MenuBar/accessibility.test.ts +3 -2
  279. package/test/MenuBar/basic.test.ts +3 -2
  280. package/test/NavMenu/basic.test.ts +1 -1
  281. package/test/NavMenu/components/{NavMenu.torp → NavMenuBasic.torp} +1 -1
  282. package/test/Notification/components/NotificationFunction.torp +0 -3
  283. package/test/Notification/components/NotificationVariable.torp +1 -1
  284. package/test/Popover/components/PopoverFunction.torp +37 -0
  285. package/test/Popover/components/PopoverTrigger.torp +36 -0
  286. package/test/Popover/components/{PromptVariable.torp → PopoverVariable.torp} +5 -3
  287. package/test/Popover/function.test.ts +2 -7
  288. package/test/Popover/trigger.test.ts +27 -0
  289. package/test/Popover/variable.test.ts +2 -2
  290. package/test/TabGroup/components/TabGroupAccessibility.torp +1 -1
  291. package/test/TabGroup/components/TabGroupKeyboard.torp +1 -1
  292. package/test/TabGroup/components/TabGroupList.torp +1 -1
  293. package/test/TabGroup/components/TabGroupTrigger.torp +1 -1
  294. package/tsup.config.ts +3 -1
  295. package/dist/Popover/PopoverContentAnchored.torp +0 -106
  296. package/dist/Popover/PopoverOverlay.torp +0 -30
  297. package/dist/Popover/PopoverTriggerContextual.torp +0 -37
  298. package/dist/Popover/PopoverTriggerHover.torp +0 -38
  299. package/dist/Popover/mountClickPopover.ts +0 -50
  300. package/dist/Popover/mountContextPopover.ts +0 -50
  301. package/dist/Popover/mountHoverPopover.ts +0 -57
  302. package/dist/Popover/showPopoverPrompt.ts +0 -23
  303. package/src/Popover/PopoverContentAnchored.torp +0 -106
  304. package/src/Popover/PopoverOverlay.torp +0 -30
  305. package/src/Popover/PopoverTriggerContextual.torp +0 -37
  306. package/src/Popover/PopoverTriggerHover.torp +0 -38
  307. package/src/Popover/mountClickPopover.ts +0 -50
  308. package/src/Popover/mountContextPopover.ts +0 -50
  309. package/src/Popover/mountHoverPopover.ts +0 -57
  310. package/src/Popover/showPopoverPrompt.ts +0 -23
  311. package/test/Dialog/components/CustomDialog.torp +0 -20
  312. package/test/Popover/components/PromptFunction.torp +0 -19
@@ -0,0 +1,51 @@
1
+ //import type { Component } from "@torpor/view";
2
+ //import showPopover from "../Modal/showModal";
3
+ //
4
+ //interface ClickPopoverOptions {
5
+ // popover: Component;
6
+ // props?: Record<PropertyKey, any>;
7
+ //}
8
+ //
9
+ ///**
10
+ // * A mount directive for showing a popover when an element is clicked.
11
+ // * @param node The element to show the popover for
12
+ // * @param options Options for showing the popover, consisting of the popover component and any props
13
+ // */
14
+ //export default function clickPopover(node: HTMLElement, options: ClickPopoverOptions) {
15
+ // const { popover, props } = options;
16
+ //
17
+ // // Add a click event handler to the node
18
+ // node.addEventListener("click", handleClick);
19
+ //
20
+ // function handleClick(e: MouseEvent) {
21
+ // e.preventDefault();
22
+ // show();
23
+ // }
24
+ //
25
+ // let div: HTMLDivElement;
26
+ //
27
+ // function show() {
28
+ // // Show the popover in a div
29
+ // if (div) {
30
+ // document.body.removeChild(div);
31
+ // }
32
+ // div = document.createElement("div");
33
+ // document.body.appendChild(div);
34
+ //
35
+ // showPopover(popover, node, props, div);
36
+ // }
37
+ //
38
+ // return {
39
+ // destroy(): void {
40
+ // // Remove the event listener from the node on destroy
41
+ // node.removeEventListener("click", handleClick);
42
+ //
43
+ // // Remove the div we added
44
+ // // TODO: Should we do this in more places?
45
+ // if (div) {
46
+ // document.body.removeChild(div);
47
+ // }
48
+ // },
49
+ // };
50
+ //}
51
+ //
@@ -0,0 +1,51 @@
1
+ //import type { Component } from "@torpor/view";
2
+ //import showPopover from "../Modal/showModal";
3
+ //
4
+ //interface ContextPopoverOptions {
5
+ // popover: Component;
6
+ // props?: Record<PropertyKey, any>;
7
+ //}
8
+ //
9
+ ///**
10
+ // * A mount directive for showing a popover when the user opens an element's context menu.
11
+ // * @param node The element to show the popover for
12
+ // * @param options Options for showing the popover, consisting of the popover component and any props
13
+ // */
14
+ //export default function contextPopover(node: HTMLElement, options: ContextPopoverOptions) {
15
+ // const { popover, props } = options;
16
+ //
17
+ // // Add a contextmenu event handler to the node
18
+ // node.addEventListener("contextmenu", handleClick);
19
+ //
20
+ // function handleClick(e: MouseEvent) {
21
+ // e.preventDefault();
22
+ // show();
23
+ // }
24
+ //
25
+ // let div: HTMLDivElement;
26
+ //
27
+ // function show() {
28
+ // // Show the popover in a div
29
+ // if (div) {
30
+ // document.body.removeChild(div);
31
+ // }
32
+ // div = document.createElement("div");
33
+ // document.body.appendChild(div);
34
+ //
35
+ // showPopover(popover, node, props, div);
36
+ // }
37
+ //
38
+ // return {
39
+ // destroy(): void {
40
+ // // Remove the event listener from the node on destroy
41
+ // node.removeEventListener("contextmenu", handleClick);
42
+ //
43
+ // // Remove the div we added
44
+ // // TODO: Should we do this in more places?
45
+ // if (div) {
46
+ // document.body.removeChild(div);
47
+ // }
48
+ // },
49
+ // };
50
+ //}
51
+ //
@@ -0,0 +1,58 @@
1
+ //import type { Component } from "@torpor/view";
2
+ //import showPopover from "../Modal/showModal";
3
+ //import hoverTrigger from "./hoverTrigger";
4
+ //
5
+ //interface HoverPopoverOptions {
6
+ // popover: Component;
7
+ // props?: Record<PropertyKey, any>;
8
+ // hoverDelay?: number;
9
+ // touchDelay?: number;
10
+ //}
11
+ //
12
+ ///**
13
+ // * A mount directive for showing a popover when an element is hovered.
14
+ // * @param node The element to show the popover for
15
+ // * @param options Options for showing the popover, consisting of the popover component, any props and delays for hover and touch
16
+ // */
17
+ //export default function hoverPopover(node: HTMLElement, options: HoverPopoverOptions): () => void {
18
+ // const { popover, props, hoverDelay, touchDelay } = options;
19
+ //
20
+ // let div: HTMLDivElement | undefined;
21
+ //
22
+ // function onHover(node: HTMLElement, e: MouseEvent | TouchEvent) {
23
+ // // Show the popover in a div
24
+ // if (div) {
25
+ // document.body.removeChild(div);
26
+ // }
27
+ // div = document.createElement("div");
28
+ // document.body.appendChild(div);
29
+ //
30
+ // // Get the position relative to the element, so we can reposition on scroll
31
+ // const rect = node.getBoundingClientRect();
32
+ // let position: { x: number; y: number };
33
+ // if (e.type.startsWith("mouse")) {
34
+ // const me = e as MouseEvent;
35
+ // position = { x: me.clientX - rect.left, y: me.clientY - rect.top };
36
+ // } else {
37
+ // const te = e as TouchEvent;
38
+ // position = {
39
+ // x: te.touches[0].clientX - rect.left,
40
+ // y: te.touches[0].clientY - rect.top,
41
+ // };
42
+ // }
43
+ // const allProps = Object.assign({}, props, { anchor: node, position });
44
+ //
45
+ // showPopover(popover, node, allProps, div);
46
+ // }
47
+ //
48
+ // function onExit() {
49
+ // // Remove the div
50
+ // if (div) {
51
+ // document.body.removeChild(div);
52
+ // div = undefined;
53
+ // }
54
+ // }
55
+ //
56
+ // return hoverTrigger(node, { onHover, onExit, hoverDelay, touchDelay });
57
+ //}
58
+ //
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@torpor/ui",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Accessible, unstyled components for use in your Torpor front-end",
5
5
  "type": "module",
6
6
  "exports": {
@@ -14,8 +14,11 @@
14
14
  },
15
15
  "./Calendar": {
16
16
  "types": "./dist/Calendar/index.d.ts",
17
- "import": "./dist/Calendar/index.js",
18
- "require": "./dist/Calendar/index.cjs"
17
+ "import": "./dist/Calendar/index.js"
18
+ },
19
+ "./Contextual": {
20
+ "types": "./dist/Contextual/index.d.ts",
21
+ "import": "./dist/Contextual/index.js"
19
22
  },
20
23
  "./Dialog": {
21
24
  "types": "./dist/Dialog/index.d.ts",
@@ -29,6 +32,10 @@
29
32
  "types": "./dist/Drawer/index.d.ts",
30
33
  "import": "./dist/Drawer/index.js"
31
34
  },
35
+ "./Form": {
36
+ "types": "./dist/Form/index.d.ts",
37
+ "import": "./dist/Form/index.js"
38
+ },
32
39
  "./Menu": {
33
40
  "types": "./dist/Menu/index.d.ts",
34
41
  "import": "./dist/Menu/index.js"
@@ -37,6 +44,10 @@
37
44
  "types": "./dist/MenuBar/index.d.ts",
38
45
  "import": "./dist/MenuBar/index.js"
39
46
  },
47
+ "./Modal": {
48
+ "types": "./dist/Modal/index.d.ts",
49
+ "import": "./dist/Modal/index.js"
50
+ },
40
51
  "./NavMenu": {
41
52
  "types": "./dist/NavMenu/index.d.ts",
42
53
  "import": "./dist/NavMenu/index.js"
@@ -53,9 +64,13 @@
53
64
  "types": "./dist/TabGroup/index.d.ts",
54
65
  "import": "./dist/TabGroup/index.js"
55
66
  },
67
+ "./icons": {
68
+ "types": "./dist/icons/index.d.ts",
69
+ "import": "./dist/icons/index.js"
70
+ },
56
71
  "./motion": {
57
- "types": "./dist/motion.d.ts",
58
- "import": "./dist/motion.js"
72
+ "types": "./dist/motion/index.d.ts",
73
+ "import": "./dist/motion/index.js"
59
74
  }
60
75
  },
61
76
  "publishConfig": {
@@ -65,8 +80,8 @@
65
80
  "author": "",
66
81
  "license": "ISC",
67
82
  "dependencies": {
68
- "@torpor/unplugin": "^0.2.0",
69
- "@torpor/view": "^0.3.0"
83
+ "@torpor/view": "^0.4.0",
84
+ "@torpor/unplugin": "^0.2.1"
70
85
  },
71
86
  "devDependencies": {
72
87
  "@testing-library/dom": "^10.4.1",
@@ -74,16 +89,17 @@
74
89
  "@testing-library/user-event": "^14.6.1",
75
90
  "@trivago/prettier-plugin-sort-imports": "^5.2.2",
76
91
  "@types/jsdom": "^27.0.0",
77
- "@types/node": "^24.6.2",
78
- "@typescript/native-preview": "7.0.0-dev.20251005.1",
92
+ "@types/node": "^24.9.2",
93
+ "@typescript/native-preview": "7.0.0-dev.20251027.1",
79
94
  "chalk": "^5.6.2",
80
95
  "esno": "^4.8.0",
81
96
  "fast-glob": "^3.3.3",
82
- "jsdom": "^27.0.0",
83
- "oxlint-tsgolint": "^0.2.0",
97
+ "jsdom": "^27.0.1",
98
+ "oxlint-tsgolint": "^0.3.0",
84
99
  "tsup": "^8.5.0",
85
100
  "typescript": "^5.9.3",
86
- "vitest": "^3.2.4"
101
+ "vitest": "^4.0.4",
102
+ "zod": "^4.1.12"
87
103
  },
88
104
  "scripts": {
89
105
  "build": "tsgo --noEmit && tsup",
@@ -25,6 +25,12 @@ async function run() {
25
25
  lstatSync(join(distFolder, f)).isDirectory(),
26
26
  );
27
27
  for (const component of componentFolders) {
28
+ // If it's an old folder, delete it
29
+ if (!existsSync(join(sourceFolder, component))) {
30
+ await fs.rmdir(join(distFolder, component));
31
+ continue;
32
+ }
33
+
28
34
  console.log(chalk.cyan.inverse(" POST "), `Tidy ${component}`);
29
35
 
30
36
  // Loop through files and change declarations to imports so they get
@@ -85,9 +91,13 @@ async function run() {
85
91
  await fs.writeFile(join(distFolder, component, "index.d.ts"), dts);
86
92
  }
87
93
 
88
- // Move all utils/*.ts files into the dest folder
94
+ // Move all `utils` and `mount` TS files into the dest folder
89
95
  await moveUtils(distFolder, "utils");
90
96
  await moveUtils(distFolder, "mount");
97
+
98
+ // HACK: Move index.d.ts into the motion folder. This works because it's the
99
+ // only d.ts file we create (for now...?)
100
+ await fs.copyFile(join(distFolder, "index.d.ts"), join(distFolder, "motion", "index.d.ts"));
91
101
  }
92
102
 
93
103
  async function moveUtils(distFolder: string, folderName: string) {
@@ -1,5 +1,20 @@
1
1
  import { AccordionContextName, type AccordionContext, type ItemState } from "./AccordionTypes";
2
2
 
3
+ interface AccordionProps {
4
+ /** An ID for the root element */
5
+ id?: string;
6
+ /** Class name(s) for the root element */
7
+ class?: string,
8
+ /** Whether a single AccordionItem or multiple AccordionItems can be expanded at the same time */
9
+ type?: "single" | "multiple",
10
+ /** The value of the expanded AccordionItem, or an array of values if the type is "multiple" */
11
+ value?: string | string[],
12
+ /** If set to true, the user cannot interact with any items in the Accordion */
13
+ disabled?: boolean,
14
+ /** Raised when the expanded item(s) have changed */
15
+ onchange?: (value: string | string[]) => void,
16
+ }
17
+
3
18
  /**
4
19
  * A vertically stacked set of interactive headings that enable users to reveal
5
20
  * or hide associated sections of content.
@@ -18,15 +33,19 @@ import { AccordionContextName, type AccordionContext, type ItemState } from "./A
18
33
  * </AccordionItem>
19
34
  * </Accordion>
20
35
  * ```
21
- *
22
- * @prop {"single" | "multiple"} type -- Whether a single AccordionItem or multiple AccordionItems can be expanded at the same time
23
- * @prop {string | string[]} value -- The value of the expanded AccordionItem, or an array of values if the type is "multiple"
24
- * @prop {boolean} disabled -- If set to true, the user cannot interact with any items in the Accordion
25
- * @prop {(value: string | string[]) => void} [onchange] -- Raised when the expanded item(s) have changed
26
36
  */
27
- export default function Accordion($props: any) {
28
- $props.type ||= "single";
29
- $props.value ||= $props.type === "single" ? "" : [];
37
+ export default function Accordion($props: AccordionProps | undefined) {
38
+ let type = $props?.type ?? "single";
39
+
40
+ let $state = $watch({
41
+ value: $props?.value ?? (type === "single" ? "" : [] as string[])
42
+ });
43
+
44
+ $run(() => {
45
+ if ($props !== undefined) {
46
+ $props.value = $state.value;
47
+ }
48
+ });
30
49
 
31
50
  let itemStates: ItemState[] = [];
32
51
 
@@ -44,13 +63,13 @@ export default function Accordion($props: any) {
44
63
 
45
64
  $run(() => {
46
65
  // HACK: This should probably be done with setters?
47
- let newValue = $props.value;
66
+ let newValue = $state.value;
48
67
 
49
68
  // Get the value
50
- switch ($props.type) {
69
+ switch (type) {
51
70
  case "single": {
52
71
  // Ensure the value passed in was a string (in case e.g. the user has set values to ints)
53
- newValue = newValue?.toString();
72
+ newValue = newValue.toString();
54
73
  for (let item of itemStates) {
55
74
  item.expanded = item.value === newValue;
56
75
  }
@@ -69,18 +88,18 @@ export default function Accordion($props: any) {
69
88
  }
70
89
 
71
90
  // Set the value
72
- $props.value = newValue;
91
+ $state.value = newValue;
73
92
  })
74
93
 
75
94
  $run(() => {
76
- itemStates.forEach((s) => s.parentDisabled = $props.disabled);
95
+ itemStates.forEach((s) => s.parentDisabled = $props?.disabled === true);
77
96
  });
78
97
 
79
98
  // Dispatch the change event when the value changes
80
99
  let firstChange = true;
81
100
  $run(() => {
82
- const ev = $props.onchange;
83
- const value = $props.value;
101
+ const ev = $props?.onchange;
102
+ const value = $state.value;
84
103
  if (firstChange) {
85
104
  firstChange = false;
86
105
  } else if (ev) {
@@ -100,21 +119,21 @@ export default function Accordion($props: any) {
100
119
  }
101
120
 
102
121
  // If we have a value, set whether the item should be expanded
103
- if ($props.value) {
104
- switch ($props.type) {
122
+ if ($state.value) {
123
+ switch (type) {
105
124
  case "single": {
106
- itemState.expanded = $props.value === itemState.value;
125
+ itemState.expanded = $state.value === itemState.value;
107
126
  break;
108
127
  }
109
128
  case "multiple": {
110
- itemState.expanded = $props.value.includes(itemState.value);
129
+ itemState.expanded = $state.value.includes(itemState.value);
111
130
  break;
112
131
  }
113
132
  }
114
133
  }
115
134
 
116
135
  // Set whether the Accordion itself is disabled
117
- itemState.parentDisabled = $props.disabled
136
+ itemState.parentDisabled = $props?.disabled === true
118
137
 
119
138
  // Add the item's state to the array
120
139
  itemStates.splice(itemState.index, 0, itemState);
@@ -131,13 +150,13 @@ export default function Accordion($props: any) {
131
150
  }
132
151
 
133
152
  function toggleItem(toggleValue: string) {
134
- switch ($props.type) {
153
+ switch (type) {
135
154
  case "single": {
136
155
  for (let item of itemStates) {
137
156
  // The item is expanded if it has the supplied value (i.e. if it was clicked) and if it
138
157
  // wasn't already expanded (i.e. we collapse it if it was expanded and clicked)
139
158
  if (item.value === toggleValue) {
140
- $props.value = item.expanded ? "" : item.value;
159
+ $state.value = item.expanded ? "" : item.value;
141
160
  break;
142
161
  }
143
162
  }
@@ -155,7 +174,7 @@ export default function Accordion($props: any) {
155
174
  newValue.push(item.value);
156
175
  }
157
176
  }
158
- $props.value = newValue.sort();
177
+ $state.value = newValue.sort();
159
178
  break;
160
179
  }
161
180
  }
@@ -198,8 +217,8 @@ export default function Accordion($props: any) {
198
217
 
199
218
  @render {
200
219
  <div
201
- {$props.id}
202
- class={`torp-accordion ${$props.class ?? ""}`.trim()}
220
+ {$props?.id}
221
+ class={`torp-accordion ${$props?.class ?? ""}`.trim()}
203
222
  >
204
223
  <slot />
205
224
  </div>
@@ -1,32 +1,38 @@
1
1
  import getId from "../utils/getId";
2
2
  import { AccordionItemContextName, type AccordionItemContext } from "./AccordionTypes";
3
3
 
4
+ interface AccordionContentProps {
5
+ /** An ID for the root element */
6
+ id?: string;
7
+ /** Class name(s) for the root element */
8
+ class?: string,
9
+ /** Whether this content should act as a region. Set this when the content contains heading elements or a nested Accordion */
10
+ ariaRegion?: boolean,
11
+ }
12
+
4
13
  /**
5
14
  * Content for an AccordionItem, which can be revealed or hidden by an associated AccordionTrigger.
6
- *
7
- * @prop {string} [id] -- An ID for the AccordionContent's div container
8
- * @prop {boolean} [ariaRegion] -- Whether this content should act as a region. Set this when the content contains heading elements or a nested Accordion
9
15
  */
10
- export default function AccordionContent($props: any) {
11
- $props.id ||= getId();
16
+ export default function AccordionContent($props: AccordionContentProps | undefined) {
17
+ let defaultId = getId();
12
18
 
13
19
  const context = $context[AccordionItemContextName] as AccordionItemContext;
14
20
  if (!context) {
15
21
  throw new Error("AccordionContent must be contained within an AccordionItem");
16
22
  }
17
- let $state = $context[AccordionItemContextName].state
23
+ let $state = context.state
18
24
 
19
25
  // Set the content ID so that it can be used with aria-controls in AccordionTrigger
20
- $state.contentId = $props.id;
26
+ $state.contentId = $props?.id ?? defaultId;
21
27
 
22
28
  @render {
23
29
  <div
24
- {$props.id}
25
- class={`torp-accordion-content ${$props.class ?? ""}`.trim()}
26
- role={$props.ariaRegion ? "region" : undefined}
30
+ id={$props?.id ?? defaultId}
31
+ class={`torp-accordion-content ${$props?.class ?? ""}`.trim()}
32
+ role={$props?.ariaRegion ? "region" : undefined}
27
33
  aria-labelledby={$state.headerId}
28
- data-state={$state.dataState}
29
- data-disabled={$state.dataDisabled}
34
+ data-state={$state.expanded ? "open" : "closed"}
35
+ data-disabled={$state.disabled ? "true" : undefined}
30
36
  >
31
37
  @if ($state.expanded) {
32
38
  <slot />
@@ -1,5 +1,14 @@
1
1
  import { AccordionItemContextName, type AccordionItemContext } from "./AccordionTypes";
2
2
 
3
+ interface AccordionHeaderProps {
4
+ /** An ID for the root element */
5
+ id?: string;
6
+ /** Class name(s) for the root element */
7
+ class?: string,
8
+ /** The type of HTML header to use */
9
+ as?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6",
10
+ }
11
+
3
12
  /**
4
13
  * The header for an AccordionItem, which contains the AccordionTrigger.
5
14
  *
@@ -10,23 +19,21 @@ import { AccordionItemContextName, type AccordionItemContext } from "./Accordion
10
19
  * <AccordionTrigger />
11
20
  * </AccordionHeader>
12
21
  * ```
13
- *
14
- * @prop {"h1" | "h2" | "h3" | "h4" | "h5" | "h6"} as -- The type of HTML header to use
15
22
  */
16
- export default function AccordionHeader($props: any) {
23
+ export default function AccordionHeader($props: AccordionHeaderProps | undefined) {
17
24
  const context = $context[AccordionItemContextName] as AccordionItemContext;
18
25
  if (!context) {
19
26
  throw new Error("AccordionHeader must be contained within an AccordionItem");
20
27
  }
21
- let $state = $context[AccordionItemContextName].state
28
+ let $state = context.state
22
29
 
23
30
  @render {
24
31
  @// TODO: $props.as
25
32
  <h4
26
- {$props.id}
27
- class={`torp-accordion-header ${$props.class ?? ""}`.trim()}
28
- data-state={$state.dataState}
29
- data-disabled={$state.dataDisabled}
33
+ {$props?.id}
34
+ class={`torp-accordion-header ${$props?.class ?? ""}`.trim()}
35
+ data-state={$state.expanded ? "open" : "closed"}
36
+ data-disabled={$state.disabled ? "true" : undefined}
30
37
  >
31
38
  <slot />
32
39
  </h4>
@@ -1,4 +1,19 @@
1
- import { AccordionContextName, AccordionItemContextName, type AccordionContext, type AccordionItemContext } from "./AccordionTypes";
1
+ import { AccordionContextName, AccordionItemContextName, type ItemState, type AccordionContext, type AccordionItemContext } from "./AccordionTypes";
2
+
3
+ interface AccordionItemProps {
4
+ /** An ID for the root element */
5
+ id?: string;
6
+ /** Class name(s) for the root element */
7
+ class?: string,
8
+ /** The index of this item in the Accordion. Set this if you will be inserting, removing or sorting items. If you don't set this, it will be set automatically */
9
+ index?: number,
10
+ /** A value for the item. Set this if you need more control over which item(s) are expanded. If you don't set this, the value will be set to the item's initial index */
11
+ value?: string,
12
+ /** If set to true, the user cannot interact with this AccordionItem */
13
+ disabled?: boolean,
14
+ /** Raised when this item is opened or closed */
15
+ ontoggle?: (open: boolean) => void,
16
+ }
2
17
 
3
18
  /**
4
19
  * An item in an Accordion, which must consist of an AccordionTrigger and an AccordionContent.
@@ -13,22 +28,17 @@ import { AccordionContextName, AccordionItemContextName, type AccordionContext,
13
28
  * <AccordionContent />
14
29
  * </AccordionItem>
15
30
  * ```
16
- *
17
- * @prop {number} [index] -- The index of this item in the Accordion. Set this if you will be inserting, removing or sorting items. If you don't set this, it will be set automatically
18
- * @prop {string} [value] -- A value for the item. Set this if you need more control over which item(s) are expanded. If you don't set this, the value will be set to the item's initial index
19
- * @prop {boolean} [disabled] -- If set to true, the user cannot interact with this AccordionItem
20
- * @prop {(boolean) => void} [ontoggle] -- Raised when this item is opened or closed
21
31
  */
22
- export default function AccordionItem($props: any) {
32
+ export default function AccordionItem($props: AccordionItemProps | undefined) {
23
33
  let $state: ItemState = $watch({
24
34
  index: -1,
25
35
  value: "",
26
36
  expanded: false,
27
- disabled: $props.disabled,
37
+ headerId: "",
38
+ contentId: "",
39
+ disabled: $props?.disabled ?? false,
28
40
  parentDisabled: false,
29
- get dataState() {
30
- return this.expanded ? "open" : "closed";
31
- },
41
+ setFocused
32
42
  })
33
43
 
34
44
  // Get stuff out of the AccordionContext
@@ -46,7 +56,7 @@ export default function AccordionItem($props: any) {
46
56
  $context[AccordionItemContextName] = itemContext;
47
57
 
48
58
  // Register this item with the parent Accordion, which will handle toggling expanded for all items
49
- context.registerItem($state);
59
+ context.registerItem($state, setFocused);
50
60
 
51
61
  // Remove the item from the parent Accordion when this item is destroyed
52
62
  $run(() => {
@@ -58,7 +68,7 @@ export default function AccordionItem($props: any) {
58
68
  // Dispatch the toggle event when the value of expanded changes
59
69
  let firstToggle = true;
60
70
  $run(() => {
61
- const ev = $props.ontoggle;
71
+ const ev = $props?.ontoggle;
62
72
  const expanded = $state.expanded;
63
73
  if (firstToggle) {
64
74
  firstToggle = false;
@@ -67,12 +77,19 @@ export default function AccordionItem($props: any) {
67
77
  }
68
78
  });
69
79
 
80
+ // Called from the parent Accordion; pass the focus command along to the AccordionButton
81
+ function setFocused() {
82
+ if (itemContext.setHeaderFocused) {
83
+ itemContext.setHeaderFocused();
84
+ }
85
+ }
86
+
70
87
  @render {
71
88
  <div
72
- {$props.id}
73
- class={`torp-accordion-item ${$props.class ?? ""}`.trim()}
74
- data-state={$state.dataState}
75
- data-disabled={$state.dataDisabled}
89
+ {$props?.id}
90
+ class={`torp-accordion-item ${$props?.class ?? ""}`.trim()}
91
+ data-state={$state.expanded ? "open" : "closed"}
92
+ data-disabled={$state.disabled ? "true" : undefined}
76
93
  >
77
94
  <slot />
78
95
  </div>
@@ -1,23 +1,30 @@
1
1
  import getId from "../utils/getId";
2
2
  import { AccordionItemContextName, type AccordionItemContext } from "./AccordionTypes";
3
3
 
4
+ interface AccordionTriggerProps {
5
+ /** An ID for the root element */
6
+ id?: string;
7
+ /** Class name(s) for the root element */
8
+ class?: string,
9
+ }
10
+
4
11
  /**
5
12
  * A header button for an AccordionItem, which can be used to reveal or hide an associated AccordionContent.
6
13
  */
7
- export default function AccordionTrigger() {
8
- let button: HTMLButtonElement;
14
+ export default function AccordionTrigger($props: AccordionTriggerProps | undefined) {
15
+ let defaultId = getId();
9
16
 
10
- $props.id ||= getId();
17
+ let button: HTMLButtonElement;
11
18
 
12
19
  // Get stuff out of the AccordionItemContext
13
20
  const context = $context[AccordionItemContextName] as AccordionItemContext;
14
21
  if (!context) {
15
22
  throw new Error("AccordionTrigger must be contained within an AccordionItem");
16
23
  }
17
- let $state = $context[AccordionItemContextName].state;
24
+ let $state = context.state;
18
25
 
19
26
  // Set the header ID so that it can be used with aria-labelledby in AccordionContent
20
- $state.headerId = $props.id;
27
+ $state.headerId = $props?.id ?? defaultId;
21
28
 
22
29
  // Let the item know how to set the button's focus
23
30
  $state.setFocused = setFocused;
@@ -41,14 +48,14 @@ export default function AccordionTrigger() {
41
48
  @render {
42
49
  <button
43
50
  type="button"
44
- {$props.id}
45
- class={`torp-accordion-trigger ${$props.class ?? ""}`.trim()}
51
+ id={$props?.id ?? defaultId}
52
+ class={`torp-accordion-trigger ${$props?.class ?? ""}`.trim()}
46
53
  disabled={$state.disabled || $state.parentDisabled}
47
54
  aria-expanded={$state.expanded.toString()}
48
- aria-disabled={$state.disabled}
55
+ aria-disabled={$state.disabled ? "true" : undefined}
49
56
  aria-controls={$state.contentId}
50
- data-state={$state.dataState}
51
- data-disabled={$state.disabled}
57
+ data-state={$state.expanded ? "open" : "closed"}
58
+ data-disabled={$state.disabled ? "true" : undefined}
52
59
  &ref={button}
53
60
  onclick={handleClick}
54
61
  onkeydown={handleKey}