@torpor/ui 0.2.1 → 0.3.1

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 (304) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/dist/Accordion/Accordion.torp +29 -22
  3. package/dist/Accordion/AccordionContent.torp +7 -8
  4. package/dist/Accordion/AccordionHeader.torp +4 -6
  5. package/dist/Accordion/AccordionItem.torp +15 -12
  6. package/dist/Accordion/AccordionTrigger.torp +6 -7
  7. package/dist/Accordion/AccordionTypes.ts +4 -3
  8. package/dist/Accordion/index.d.ts +5 -5
  9. package/dist/Breadcrumb/Breadcrumb.torp +9 -10
  10. package/dist/Breadcrumb/BreadcrumbItem.torp +5 -7
  11. package/dist/Breadcrumb/BreadcrumbSeparator.torp +3 -5
  12. package/dist/Breadcrumb/index.d.ts +8 -7
  13. package/dist/Calendar/Calendar.torp +12 -13
  14. package/dist/Calendar/CalendarDay.torp +3 -3
  15. package/dist/Contextual/Contextual.torp +125 -0
  16. package/dist/{Popover/PopoverContentContextual.torp → Contextual/ContextualContent.torp} +15 -15
  17. package/dist/Contextual/ContextualTrigger.torp +66 -0
  18. package/dist/Contextual/ContextualTypes.ts +30 -0
  19. package/dist/Contextual/index.d.ts +90 -0
  20. package/dist/Contextual/index.js +14 -0
  21. package/dist/Contextual/index.js.map +1 -0
  22. package/dist/Dialog/Dialog.torp +38 -72
  23. package/dist/Dialog/DialogBody.torp +6 -8
  24. package/dist/Dialog/DialogButton.torp +14 -12
  25. package/dist/Dialog/DialogFooter.torp +3 -5
  26. package/dist/Dialog/DialogHeader.torp +6 -8
  27. package/dist/Dialog/DialogTypes.ts +3 -2
  28. package/dist/Dialog/index.d.ts +16 -11
  29. package/dist/Disclosure/Disclosure.torp +22 -23
  30. package/dist/Disclosure/DisclosureContent.torp +7 -8
  31. package/dist/Disclosure/DisclosureHeader.torp +5 -7
  32. package/dist/Disclosure/DisclosureTrigger.torp +7 -8
  33. package/dist/Disclosure/DisclosureTypes.ts +0 -1
  34. package/dist/Disclosure/index.d.ts +12 -12
  35. package/dist/Drawer/Drawer.torp +101 -70
  36. package/dist/Drawer/DrawerContent.torp +80 -0
  37. package/dist/Drawer/DrawerOverlay.torp +38 -0
  38. package/dist/Drawer/DrawerTrigger.torp +35 -0
  39. package/dist/Drawer/DrawerTypes.ts +24 -0
  40. package/dist/Drawer/index.d.ts +90 -3
  41. package/dist/Drawer/index.js +13 -1
  42. package/dist/Form/CheckBox.torp +91 -0
  43. package/dist/Form/Field.torp +2 -4
  44. package/dist/Form/File.torp +106 -0
  45. package/dist/Form/Form.torp +17 -10
  46. package/dist/Form/FormTypes.ts +5 -0
  47. package/dist/Form/Input.torp +28 -17
  48. package/dist/Form/Label.torp +1 -1
  49. package/dist/Form/Message.torp +1 -1
  50. package/dist/Form/Option.torp +24 -0
  51. package/dist/Form/Select.torp +97 -0
  52. package/dist/Form/TextArea.torp +101 -0
  53. package/dist/Form/index.d.ts +192 -5
  54. package/dist/Form/index.js +21 -1
  55. package/dist/Menu/Menu.torp +16 -15
  56. package/dist/Menu/MenuButton.torp +19 -13
  57. package/dist/Menu/MenuCheck.torp +18 -14
  58. package/dist/Menu/MenuGroup.torp +4 -6
  59. package/dist/Menu/MenuIndicator.torp +5 -7
  60. package/dist/Menu/MenuPopout.torp +12 -15
  61. package/dist/Menu/MenuPopoutContent.torp +6 -8
  62. package/dist/Menu/MenuPopoutTrigger.torp +12 -14
  63. package/dist/Menu/MenuRadio.torp +14 -14
  64. package/dist/Menu/MenuRadioGroup.torp +22 -14
  65. package/dist/Menu/MenuSeparator.torp +3 -5
  66. package/dist/Menu/MenuTypes.ts +7 -5
  67. package/dist/Menu/index.d.ts +28 -22
  68. package/dist/MenuBar/MenuBar.torp +13 -14
  69. package/dist/MenuBar/MenuBarItem.torp +13 -16
  70. package/dist/MenuBar/MenuBarItemContent.torp +7 -9
  71. package/dist/MenuBar/MenuBarItemTrigger.torp +6 -9
  72. package/dist/MenuBar/index.d.ts +16 -16
  73. package/dist/Modal/Modal.torp +118 -0
  74. package/dist/Modal/ModalContent.torp +77 -0
  75. package/dist/Modal/ModalOverlay.torp +38 -0
  76. package/dist/Modal/ModalTrigger.torp +50 -0
  77. package/dist/Modal/ModalTypes.ts +22 -0
  78. package/dist/Modal/index.d.ts +108 -0
  79. package/dist/Modal/index.js +33 -0
  80. package/dist/Modal/index.js.map +1 -0
  81. package/dist/Modal/showModal.ts +19 -0
  82. package/dist/Modal/showPrompt.ts +23 -0
  83. package/dist/NavMenu/NavMenu.torp +7 -8
  84. package/dist/NavMenu/NavMenuButton.torp +6 -8
  85. package/dist/NavMenu/NavMenuElement.torp +8 -8
  86. package/dist/NavMenu/NavMenuGroup.torp +4 -6
  87. package/dist/NavMenu/NavMenuGroupHeader.torp +5 -6
  88. package/dist/NavMenu/NavMenuLink.torp +8 -11
  89. package/dist/NavMenu/NavMenuPopout.torp +25 -17
  90. package/dist/NavMenu/NavMenuPopoutButton.torp +12 -13
  91. package/dist/NavMenu/NavMenuPopoutContent.torp +12 -12
  92. package/dist/NavMenu/NavMenuSeparator.torp +3 -5
  93. package/dist/NavMenu/index.d.ts +17 -11
  94. package/dist/Notification/Notification.torp +22 -13
  95. package/dist/Notification/NotificationClose.torp +3 -5
  96. package/dist/Notification/NotificationContainer.torp +3 -5
  97. package/dist/Notification/NotificationContent.torp +3 -5
  98. package/dist/Notification/index.d.ts +4 -4
  99. package/dist/Popover/Popover.torp +31 -25
  100. package/dist/Popover/PopoverContent.torp +35 -10
  101. package/dist/Popover/PopoverTrigger.torp +24 -4
  102. package/dist/Popover/PopoverTypes.ts +1 -1
  103. package/dist/Popover/index.d.ts +16 -124
  104. package/dist/Popover/index.js +1 -163
  105. package/dist/Popover/index.js.map +1 -1
  106. package/dist/TabGroup/TabContent.torp +12 -9
  107. package/dist/TabGroup/TabGroup.torp +41 -35
  108. package/dist/TabGroup/TabGroupTypes.ts +10 -5
  109. package/dist/TabGroup/TabHeader.torp +15 -8
  110. package/dist/TabGroup/TabList.torp +4 -6
  111. package/dist/TabGroup/TabTrigger.torp +8 -9
  112. package/dist/TabGroup/index.d.ts +14 -6
  113. package/dist/icons/ArrowDown.torp +3 -1
  114. package/dist/icons/ArrowLeft.torp +3 -1
  115. package/dist/icons/ArrowRight.torp +3 -1
  116. package/dist/icons/ArrowUp.torp +3 -1
  117. package/dist/icons/Bars.torp +3 -1
  118. package/dist/icons/Check.torp +3 -1
  119. package/dist/icons/ChevronDown.torp +3 -1
  120. package/dist/icons/ChevronLeft.torp +3 -1
  121. package/dist/icons/ChevronRight.torp +3 -1
  122. package/dist/icons/ChevronUp.torp +3 -1
  123. package/dist/icons/Cross.torp +3 -1
  124. package/dist/icons/IconTypes.ts +6 -0
  125. package/dist/icons/Loading.torp +3 -1
  126. package/dist/icons/Minus.torp +3 -1
  127. package/dist/icons/Plus.torp +3 -1
  128. package/dist/icons/index.d.ts +271 -14
  129. package/dist/index.d.ts +17 -4
  130. package/dist/metafile-esm.json +1 -1
  131. package/dist/motion/fade.ts +15 -6
  132. package/dist/motion/grow.ts +23 -0
  133. package/dist/motion/index.d.ts +19 -2
  134. package/dist/motion/index.js +93 -3
  135. package/dist/motion/index.js.map +1 -1
  136. package/dist/motion/measure.ts +28 -0
  137. package/dist/motion/slide.ts +45 -0
  138. package/dist/mount/clickPopover.ts +51 -0
  139. package/dist/mount/contextPopover.ts +51 -0
  140. package/dist/mount/hoverPopover.ts +58 -0
  141. package/package.json +21 -14
  142. package/scripts/postbuild.ts +11 -1
  143. package/src/Accordion/Accordion.torp +29 -22
  144. package/src/Accordion/AccordionContent.torp +7 -8
  145. package/src/Accordion/AccordionHeader.torp +4 -6
  146. package/src/Accordion/AccordionItem.torp +15 -12
  147. package/src/Accordion/AccordionTrigger.torp +6 -7
  148. package/src/Accordion/AccordionTypes.ts +4 -3
  149. package/src/Breadcrumb/Breadcrumb.torp +9 -10
  150. package/src/Breadcrumb/BreadcrumbItem.torp +5 -7
  151. package/src/Breadcrumb/BreadcrumbSeparator.torp +3 -5
  152. package/src/Calendar/Calendar.torp +12 -13
  153. package/src/Calendar/CalendarDay.torp +3 -3
  154. package/src/Contextual/Contextual.torp +125 -0
  155. package/src/{Popover/PopoverContentContextual.torp → Contextual/ContextualContent.torp} +15 -15
  156. package/src/Contextual/ContextualTrigger.torp +66 -0
  157. package/src/Contextual/ContextualTypes.ts +30 -0
  158. package/src/Contextual/index.ts +5 -0
  159. package/src/Dialog/Dialog.torp +38 -72
  160. package/src/Dialog/DialogBody.torp +6 -8
  161. package/src/Dialog/DialogButton.torp +14 -12
  162. package/src/Dialog/DialogFooter.torp +3 -5
  163. package/src/Dialog/DialogHeader.torp +6 -8
  164. package/src/Dialog/DialogTypes.ts +3 -2
  165. package/src/Disclosure/Disclosure.torp +22 -23
  166. package/src/Disclosure/DisclosureContent.torp +7 -8
  167. package/src/Disclosure/DisclosureHeader.torp +5 -7
  168. package/src/Disclosure/DisclosureTrigger.torp +7 -8
  169. package/src/Disclosure/DisclosureTypes.ts +0 -1
  170. package/src/Drawer/Drawer.torp +101 -70
  171. package/src/Drawer/DrawerContent.torp +80 -0
  172. package/src/Drawer/DrawerOverlay.torp +38 -0
  173. package/src/Drawer/DrawerTrigger.torp +35 -0
  174. package/src/Drawer/DrawerTypes.ts +24 -0
  175. package/src/Drawer/index.ts +4 -1
  176. package/src/Form/CheckBox.torp +91 -0
  177. package/src/Form/Field.torp +2 -4
  178. package/src/Form/File.torp +106 -0
  179. package/src/Form/Form.torp +17 -10
  180. package/src/Form/FormTypes.ts +5 -0
  181. package/src/Form/Input.torp +28 -17
  182. package/src/Form/Label.torp +1 -1
  183. package/src/Form/Message.torp +1 -1
  184. package/src/Form/Option.torp +24 -0
  185. package/src/Form/Select.torp +97 -0
  186. package/src/Form/TextArea.torp +101 -0
  187. package/src/Form/index.ts +6 -1
  188. package/src/Menu/Menu.torp +16 -15
  189. package/src/Menu/MenuButton.torp +19 -13
  190. package/src/Menu/MenuCheck.torp +18 -14
  191. package/src/Menu/MenuGroup.torp +4 -6
  192. package/src/Menu/MenuIndicator.torp +5 -7
  193. package/src/Menu/MenuPopout.torp +12 -15
  194. package/src/Menu/MenuPopoutContent.torp +6 -8
  195. package/src/Menu/MenuPopoutTrigger.torp +12 -14
  196. package/src/Menu/MenuRadio.torp +14 -14
  197. package/src/Menu/MenuRadioGroup.torp +22 -14
  198. package/src/Menu/MenuSeparator.torp +3 -5
  199. package/src/Menu/MenuTypes.ts +7 -5
  200. package/src/MenuBar/MenuBar.torp +13 -14
  201. package/src/MenuBar/MenuBarItem.torp +13 -16
  202. package/src/MenuBar/MenuBarItemContent.torp +7 -9
  203. package/src/MenuBar/MenuBarItemTrigger.torp +6 -9
  204. package/src/Modal/Modal.torp +118 -0
  205. package/src/Modal/ModalContent.torp +77 -0
  206. package/src/Modal/ModalOverlay.torp +38 -0
  207. package/src/Modal/ModalTrigger.torp +50 -0
  208. package/src/Modal/ModalTypes.ts +22 -0
  209. package/src/Modal/index.ts +10 -0
  210. package/src/Modal/showModal.ts +19 -0
  211. package/src/Modal/showPrompt.ts +23 -0
  212. package/src/NavMenu/NavMenu.torp +7 -8
  213. package/src/NavMenu/NavMenuButton.torp +6 -8
  214. package/src/NavMenu/NavMenuElement.torp +8 -8
  215. package/src/NavMenu/NavMenuGroup.torp +4 -6
  216. package/src/NavMenu/NavMenuGroupHeader.torp +5 -6
  217. package/src/NavMenu/NavMenuLink.torp +8 -11
  218. package/src/NavMenu/NavMenuPopout.torp +25 -17
  219. package/src/NavMenu/NavMenuPopoutButton.torp +12 -13
  220. package/src/NavMenu/NavMenuPopoutContent.torp +12 -12
  221. package/src/NavMenu/NavMenuSeparator.torp +3 -5
  222. package/src/Notification/Notification.torp +22 -13
  223. package/src/Notification/NotificationClose.torp +3 -5
  224. package/src/Notification/NotificationContainer.torp +3 -5
  225. package/src/Notification/NotificationContent.torp +3 -5
  226. package/src/Popover/Popover.torp +31 -25
  227. package/src/Popover/PopoverContent.torp +35 -10
  228. package/src/Popover/PopoverTrigger.torp +24 -4
  229. package/src/Popover/PopoverTypes.ts +1 -1
  230. package/src/Popover/index.ts +1 -24
  231. package/src/Slider/Slider.torp +3 -3
  232. package/src/TabGroup/TabContent.torp +12 -9
  233. package/src/TabGroup/TabGroup.torp +41 -35
  234. package/src/TabGroup/TabGroupTypes.ts +10 -5
  235. package/src/TabGroup/TabHeader.torp +15 -8
  236. package/src/TabGroup/TabList.torp +4 -6
  237. package/src/TabGroup/TabTrigger.torp +8 -9
  238. package/src/icons/ArrowDown.torp +3 -1
  239. package/src/icons/ArrowLeft.torp +3 -1
  240. package/src/icons/ArrowRight.torp +3 -1
  241. package/src/icons/ArrowUp.torp +3 -1
  242. package/src/icons/Bars.torp +3 -1
  243. package/src/icons/Check.torp +3 -1
  244. package/src/icons/ChevronDown.torp +3 -1
  245. package/src/icons/ChevronLeft.torp +3 -1
  246. package/src/icons/ChevronRight.torp +3 -1
  247. package/src/icons/ChevronUp.torp +3 -1
  248. package/src/icons/Cross.torp +3 -1
  249. package/src/icons/IconTypes.ts +6 -0
  250. package/src/icons/Loading.torp +3 -1
  251. package/src/icons/Minus.torp +3 -1
  252. package/src/icons/Plus.torp +3 -1
  253. package/src/motion/fade.ts +15 -6
  254. package/src/motion/grow.ts +23 -0
  255. package/src/motion/index.ts +4 -1
  256. package/src/motion/measure.ts +28 -0
  257. package/src/motion/slide.ts +45 -0
  258. package/src/mount/clickPopover.ts +51 -0
  259. package/src/mount/contextPopover.ts +51 -0
  260. package/src/mount/hoverPopover.ts +58 -0
  261. package/test/Accordion/components/AccordionAccessibility.torp +1 -3
  262. package/test/Accordion/components/AccordionKeyboard.torp +1 -3
  263. package/test/Accordion/components/AccordionList.torp +1 -3
  264. package/test/Accordion/components/AccordionMultiple.torp +2 -4
  265. package/test/Accordion/components/AccordionSingle.torp +2 -4
  266. package/test/Dialog/accessibility-modal.test.ts +2 -2
  267. package/test/Dialog/components/DialogAccessibility.torp +8 -14
  268. package/test/Dialog/components/DialogFunction.torp +20 -4
  269. package/test/Dialog/components/DialogModal.torp +30 -0
  270. package/test/Dialog/components/DialogVariable.torp +7 -7
  271. package/test/Disclosure/components/DisclosureTest.torp +1 -3
  272. package/test/Menu/components/MenuAccessibility.torp +5 -5
  273. package/test/Menu/components/MenuBasic.torp +5 -5
  274. package/test/Notification/components/NotificationFunction.torp +0 -3
  275. package/test/Notification/components/NotificationVariable.torp +1 -1
  276. package/test/Popover/components/PopoverFunction.torp +37 -0
  277. package/test/Popover/components/PopoverTrigger.torp +36 -0
  278. package/test/Popover/components/{PromptVariable.torp → PopoverVariable.torp} +5 -3
  279. package/test/Popover/function.test.ts +2 -7
  280. package/test/Popover/trigger.test.ts +27 -0
  281. package/test/Popover/variable.test.ts +2 -2
  282. package/test/TabGroup/components/TabGroupAccessibility.torp +1 -3
  283. package/test/TabGroup/components/TabGroupKeyboard.torp +1 -3
  284. package/test/TabGroup/components/TabGroupList.torp +1 -3
  285. package/test/TabGroup/components/TabGroupTrigger.torp +1 -3
  286. package/tsup.config.ts +2 -0
  287. package/dist/Popover/PopoverContentAnchored.torp +0 -113
  288. package/dist/Popover/PopoverOverlay.torp +0 -39
  289. package/dist/Popover/PopoverTriggerContextual.torp +0 -46
  290. package/dist/Popover/PopoverTriggerHover.torp +0 -47
  291. package/dist/Popover/mountClickPopover.ts +0 -50
  292. package/dist/Popover/mountContextPopover.ts +0 -50
  293. package/dist/Popover/mountHoverPopover.ts +0 -57
  294. package/dist/Popover/showPopoverPrompt.ts +0 -23
  295. package/src/Popover/PopoverContentAnchored.torp +0 -113
  296. package/src/Popover/PopoverOverlay.torp +0 -39
  297. package/src/Popover/PopoverTriggerContextual.torp +0 -46
  298. package/src/Popover/PopoverTriggerHover.torp +0 -47
  299. package/src/Popover/mountClickPopover.ts +0 -50
  300. package/src/Popover/mountContextPopover.ts +0 -50
  301. package/src/Popover/mountHoverPopover.ts +0 -57
  302. package/src/Popover/showPopoverPrompt.ts +0 -23
  303. package/test/Dialog/components/CustomDialog.torp +0 -20
  304. package/test/Popover/components/PromptFunction.torp +0 -19
