@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
@@ -5,15 +5,22 @@ import {
5
5
  type MenuPopoutContext
6
6
  } from "./MenuTypes";
7
7
 
8
+ interface MenuPopoutTriggerProps {
9
+ /** An ID for the root element */
10
+ id?: string;
11
+ /** Class name(s) for the root element */
12
+ class?: string,
13
+ /** The delay before showing the popout, in milliseconds */
14
+ hoverDelay?: number,
15
+ /** Whether this button is disabled */
16
+ disabled?: boolean,
17
+ }
18
+
8
19
  /**
9
20
  * A button that is placed in a Menu or MenuGroup and signals a response by a user.
10
- *
11
- * @prop {number} hoverDelay -- The delay before showing the popout, in milliseconds
12
- * @prop {boolean} disabled -- Whether this button is disabled
13
21
  */
14
- export default function MenuPopoutTrigger() {
15
- $props.hoverDelay ??= 500;
16
- $props.disabled ??= false;
22
+ export default function MenuPopoutTrigger($props: MenuPopoutTriggerProps | undefined) {
23
+ let defaultHoverDelay = 500;
17
24
 
18
25
  let button: HTMLButtonElement;
19
26
  let interval: NodeJS.Timeout | undefined;
@@ -63,16 +70,16 @@ export default function MenuPopoutTrigger() {
63
70
  }
64
71
 
65
72
  function handleMouseEnter() {
66
- if ($props.disabled) return;
73
+ if ($props?.disabled) return;
67
74
 
68
75
  // Handle the hover after a delay
69
76
  if (!interval) {
70
- interval = setTimeout(() => setVisible(true), $props.hoverDelay);
77
+ interval = setTimeout(() => setVisible(true), $props?.hoverDelay ?? defaultHoverDelay);
71
78
  }
72
79
  }
73
80
 
74
81
  function handleMouseLeave() {
75
- if ($props.disabled) return;
82
+ if ($props?.disabled) return;
76
83
 
77
84
  // Prevent short hovers or touches from firing the event
78
85
  if (interval) {
@@ -82,26 +89,26 @@ export default function MenuPopoutTrigger() {
82
89
  }
83
90
 
84
91
  function handleMouseMove() {
85
- if ($props.disabled) return;
92
+ if ($props?.disabled) return;
86
93
 
87
94
  // Reset the interval on mouse move
88
95
  if (interval) {
89
96
  clearTimeout(interval);
90
- interval = setTimeout(() => setVisible(true), $props.hoverDelay);
97
+ interval = setTimeout(() => setVisible(true), $props?.hoverDelay ?? defaultHoverDelay);
91
98
  }
92
99
  }
93
100
 
94
101
  @render {
95
102
  <button
96
- {$props.id}
97
- class={`torp-menu-popout-trigger ${$props.class ?? ""}`.trim()}
103
+ {$props?.id}
104
+ class={`torp-menu-popout-trigger ${$props?.class ?? ""}`.trim()}
98
105
  type="button"
99
- {$props.disabled}
106
+ {$props?.disabled}
100
107
  role="menuitem"
101
108
  aria-haspopup="true"
102
109
  aria-expanded={($state.visible ?? false).toString()}
103
- aria-disabled={$props.disabled ? "true" : undefined}
104
- data-disabled={$props.disabled ? "true" : undefined}
110
+ aria-disabled={$props?.disabled ? "true" : undefined}
111
+ data-disabled={$props?.disabled ? "true" : undefined}
105
112
  onkeydown={handlePopoutKey}
106
113
  onclick={handleClick}
107
114
  onfocus={() => handleItemFocus(index)}
@@ -7,21 +7,32 @@ import {
7
7
  type MenuRadioGroupContext
8
8
  } from "./MenuTypes";
9
9
 
10
+ interface MenuRadioProps {
11
+ /** An ID for the root element */
12
+ id?: string;
13
+ /** Class name(s) for the root element */
14
+ class?: string,
15
+ /** The value of the item */
16
+ value?: string,
17
+ /** Whether this item is checked */
18
+ checked?: boolean,
19
+ /** Whether this item is disabled */
20
+ disabled?: boolean,
21
+ }
22
+
10
23
  /**
11
24
  * A button that is placed in a Menu or MenuGroup to allow the user to select
12
25
  * from a number of options.
13
- *
14
- * @prop {string} value -- The value of the item
15
- * @prop {boolean} checked -- Whether this item is checked
16
- * @prop {boolean} disabled -- Whether this item is disabled
17
26
  */
18
- export default function MenuRadio() {
27
+ export default function MenuRadio($props: MenuRadioProps | undefined) {
19
28
  let $state = $watch({
20
- checked: $props.checked,
29
+ checked: $props?.checked ?? false,
21
30
  });
22
31
 
23
32
  $run(() => {
24
- $props.checked = $state.checked;
33
+ if ($props !== undefined) {
34
+ $props.checked = $state.checked;
35
+ }
25
36
  });
26
37
 
27
38
  let button: HTMLButtonElement;
@@ -44,7 +55,7 @@ export default function MenuRadio() {
44
55
  const { index } = registerItem(setFocused);
45
56
 
46
57
  // Register this item with the parent MenuRadioGroup
47
- registerItemInGroup($props.value, setChecked);
58
+ registerItemInGroup($props?.value ?? "", setChecked);
48
59
 
49
60
  // Set the context to pass down to items
50
61
  let context: MenuButtonContext = {
@@ -62,21 +73,21 @@ export default function MenuRadio() {
62
73
 
63
74
  function handleClick() {
64
75
  if (!$state.checked) {
65
- toggleItem($props.value);
76
+ toggleItem($props?.value ?? "");
66
77
  }
67
78
  }
68
79
 
69
80
  @render {
70
81
  <button
71
- {$props.id}
72
- class={`torp-menu-radio ${$props.class ?? ""}`.trim()}
82
+ {$props?.id}
83
+ class={`torp-menu-radio ${$props?.class ?? ""}`.trim()}
73
84
  type="button"
74
- {$props.disabled}
85
+ {$props?.disabled}
75
86
  role="menuitemradio"
76
- aria-checked={$props.checked}
77
- aria-disabled={$props.disabled ? "true" : undefined}
78
- data-state={$props.checked ? "checked" : "unchecked"}
79
- data-disabled={$props.disabled ? "true" : undefined}
87
+ aria-checked={$props?.checked}
88
+ aria-disabled={$props?.disabled ? "true" : undefined}
89
+ data-state={$props?.checked ? "checked" : "unchecked"}
90
+ data-disabled={$props?.disabled ? "true" : undefined}
80
91
  onkeydown={handleItemKey}
81
92
  onclick={handleClick}
82
93
  onfocus={() => handleItemFocus(index)}
@@ -4,17 +4,36 @@ import {
4
4
  type RadioGroupItemState
5
5
  } from "./MenuTypes";
6
6
 
7
+ interface MenuRadioGroupProps {
8
+ /** An ID for the root element */
9
+ id?: string;
10
+ /** Class name(s) for the root element */
11
+ class?: string,
12
+ /** An ARIA label for describing the menu to screen readers */
13
+ ariaLabel?: string,
14
+ /** The value of the checked MenuRadio */
15
+ value?: string | undefined,
16
+ /** Raised when the checked item has changed */
17
+ onchange?: (value: any) => void,
18
+ }
19
+
7
20
  /**
8
21
  * A container for a logical group of menu RadioGroup items.
9
- *
10
- * @prop {string} ariaLabel -- An ARIA label for describing the menu to screen readers
11
- * @prop {string | undefined} value -- The value of the checked MenuRadio
12
- * @prop {(any) => void} onchange - Called when the checked item has changed
13
22
  */
14
- export default function MenuRadioGroup() {
23
+ export default function MenuRadioGroup($props: MenuRadioGroupProps | undefined) {
15
24
  // A collection containing the state and some functions for each item
16
25
  let itemStates: RadioGroupItemState[] = [];
17
26
 
27
+ let $state = $watch({
28
+ value: $props?.value
29
+ });
30
+
31
+ $run(() => {
32
+ if ($props !== undefined) {
33
+ $props.value = $state.value;
34
+ }
35
+ });
36
+
18
37
  // Set the context to pass down to items
19
38
  let context: MenuRadioGroupContext = {
20
39
  registerItemInGroup,
@@ -24,11 +43,11 @@ export default function MenuRadioGroup() {
24
43
 
25
44
  $mount(() => {
26
45
  // Set the initial checked item
27
- setValue($props.value);
46
+ setValue($props?.value);
28
47
  });
29
48
 
30
49
  function registerItemInGroup(itemValue: string, setChecked: (value: boolean) => void) {
31
- // Add the item"s state to the array
50
+ // Add the item's state to the array
32
51
  const newItemState: RadioGroupItemState = {
33
52
  value: itemValue,
34
53
  checked: false,
@@ -52,11 +71,11 @@ export default function MenuRadioGroup() {
52
71
  }
53
72
 
54
73
  // Set the value
55
- if ($props.value !== newValue) {
56
- $props.value = newValue;
74
+ if ($state.value !== newValue) {
75
+ $state.value = newValue;
57
76
 
58
- if ($props.onchange) {
59
- $props.onchange($props.value);
77
+ if ($props?.onchange) {
78
+ $props?.onchange($props?.value);
60
79
  }
61
80
  }
62
81
  }
@@ -70,15 +89,15 @@ export default function MenuRadioGroup() {
70
89
  newValue = item.value;
71
90
  }
72
91
  }
73
- $props.value = newValue;
92
+ $state.value = newValue;
74
93
  }
75
94
 
76
95
  @render {
77
96
  <div
78
- {$props.id}
79
- class={`torp-menu-radio-group ${$props.class ?? ""}`.trim()}
97
+ {$props?.id}
98
+ class={`torp-menu-radio-group ${$props?.class ?? ""}`.trim()}
80
99
  role="group"
81
- aria-label={$props.ariaLabel}
100
+ aria-label={$props?.ariaLabel}
82
101
  >
83
102
  <slot />
84
103
  </div>
@@ -1,11 +1,19 @@
1
+
2
+ interface MenuSeparatorProps {
3
+ /** An ID for the root element */
4
+ id?: string;
5
+ /** Class name(s) for the root element */
6
+ class?: string,
7
+ }
8
+
1
9
  /**
2
10
  * An element in a menu that separates logical sets of menu items.
3
11
  */
4
- export default function MenuSeparator() {
12
+ export default function MenuSeparator($props: MenuSeparatorProps | undefined) {
5
13
  @render {
6
14
  <div
7
- {$props.id}
8
- class={`torp-menu-separator ${$props.class ?? ""}`.trim()}
15
+ {$props?.id}
16
+ class={`torp-menu-separator ${$props?.class ?? ""}`.trim()}
9
17
  role="separator"
10
18
  >
11
19
  <slot />
@@ -7,7 +7,7 @@ export interface MenuContext {
7
7
  setVisible: (value: boolean, result?: any) => void;
8
8
 
9
9
  /** Called from a MenuButton to close the Menu and return a result */
10
- handleTrigger: (type: "confirm" | "cancel" | undefined, value?: any) => void;
10
+ handleButton: (type: "confirm" | "cancel" | undefined, value?: any) => void;
11
11
 
12
12
  /** Called from a MenuButton when its button is focused */
13
13
  handleItemFocus: (index: number) => void;
@@ -15,10 +15,7 @@ export interface MenuContext {
15
15
  /** Called from a MenuButton when a key is pressed */
16
16
  handleItemKey: (e: KeyboardEvent) => void;
17
17
 
18
- state: {
19
- /** Whether the Menu is visible. Writable so that it can be subscribed to by children */
20
- visible: boolean;
21
- };
18
+ state: MenuState;
22
19
 
23
20
  /** The element that caused this Menu to be shown */
24
21
  anchorElement?: HTMLElement;
@@ -27,6 +24,11 @@ export interface MenuContext {
27
24
  registerItem: (setFocused: () => void) => { index: number };
28
25
  }
29
26
 
27
+ export interface MenuState {
28
+ /** Whether the Menu is visible */
29
+ visible: boolean;
30
+ }
31
+
30
32
  export interface MenuButtonContext {
31
33
  state: {
32
34
  checked: boolean;
@@ -1,5 +1,16 @@
1
1
  import { MenuBarContextName, type MenuBarContext, type ItemState } from "./MenuBarTypes";
2
2
 
3
+ interface MenuBarProps {
4
+ /** An ID for the root element */
5
+ id?: string;
6
+ /** Class name(s) for the root element */
7
+ class?: string,
8
+ /** An ARIA label for describing the menu to screen readers */
9
+ ariaLabel?: string,
10
+ /** The orientation of the menu, which affects keyboard navigation */
11
+ orientation?: "horizontal" | "vertical",
12
+ }
13
+
3
14
  /**
4
15
  * A menu bar, similar to that shown at the top of Windows applications or at the top of the screen on Macs.
5
16
  *
@@ -9,20 +20,17 @@ import { MenuBarContextName, type MenuBarContext, type ItemState } from "./MenuB
9
20
  *
10
21
  * ```
11
22
  * <MenuBar>
12
- * <MenuBarItem>
13
- * <MenuBarItemTrigger />
14
- * <MenuBarItemContent>
15
- * <Menu />
16
- * </MenuBarItemContent>
17
- * </MenuBarItem>
23
+ * <MenuBarItem>
24
+ * <MenuBarItemTrigger />
25
+ * <MenuBarItemContent>
26
+ * <Menu />
27
+ * </MenuBarItemContent>
28
+ * </MenuBarItem>
18
29
  * </MenuBar>
19
30
  * ```
20
- *
21
- * @prop {string} ariaLabel -- An ARIA label for describing the menu to screen readers
22
- * @prop {"horizontal" | "vertical"} orientation -- The orientation of the menu, which affects keyboard navigation
23
31
  */
24
- export default function MenuBar() {
25
- $props.orientation ??= "horizontal";
32
+ export default function MenuBar($props: MenuBarProps | undefined) {
33
+ let orientation = $props?.orientation ?? "horizontal";
26
34
 
27
35
  let $state = $watch({
28
36
  active: false,
@@ -43,7 +51,7 @@ export default function MenuBar() {
43
51
  $context[MenuBarContextName] = context;
44
52
 
45
53
  function registerItem(setVisible: (value: boolean) => void, setFocused: () => void) {
46
- // Add the item"s state to the array and return its index
54
+ // Add the item's state to the array and return its index
47
55
  const newItemState: ItemState = {
48
56
  setVisible,
49
57
  setFocused
@@ -137,12 +145,12 @@ export default function MenuBar() {
137
145
 
138
146
  @render {
139
147
  <div
140
- {$props.id}
141
- class={`torp-menu-bar ${$props.class ?? ""}`.trim()}
148
+ {$props?.id}
149
+ class={`torp-menu-bar ${$props?.class ?? ""}`.trim()}
142
150
  tabindex="-1"
143
151
  role="menubar"
144
- aria-label={$props.ariaLabel}
145
- aria-orientation={$props.orientation}
152
+ aria-label={$props?.ariaLabel}
153
+ aria-orientation={orientation}
146
154
  >
147
155
  <slot />
148
156
  </div>
@@ -6,6 +6,21 @@ import {
6
6
  } from "./MenuBarTypes";
7
7
  import { PopoverContextName, type PopoverContext } from "../Popover/PopoverTypes";
8
8
 
9
+ interface MenuBarItemProps {
10
+ /** An ID for the root element */
11
+ id?: string;
12
+ /** Class name(s) for the root element */
13
+ class?: string,
14
+ /** Whether the item is visible */
15
+ visible?: boolean,
16
+ /** Raised when the item is opened or closed */
17
+ ontoggle?: (visible: boolean) => void,
18
+ /** Raised when the item has opened */
19
+ onopen?: () => void,
20
+ /** Raised when the item has closed */
21
+ onclose?: (result: any) => void,
22
+ }
23
+
9
24
  /**
10
25
  * A popout that is attached to a menubar button and can be used to show a submenu.
11
26
  *
@@ -13,21 +28,14 @@ import { PopoverContextName, type PopoverContext } from "../Popover/PopoverTypes
13
28
  *
14
29
  * ```
15
30
  * <MenuBarItem>
16
- * <MenuBarItemTrigger /> (optional)
17
- * <MenuBarItemContent />
31
+ * <MenuBarItemTrigger /> (optional)
32
+ * <MenuBarItemContent />
18
33
  * </MenuBarItem>
19
34
  * ```
20
- *
21
- * @prop {boolean} visible -- Whether the item is visible
22
- * @prop {(boolean) => void} ontoggle -- Called when the item is opened or closed
23
- * @prop {() => void} onopen -- Called when the item has opened
24
- * @prop {() => void} onclose -- Called when the item has closed
25
35
  */
26
- export default function MenuBarItem() {
27
- $props.visible ??= false;
28
-
36
+ export default function MenuBarItem($props: MenuBarItemProps | undefined) {
29
37
  let $state = $watch({
30
- visible: $props.visible
38
+ visible: $props?.visible ?? false
31
39
  });
32
40
 
33
41
  let result: any;
@@ -72,9 +80,9 @@ export default function MenuBarItem() {
72
80
 
73
81
  let firstToggle = true;
74
82
  $run(() => {
75
- const ontoggle = $props.ontoggle;
76
- const onopen = $props.onopen;
77
- const onclose = $props.onclose;
83
+ const ontoggle = $props?.ontoggle;
84
+ const onopen = $props?.onopen;
85
+ const onclose = $props?.onclose;
78
86
  const visible = $state.visible;
79
87
  if (firstToggle) {
80
88
  firstToggle = false;
@@ -95,8 +103,8 @@ export default function MenuBarItem() {
95
103
 
96
104
  @render {
97
105
  <div
98
- {$props.id}
99
- class={`torp-menu-bar-item ${$props.class ?? ""}`.trim()}
106
+ {$props?.id}
107
+ class={`torp-menu-bar-item ${$props?.class ?? ""}`.trim()}
100
108
  >
101
109
  <slot />
102
110
  </div>
@@ -7,16 +7,21 @@ import {
7
7
  type MenuBarItemContext
8
8
  } from "./MenuBarTypes";
9
9
 
10
+ interface MenuBarItemContentProps {
11
+ /** An ID for the root element */
12
+ id?: string;
13
+ /** Class name(s) for the root element */
14
+ class?: string,
15
+ /** Where the popout will be shown, relative to the popout button */
16
+ side?: "top" | "right" | "bottom" | "left",
17
+ /** How the popout will be aligned, relative to the popout button */
18
+ alignment?: "start" | "center" | "end",
19
+ }
20
+
10
21
  /**
11
22
  * The content that is displayed for a MenuBarItem when it is open.
12
- *
13
- * @prop {"top" | "right" | "bottom" | "left"} side -- Where the popout will be shown, relative to the popout button
14
- * @prop {"start" | "center" | "end"} alignment -- How the popout will be aligned, relative to the popout button
15
23
  */
16
- export default function MenuBarItemContent() {
17
- $props.side ??= "bottom";
18
- $props.alignment ??= "start";
19
-
24
+ export default function MenuBarItemContent($props: MenuBarItemContentProps | undefined) {
20
25
  let div: HTMLDivElement;
21
26
  let closeOnClick = false;
22
27
  let shown = false;
@@ -80,7 +85,7 @@ export default function MenuBarItemContent() {
80
85
 
81
86
  function handleDocumentClick(e: MouseEvent) {
82
87
  if (closeOnClick && !div.contains(e.target as HTMLElement)) {
83
- context.active = false;
88
+ //context.active = false;
84
89
  setVisible(false);
85
90
  }
86
91
  }
@@ -90,14 +95,16 @@ export default function MenuBarItemContent() {
90
95
  throw new Error("MenuBarItemContent must have an anchor element");
91
96
  }
92
97
 
93
- setPopoverPosition(itemContext.anchorElement, div, $props.side, $props.alignment);
98
+ let side = $props?.side ?? "bottom";
99
+ let alignment = $props?.alignment ?? "start";
100
+ setPopoverPosition(itemContext.anchorElement, div, side, alignment);
94
101
  }
95
102
 
96
103
  @render {
97
104
  @if ($state.visible) {
98
105
  <div
99
- {$props.id}
100
- class={`torp-menu-bar-item-content ${$props.class ?? ""}`.trim()}
106
+ {$props?.id}
107
+ class={`torp-menu-bar-item-content ${$props?.class ?? ""}`.trim()}
101
108
  &ref={div}
102
109
  onmount={show}
103
110
  >
@@ -5,14 +5,20 @@ import {
5
5
  type MenuBarItemContext
6
6
  } from "./MenuBarTypes";
7
7
 
8
+ interface MenuBarItemTriggerProps {
9
+ /** An ID for the root element */
10
+ id?: string;
11
+ /** Class name(s) for the root element */
12
+ class?: string,
13
+ /** Whether this button is disabled */
14
+ disabled?: boolean,
15
+ }
16
+
8
17
  /**
9
18
  * A button that is placed in a MenuBar and opens a submenu.
10
19
  *
11
- * @prop {boolean} disabled -- Whether this button is disabled
12
20
  */
13
- export default function MenuBarItemTrigger() {
14
- $props.disabled ??= false;
15
-
21
+ export default function MenuBarItemTrigger($props: MenuBarItemTriggerProps | undefined) {
16
22
  let button: HTMLButtonElement;
17
23
 
18
24
  // Get stuff out of the MenuBarContext
@@ -67,15 +73,15 @@ export default function MenuBarItemTrigger() {
67
73
 
68
74
  @render {
69
75
  <button
70
- {$props.id}
71
- class={`torp-menu-bar-item-button ${$props.class ?? ""}`.trim()}
76
+ {$props?.id}
77
+ class={`torp-menu-bar-item-button ${$props?.class ?? ""}`.trim()}
72
78
  type="button"
73
- {$props.disabled}
79
+ {$props?.disabled}
74
80
  role="menuitem"
75
81
  aria-haspopup="true"
76
82
  aria-expanded={($state.visible ?? false).toString()}
77
- aria-disabled={$props.disabled ? "true" : undefined}
78
- data-disabled={$props.disabled ? "true" : undefined}
83
+ aria-disabled={$props?.disabled ? "true" : undefined}
84
+ data-disabled={$props?.disabled ? "true" : undefined}
79
85
  onkeydown={handleKey}
80
86
  onclick={handleClick}
81
87
  onfocus={() => handleButtonFocus(index)}
@@ -0,0 +1,118 @@
1
+ import { ModalContextName, type ModalContext, type ModalState } from "./ModalTypes";
2
+
3
+ interface ModalProps {
4
+ /** An ID for the root element */
5
+ id?: string;
6
+ /** Class name(s) for the root element */
7
+ class?: string,
8
+ /** Whether the modal is visible */
9
+ visible?: boolean,
10
+ /** A function to be called when the user selects a response */
11
+ callback?: ((value: any) => void),
12
+ /** Raised when the modal is opened or closed */
13
+ ontoggle?: (open: boolean) => void,
14
+ /** Raised when the modal has opened */
15
+ onopen?: () => void,
16
+ /** Raised when the modal has closed */
17
+ onclose?: (result: any) => void,
18
+ }
19
+
20
+ /**
21
+ * A modal window that can be used to show rich content or obtain information from a user.
22
+ *
23
+ * See [the WAI ARIA guidelines for Modals](https://www.w3.org/WAI/ARIA/apg/patterns/dialogmodal/).
24
+ *
25
+ * The structure of a Modal is:
26
+ *
27
+ * ```
28
+ * <Modal>
29
+ * <ModalOverlay />
30
+ * <ModalTrigger /> (optional)
31
+ * <ModalContent />
32
+ * </Modal>
33
+ * ```
34
+ */
35
+ export default function Modal($props: ModalProps | undefined) {
36
+ let $state: ModalState = $watch({
37
+ visible: false,
38
+ })
39
+
40
+ // Sync props and state
41
+ $run(() => {
42
+ $state.visible = $props?.visible ?? false;
43
+ });
44
+ $run(() => {
45
+ if ($props !== undefined) {
46
+ $props.visible = $state.visible;
47
+ }
48
+ });
49
+
50
+ let result: any;
51
+
52
+ // Set the context to pass down to items
53
+ let context: ModalContext = {
54
+ handleButton,
55
+ handleClickOutside,
56
+ state: $state,
57
+ };
58
+ $context[ModalContextName] = context;
59
+
60
+ // Dispatch the toggle event when the modal is opened or closed
61
+ let firstToggle = true;
62
+ $run(() => {
63
+ const ontoggle = $props?.ontoggle;
64
+ const onopen = $props?.onopen;
65
+ const onclose = $props?.onclose;
66
+ const visible = $state.visible;
67
+ if (firstToggle) {
68
+ firstToggle = false;
69
+ } else {
70
+ if (ontoggle) ontoggle(visible);
71
+ if (visible) {
72
+ if (onopen) onopen()
73
+ } else {
74
+ if (onclose) onclose(result);
75
+ }
76
+ }
77
+ });
78
+
79
+ function handleButton(type: "confirm" | "cancel" | undefined, value?: any) {
80
+ // Get the button's result
81
+ switch (type) {
82
+ case "confirm": {
83
+ result = value || true;
84
+ break;
85
+ }
86
+ case "cancel": {
87
+ result = value || false;
88
+ break;
89
+ }
90
+ default: {
91
+ result = value;
92
+ break;
93
+ }
94
+ }
95
+
96
+ // Hide the modal
97
+ $state.visible = false;
98
+
99
+ // Call the callback
100
+ if ($props?.callback) {
101
+ $props?.callback(result);
102
+ }
103
+ }
104
+
105
+ function handleClickOutside(e: MouseEvent) {
106
+ e.preventDefault();
107
+ $state.visible = false;
108
+ }
109
+
110
+ @render {
111
+ <div
112
+ {$props?.id}
113
+ class={`torp-modal ${$props?.class ?? ""}`.trim()}
114
+ >
115
+ <slot />
116
+ </div>
117
+ }
118
+ }