@@ -1,3 +1,5 @@
1
+ import { ContextualContextName } from "../Contextual/ContextualTypes";
2
+ import { ModalContextName } from "../Modal/ModalTypes";
1
3
  import { PopoverContextName, type PopoverContext } from "../Popover/PopoverTypes";
2
4
  import {
3
5
  MenuContextName,
@@ -26,27 +28,26 @@ interface MenuProps {
26
28
  *
27
29
  * ```
28
30
  * <Menu>
29
- * <MenuButton />
30
- * <MenuSeparator /> (optional)
31
- * <MenuGroup> (optional)
32
- * <MenuButton />
33
- * </MenuGroup>
31
+ * <MenuButton />
32
+ * <MenuSeparator /> (optional)
33
+ * <MenuGroup> (optional)
34
+ * <MenuButton />
35
+ * </MenuGroup>
34
36
  * </Menu>
35
37
  * ```
36
38
  */
37
- export default function Menu($props: MenuProps) {
38
- $props ??= $watch({});
39
-
39
+ export default function Menu($props: MenuProps | undefined) {
40
40
  // A collection containing the state and some functions for each item
41
41
  let itemStates: ItemState[] = [];
42
42
  let focusIndex = -1;
43
43
 
44
44
  // Get stuff out of the PopoverContext
45
- const popoverContext = $context[PopoverContextName] as PopoverContext;
45
+ // HACK: share state in PopupState and extend in context/modal/popover
46
+ const popoverContext = $context[ContextualContextName] ?? $context[ModalContextName] ?? $context[PopoverContextName] as PopoverContext;
46
47
  if (!popoverContext) {
47
- throw new Error("Menu must be contained within a Contextual, Prompt or Popover");
48
+ throw new Error("Menu must be contained within a Context, Modal or Popover");
48
49
  }
49
- const { setVisible, handleButton, modal, visible } = popoverContext;
50
+ const { setVisible, handleButton, visible } = popoverContext;
50
51
 
51
52
  // Check whether this is a menu in a popout
52
53
  const popoutContext = $context[MenuPopoutContextName] as MenuPopoutContext;
@@ -77,7 +78,7 @@ export default function Menu($props: MenuProps) {
77
78
  }
78
79
 
79
80
  function registerItem(setFocused: () => void) {
80
- // Add the item"s state to the array and return its index
81
+ // Add the item's state to the array and return its index
81
82
  const newItemState: ItemState = {
82
83
  setFocused
83
84
  };
@@ -156,11 +157,11 @@ export default function Menu($props: MenuProps) {
156
157
 
157
158
  @render {
158
159
  <div
159
- {$props.id}
160
- class={`torp-menu ${$props.class ?? ""}`.trim()}
160
+ {$props?.id}
161
+ class={`torp-menu ${$props?.class ?? ""}`.trim()}
161
162
  tabindex="-1"
162
163
  role="menu"
163
- aria-label={$props.ariaLabel}
164
+ aria-label={$props?.ariaLabel}
164
165
  aria-orientation="vertical"
165
166
  >
166
167
  <slot />
@@ -9,15 +9,17 @@ interface MenuButtonProps {
9
9
  value?: any,
10
10
  /** Whether this button is disabled */
11
11
  disabled?: boolean,
12
+ /** Raised when the button is clicked */
13
+ onclick?: (e: MouseEvent) => void,
14
+ /** Raised when a key is pressed down */
15
+ onkeydown?: (e: KeyboardEvent) => void,
12
16
  }
13
17
 
14
18
  /**
15
19
  * A button that is placed in a Menu or MenuGroup and signals a response by a user.
16
20
  *
17
21
  */
18
- export default function MenuButton($props: MenuButtonProps) {
19
- $props ??= $watch({});
20
-
22
+ export default function MenuButton($props: MenuButtonProps | undefined) {
21
23
  let button: HTMLButtonElement;
22
24
 
23
25
  // Get stuff out of the MenuContext
@@ -30,14 +32,18 @@ export default function MenuButton($props: MenuButtonProps) {
30
32
  // Register this item with the parent Menu and store the index
31
33
  const { index } = registerItem(setFocused);
32
34
 
33
- function handleKeyDown(e) {
35
+ function handleKeyDown(e: KeyboardEvent) {
34
36
  handleItemKey(e);
35
- if ($props.onkeydown) $props.onkeydown(e);
37
+ if ($props?.onkeydown) {
38
+ $props.onkeydown(e);
39
+ }
36
40
  }
37
41
 
38
- function handleClick(e) {
39
- handleButton($props.value);
40
- if ($props.onclick) $props.onclick(e);
42
+ function handleClick(e: MouseEvent) {
43
+ handleButton($props?.value);
44
+ if ($props?.onclick) {
45
+ $props.onclick(e);
46
+ }
41
47
  }
42
48
 
43
49
  function setFocused() {
@@ -46,13 +52,13 @@ export default function MenuButton($props: MenuButtonProps) {
46
52
 
47
53
  @render {
48
54
  <button
49
- {$props.id}
50
- class={`torp-menu-button ${$props.class ?? ""}`.trim()}
55
+ {$props?.id}
56
+ class={`torp-menu-button ${$props?.class ?? ""}`.trim()}
51
57
  type="button"
52
- {$props.disabled}
58
+ {$props?.disabled}
53
59
  role="menuitem"
54
- aria-disabled={$props.disabled ? "true" : undefined}
55
- data-disabled={$props.disabled ? "true" : undefined}
60
+ aria-disabled={$props?.disabled ? "true" : undefined}
61
+ data-disabled={$props?.disabled ? "true" : undefined}
56
62
  onkeydown={handleKeyDown}
57
63
  onclick={handleClick}
58
64
  onfocus={() => handleItemFocus(index)}
@@ -14,6 +14,8 @@ interface MenuCheckProps {
14
14
  checked?: boolean,
15
15
  /** Whether this item is disabled */
16
16
  disabled?: boolean,
17
+ /** Raised when the checkbox is clicked */
18
+ onclick?: (e: MouseEvent) => void,
17
19
  }
18
20
 
19
21
  /**
@@ -21,15 +23,15 @@ interface MenuCheckProps {
21
23
  * option on or off.
22
24
  *
23
25
  */
24
- export default function MenuCheck($props: MenuCheckProps) {
25
- $props ??= $watch({});
26
-
26
+ export default function MenuCheck($props: MenuCheckProps | undefined) {
27
27
  let $state = $watch({
28
- checked: $props.checked
28
+ checked: $props?.checked ?? false
29
29
  });
30
30
 
31
31
  $run(() => {
32
- $props.checked = $state.checked;
32
+ if ($props !== undefined) {
33
+ $props.checked = $state.checked;
34
+ }
33
35
  });
34
36
 
35
37
  let button: HTMLButtonElement;
@@ -54,22 +56,24 @@ export default function MenuCheck($props: MenuCheckProps) {
54
56
  button.focus();
55
57
  }
56
58
 
57
- function handleClick() {
59
+ function handleClick(e: MouseEvent) {
58
60
  $state.checked = !$state.checked;
59
- if ($props.onclick) $props.onclick();
61
+ if ($props?.onclick) {
62
+ $props.onclick(e);
63
+ }
60
64
  }
61
65
 
62
66
  @render {
63
67
  <button
64
- {$props.id}
65
- class={`torp-menu-check ${$props.class ?? ""}`.trim()}
68
+ {$props?.id}
69
+ class={`torp-menu-check ${$props?.class ?? ""}`.trim()}
66
70
  type="button"
67
- {$props.disabled}
71
+ {$props?.disabled}
68
72
  role="menuitemcheckbox"
69
- aria-checked={$props.checked ? "true" : "false"}
70
- aria-disabled={$props.disabled ? "true" : undefined}
71
- data-state={$props.checked ? "checked" : "unchecked"}
72
- data-disabled={$props.disabled ? "true" : undefined}
73
+ aria-checked={$props?.checked ? "true" : "false"}
74
+ aria-disabled={$props?.disabled ? "true" : undefined}
75
+ data-state={$props?.checked ? "checked" : "unchecked"}
76
+ data-disabled={$props?.disabled ? "true" : undefined}
73
77
  onkeydown={handleItemKey}
74
78
  onclick={handleClick}
75
79
  onfocus={() => handleItemFocus(index)}
@@ -11,17 +11,15 @@ interface MenuGroupProps {
11
11
  /**
12
12
  * A container for a logical group of menu items.
13
13
  */
14
- export default function MenuGroup($props: MenuGroupProps) {
15
- $props ??= $watch({});
16
-
14
+ export default function MenuGroup($props: MenuGroupProps | undefined) {
17
15
  // TODO: Intercept the context to steal toggleItem??
18
16
 
19
17
  @render {
20
18
  <div
21
- {$props.id}
22
- class={`torp-menu-group ${$props.class ?? ""}`.trim()}
19
+ {$props?.id}
20
+ class={`torp-menu-group ${$props?.class ?? ""}`.trim()}
23
21
  role="group"
24
- aria-label={$props.ariaLabel}
22
+ aria-label={$props?.ariaLabel}
25
23
  >
26
24
  <slot />
27
25
  </div>
@@ -13,9 +13,7 @@ interface MenuIndicatorProps {
13
13
  * An indicator for a MenuCheck or MenuRadio component, which is displayed
14
14
  * when the value of checked is true.
15
15
  */
16
- export default function MenuIndicator($props: MenuIndicatorProps) {
17
- $props ??= $watch({});
18
-
16
+ export default function MenuIndicator($props: MenuIndicatorProps | undefined) {
19
17
  // Get stuff out of the MenuButtonContext
20
18
  const context = $context[MenuButtonContextName] as MenuButtonContext;
21
19
  if (!context) {
@@ -26,10 +24,10 @@ export default function MenuIndicator($props: MenuIndicatorProps) {
26
24
  @render {
27
25
  @if ($state.checked) {
28
26
  <div
29
- {$props.id}
30
- class={`torp-menu-indicator ${$props.class ?? ""}`.trim()}
31
- aria-disabled={$props.disabled ? "true" : undefined}
32
- data-disabled={$props.disabled ? "true" : undefined}
27
+ {$props?.id}
28
+ class={`torp-menu-indicator ${$props?.class ?? ""}`.trim()}
29
+ aria-disabled={$props?.disabled ? "true" : undefined}
30
+ data-disabled={$props?.disabled ? "true" : undefined}
33
31
  >
34
32
  <slot />
35
33
  </div>
@@ -7,12 +7,12 @@ interface MenuPopoutProps {
7
7
  class?: string,
8
8
  /** Whether the popout is visible */
9
9
  visible?: boolean,
10
- /** Called when the popout is opened or closed */
10
+ /** Raised when the popout is opened or closed */
11
11
  ontoggle?: (open: boolean) => void,
12
- /** Called when the popout has opened */
12
+ /** Raised when the popout has opened */
13
13
  onopen?: () => void,
14
- /** Called when the popout has closed */
15
- onclose?: () => void,
14
+ /** Raised when the popout has closed */
15
+ onclose?: (result: any) => void,
16
16
  }
17
17
 
18
18
  /**
@@ -22,17 +22,14 @@ interface MenuPopoutProps {
22
22
  *
23
23
  * ```
24
24
  * <MenuPopout>
25
- * <MenuPopoutTrigger /> (optional)
25
+ * <MenuPopoutTrigger /> (optional)
26
26
  * <MenuPopoutContent />
27
27
  * </MenuPopout>
28
28
  * ```
29
29
  */
30
- export default function MenuPopout($props: MenuPopoutProps) {
31
- $props ??= $watch({});
32
- $props.visible ??= false;
33
-
30
+ export default function MenuPopout($props: MenuPopoutProps | undefined) {
34
31
  let $state = $watch({
35
- visible: $props.visible
32
+ visible: $props?.visible ?? false
36
33
  });
37
34
 
38
35
  let result: any;
@@ -50,9 +47,9 @@ export default function MenuPopout($props: MenuPopoutProps) {
50
47
 
51
48
  let firstToggle = true;
52
49
  $run(() => {
53
- const ontoggle = $props.ontoggle;
54
- const onopen = $props.onopen;
55
- const onclose = $props.onclose;
50
+ const ontoggle = $props?.ontoggle;
51
+ const onopen = $props?.onopen;
52
+ const onclose = $props?.onclose;
56
53
  const visible = $state.visible;
57
54
  if (firstToggle) {
58
55
  firstToggle = false;
@@ -72,8 +69,8 @@ export default function MenuPopout($props: MenuPopoutProps) {
72
69
 
73
70
  @render {
74
71
  <div
75
- {$props.id}
76
- class={`torp-menu-popout ${$props.class ?? ""}`.trim()}
72
+ {$props?.id}
73
+ class={`torp-menu-popout ${$props?.class ?? ""}`.trim()}
77
74
  onmouseleave={handleMouseLeave}
78
75
  >
79
76
  <slot />
@@ -16,11 +16,7 @@ interface MenuPopoutContentProps {
16
16
  /**
17
17
  * The content that is displayed for a MenuPopout when it is open.
18
18
  */
19
- export default function MenuPopoutContent($props: MenuPopoutContentProps) {
20
- $props ??= $watch({});
21
- $props.side ??= "right";
22
- $props.alignment ??= "start";
23
-
19
+ export default function MenuPopoutContent($props: MenuPopoutContentProps | undefined) {
24
20
  let div: HTMLDivElement;
25
21
  let shown = false;
26
22
 
@@ -65,14 +61,16 @@ export default function MenuPopoutContent($props: MenuPopoutContentProps) {
65
61
  throw new Error("MenuPopoutContent must have an anchor element");
66
62
  }
67
63
 
68
- setPopoverPosition(popoutContext.anchorElement, div, $props.side, $props.alignment);
64
+ let side = $props?.side ?? "right";
65
+ let alignment = $props?.alignment ?? "start";
66
+ setPopoverPosition(popoutContext.anchorElement, div, side, alignment);
69
67
  }
70
68
 
71
69
  @render {
72
70
  @if ($state.visible) {
73
71
  <div
74
- {$props.id}
75
- class={`torp-menu-popout-content ${$props.class ?? ""}`.trim()}
72
+ {$props?.id}
73
+ class={`torp-menu-popout-content ${$props?.class ?? ""}`.trim()}
76
74
  &ref={div}
77
75
  onmount={show}
78
76
  >
@@ -19,10 +19,8 @@ interface MenuPopoutTriggerProps {
19
19
  /**
20
20
  * A button that is placed in a Menu or MenuGroup and signals a response by a user.
21
21
  */
22
- export default function MenuPopoutTrigger($props: MenuPopoutTriggerProps) {
23
- $props ??= $watch({});
24
- $props.hoverDelay ??= 500;
25
- $props.disabled ??= false;
22
+ export default function MenuPopoutTrigger($props: MenuPopoutTriggerProps | undefined) {
23
+ let defaultHoverDelay = 500;
26
24
 
27
25
  let button: HTMLButtonElement;
28
26
  let interval: NodeJS.Timeout | undefined;
@@ -72,16 +70,16 @@ export default function MenuPopoutTrigger($props: MenuPopoutTriggerProps) {
72
70
  }
73
71
 
74
72
  function handleMouseEnter() {
75
- if ($props.disabled) return;
73
+ if ($props?.disabled) return;
76
74
 
77
75
  // Handle the hover after a delay
78
76
  if (!interval) {
79
- interval = setTimeout(() => setVisible(true), $props.hoverDelay);
77
+ interval = setTimeout(() => setVisible(true), $props?.hoverDelay ?? defaultHoverDelay);
80
78
  }
81
79
  }
82
80
 
83
81
  function handleMouseLeave() {
84
- if ($props.disabled) return;
82
+ if ($props?.disabled) return;
85
83
 
86
84
  // Prevent short hovers or touches from firing the event
87
85
  if (interval) {
@@ -91,26 +89,26 @@ export default function MenuPopoutTrigger($props: MenuPopoutTriggerProps) {
91
89
  }
92
90
 
93
91
  function handleMouseMove() {
94
- if ($props.disabled) return;
92
+ if ($props?.disabled) return;
95
93
 
96
94
  // Reset the interval on mouse move
97
95
  if (interval) {
98
96
  clearTimeout(interval);
99
- interval = setTimeout(() => setVisible(true), $props.hoverDelay);
97
+ interval = setTimeout(() => setVisible(true), $props?.hoverDelay ?? defaultHoverDelay);
100
98
  }
101
99
  }
102
100
 
103
101
  @render {
104
102
  <button
105
- {$props.id}
106
- class={`torp-menu-popout-trigger ${$props.class ?? ""}`.trim()}
103
+ {$props?.id}
104
+ class={`torp-menu-popout-trigger ${$props?.class ?? ""}`.trim()}
107
105
  type="button"
108
- {$props.disabled}
106
+ {$props?.disabled}
109
107
  role="menuitem"
110
108
  aria-haspopup="true"
111
109
  aria-expanded={($state.visible ?? false).toString()}
112
- aria-disabled={$props.disabled ? "true" : undefined}
113
- data-disabled={$props.disabled ? "true" : undefined}
110
+ aria-disabled={$props?.disabled ? "true" : undefined}
111
+ data-disabled={$props?.disabled ? "true" : undefined}
114
112
  onkeydown={handlePopoutKey}
115
113
  onclick={handleClick}
116
114
  onfocus={() => handleItemFocus(index)}
@@ -24,15 +24,15 @@ interface MenuRadioProps {
24
24
  * A button that is placed in a Menu or MenuGroup to allow the user to select
25
25
  * from a number of options.
26
26
  */
27
- export default function MenuRadio($props: MenuRadioProps) {
28
- $props ??= $watch({});
29
-
27
+ export default function MenuRadio($props: MenuRadioProps | undefined) {
30
28
  let $state = $watch({
31
- checked: $props.checked,
29
+ checked: $props?.checked ?? false,
32
30
  });
33
31
 
34
32
  $run(() => {
35
- $props.checked = $state.checked;
33
+ if ($props !== undefined) {
34
+ $props.checked = $state.checked;
35
+ }
36
36
  });
37
37
 
38
38
  let button: HTMLButtonElement;
@@ -55,7 +55,7 @@ export default function MenuRadio($props: MenuRadioProps) {
55
55
  const { index } = registerItem(setFocused);
56
56
 
57
57
  // Register this item with the parent MenuRadioGroup
58
- registerItemInGroup($props.value, setChecked);
58
+ registerItemInGroup($props?.value ?? "", setChecked);
59
59
 
60
60
  // Set the context to pass down to items
61
61
  let context: MenuButtonContext = {
@@ -73,21 +73,21 @@ export default function MenuRadio($props: MenuRadioProps) {
73
73
 
74
74
  function handleClick() {
75
75
  if (!$state.checked) {
76
- toggleItem($props.value);
76
+ toggleItem($props?.value ?? "");
77
77
  }
78
78
  }
79
79
 
80
80
  @render {
81
81
  <button
82
- {$props.id}
83
- class={`torp-menu-radio ${$props.class ?? ""}`.trim()}
82
+ {$props?.id}
83
+ class={`torp-menu-radio ${$props?.class ?? ""}`.trim()}
84
84
  type="button"
85
- {$props.disabled}
85
+ {$props?.disabled}
86
86
  role="menuitemradio"
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}
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}
91
91
  onkeydown={handleItemKey}
92
92
  onclick={handleClick}
93
93
  onfocus={() => handleItemFocus(index)}
@@ -13,19 +13,27 @@ interface MenuRadioGroupProps {
13
13
  ariaLabel?: string,
14
14
  /** The value of the checked MenuRadio */
15
15
  value?: string | undefined,
16
- /** Called when the checked item has changed */
16
+ /** Raised when the checked item has changed */
17
17
  onchange?: (value: any) => void,
18
18
  }
19
19
 
20
20
  /**
21
21
  * A container for a logical group of menu RadioGroup items.
22
22
  */
23
- export default function MenuRadioGroup($props: MenuRadioGroupProps) {
24
- $props ??= $watch({});
25
-
23
+ export default function MenuRadioGroup($props: MenuRadioGroupProps | undefined) {
26
24
  // A collection containing the state and some functions for each item
27
25
  let itemStates: RadioGroupItemState[] = [];
28
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
+
29
37
  // Set the context to pass down to items
30
38
  let context: MenuRadioGroupContext = {
31
39
  registerItemInGroup,
@@ -35,11 +43,11 @@ export default function MenuRadioGroup($props: MenuRadioGroupProps) {
35
43
 
36
44
  $mount(() => {
37
45
  // Set the initial checked item
38
- setValue($props.value);
46
+ setValue($props?.value);
39
47
  });
40
48
 
41
49
  function registerItemInGroup(itemValue: string, setChecked: (value: boolean) => void) {
42
- // Add the item"s state to the array
50
+ // Add the item's state to the array
43
51
  const newItemState: RadioGroupItemState = {
44
52
  value: itemValue,
45
53
  checked: false,
@@ -63,11 +71,11 @@ export default function MenuRadioGroup($props: MenuRadioGroupProps) {
63
71
  }
64
72
 
65
73
  // Set the value
66
- if ($props.value !== newValue) {
67
- $props.value = newValue;
74
+ if ($state.value !== newValue) {
75
+ $state.value = newValue;
68
76
 
69
- if ($props.onchange) {
70
- $props.onchange($props.value);
77
+ if ($props?.onchange) {
78
+ $props?.onchange($props?.value);
71
79
  }
72
80
  }
73
81
  }
@@ -81,15 +89,15 @@ export default function MenuRadioGroup($props: MenuRadioGroupProps) {
81
89
  newValue = item.value;
82
90
  }
83
91
  }
84
- $props.value = newValue;
92
+ $state.value = newValue;
85
93
  }
86
94
 
87
95
  @render {
88
96
  <div
89
- {$props.id}
90
- class={`torp-menu-radio-group ${$props.class ?? ""}`.trim()}
97
+ {$props?.id}
98
+ class={`torp-menu-radio-group ${$props?.class ?? ""}`.trim()}
91
99
  role="group"
92
- aria-label={$props.ariaLabel}
100
+ aria-label={$props?.ariaLabel}
93
101
  >
94
102
  <slot />
95
103
  </div>
@@ -9,13 +9,11 @@ interface MenuSeparatorProps {
9
9
  /**
10
10
  * An element in a menu that separates logical sets of menu items.
11
11
  */
12
- export default function MenuSeparator($props: MenuSeparatorProps) {
13
- $props ??= $watch({});
14
-
12
+ export default function MenuSeparator($props: MenuSeparatorProps | undefined) {
15
13
  @render {
16
14
  <div
17
- {$props.id}
18
- class={`torp-menu-separator ${$props.class ?? ""}`.trim()}
15
+ {$props?.id}
16
+ class={`torp-menu-separator ${$props?.class ?? ""}`.trim()}
19
17
  role="separator"
20
18
  >
21
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;
@@ -20,18 +20,17 @@ interface MenuBarProps {
20
20
  *
21
21
  * ```
22
22
  * <MenuBar>
23
- * <MenuBarItem>
24
- * <MenuBarItemTrigger />
25
- * <MenuBarItemContent>
26
- * <Menu />
27
- * </MenuBarItemContent>
28
- * </MenuBarItem>
23
+ * <MenuBarItem>
24
+ * <MenuBarItemTrigger />
25
+ * <MenuBarItemContent>
26
+ * <Menu />
27
+ * </MenuBarItemContent>
28
+ * </MenuBarItem>
29
29
  * </MenuBar>
30
30
  * ```
31
31
  */
32
- export default function MenuBar($props: MenuBarProps) {
33
- $props ??= $watch({});
34
- $props.orientation ??= "horizontal";
32
+ export default function MenuBar($props: MenuBarProps | undefined) {
33
+ let orientation = $props?.orientation ?? "horizontal";
35
34
 
36
35
  let $state = $watch({
37
36
  active: false,
@@ -52,7 +51,7 @@ export default function MenuBar($props: MenuBarProps) {
52
51
  $context[MenuBarContextName] = context;
53
52
 
54
53
  function registerItem(setVisible: (value: boolean) => void, setFocused: () => void) {
55
- // 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
56
55
  const newItemState: ItemState = {
57
56
  setVisible,
58
57
  setFocused
@@ -146,12 +145,12 @@ export default function MenuBar($props: MenuBarProps) {
146
145
 
147
146
  @render {
148
147
  <div
149
- {$props.id}
150
- class={`torp-menu-bar ${$props.class ?? ""}`.trim()}
148
+ {$props?.id}
149
+ class={`torp-menu-bar ${$props?.class ?? ""}`.trim()}
151
150
  tabindex="-1"
152
151
  role="menubar"
153
- aria-label={$props.ariaLabel}
154
- aria-orientation={$props.orientation}
152
+ aria-label={$props?.ariaLabel}
153
+ aria-orientation={orientation}
155
154
  >
156
155
  <slot />
157
156
  </div>