@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
@@ -1,11 +1,24 @@
1
1
  import getId from "../utils/getId";
2
- import { addDocumentEvent, removeDocumentEvent } from "../utils/documentEvents";
3
2
  import { trapFocus, type TrapFocusOptions } from "../mount/trapFocus";
4
- import { PopoverContextName, type PopoverContext } from "../Popover/PopoverTypes";
5
- import { DialogContextName, type DialogContext, type DialogState } from "./DialogTypes";
3
+ import { ModalContextName, type ModalContext } from "../Modal/ModalTypes";
4
+ import { PopoverContextName } from "../Popover/PopoverTypes";
5
+ import { DialogContextName, type DialogContext, type DialogState, type HandleButtonPress } from "./DialogTypes";
6
+
7
+ interface DialogProps {
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 popover to screen readers */
13
+ ariaLabel?: string,
14
+ /** Whether the dialog should alert the user via the screen reader */
15
+ alert?: boolean,
16
+ }
6
17
 
7
18
  /**
8
- * Content for a window displayed in a Popover.
19
+ * A dialog that can be used to show a message to the user, or get information from the user.
20
+ *
21
+ * Dialogs are typically shown within a Modal or Popover.
9
22
  *
10
23
  * See [the WAI ARIA guidelines for Dialogs](https://www.w3.org/WAI/ARIA/apg/patterns/dialogmodal/).
11
24
  *
@@ -13,43 +26,44 @@ import { DialogContextName, type DialogContext, type DialogState } from "./Dialo
13
26
  *
14
27
  * ```
15
28
  * <Dialog>
16
- * <DialogHeader /> (optional)
17
- * <DialogBody /> (optional)
18
- * <DialogFooter> (optional)
19
- * <DialogButton /> (optional)
20
- * </DialogFooter>
29
+ * <ModalOverlay /> (optional -- will set `modal` to true)
30
+ * <DialogHeader /> (optional)
31
+ * <DialogBody /> (optional)
32
+ * <DialogFooter> (optional)
33
+ * <DialogButton /> (optional)
34
+ * </DialogFooter>
21
35
  * </Dialog>
22
36
  * ```
23
37
  *
24
- * @prop {string | undefined} ariaLabel -- An ARIA label for describing the popover to screen readers
25
- * @prop {boolean} alert -- Whether the dialog should alert the user via the screen reader
26
38
  */
27
- export default function Dialog($props: any) {
28
- $props.id ??= getId();
29
- $props.dialog ??= false;
39
+ export default function Dialog($props: DialogProps | undefined) {
40
+ let defaultId = getId();
30
41
 
31
- let div: HTMLDivElement;
42
+ //let div: HTMLDivElement;
32
43
 
33
44
  let trapFocusOptions: TrapFocusOptions = {
34
45
  focusableElements: []
35
46
  };
36
47
 
37
- // Get stuff out of the PopoverContext
38
- const popoverContext = $context[PopoverContextName] as PopoverContext;
39
- if (!popoverContext) {
40
- throw new Error("Dialog must be contained within a Popover");
41
- }
42
- const { handleButton, modal } = popoverContext;
43
- const visible = popoverContext.state.visible;
48
+ // Maybe get stuff out of a Modal context
49
+ let modal = false;
50
+ let visible = true;
51
+ let handleButton: HandleButtonPress | undefined = undefined;
52
+ const modalContext = $context[ModalContextName] ?? $context[PopoverContextName] as ModalContext;
53
+ if (modalContext) {
54
+ modal = true;
55
+ visible = modalContext.state.visible;
56
+ handleButton = modalContext.handleButton;
44
57
 
45
- popoverContext.handleClickOutside = handleClickOutside;
46
- // Set the focusFirstElement method in the PopoverContext so that it can be
47
- // called after everything has been shown
48
- popoverContext.focusFirstElement = focusFirstElement;
58
+ modalContext.handleClickOutside = handleClickOutside;
59
+ // Set the focusFirstElement method in the ModalContext so that it can be
60
+ // called after everything has been shown
61
+ modalContext.focusFirstElement = focusFirstElement;
62
+ }
49
63
 
50
64
  // Set the IDs for using in the Dialog's ARIA attributes
51
65
  let $state: DialogState = $watch({
52
- dialogId: $props.id,
66
+ dialogId: $props?.id ?? defaultId,
53
67
  headerId: "",
54
68
  bodyId: "",
55
69
  visible
@@ -59,60 +73,22 @@ export default function Dialog($props: any) {
59
73
  let context: DialogContext = {
60
74
  handleButton,
61
75
  state: $state,
62
- anchorElement: popoverContext.anchorElement
76
+ anchorElement: modalContext ? modalContext.anchorElement : undefined
63
77
  };
64
78
  $context[DialogContextName] = context;
65
79
 
66
- let closeOnClick = false;
67
-
68
- $mount(() => {
69
- if ($state.visible) {
70
- // HACK: Because this Dialog could be shown with a click, we need to
71
- // wait for another mousedown before we close on click. Otherwise
72
- // the click immediately bubbles to the document. I guess we could
73
- // require the user to preventDefault after calling showPrompt etc,
74
- // but that seems very error-prone?
75
- closeOnClick = false;
76
- addDocumentEvent("mousedown", handleDocumentMouseDown);
77
- addDocumentEvent("click", handleDocumentClick);
78
- } else {
79
- removeDocumentEvent("mousedown", handleDocumentMouseDown);
80
- removeDocumentEvent("click", handleDocumentClick);
81
- // Focus the anchor element per WAI guidelines
82
- if (context.anchorElement?.focus) {
83
- context.anchorElement.focus();
84
- }
85
- }
86
- });
87
-
88
80
  function focusFirstElement() {
89
81
  if (trapFocusOptions.focusableElements.length) {
90
82
  trapFocusOptions.focusableElements[0].focus();
91
83
  }
92
84
  }
93
85
 
94
- function handleDocumentMouseDown() {
95
- closeOnClick = true;
96
- }
97
-
98
- function handleDocumentClick(e: MouseEvent) {
99
- if (
100
- closeOnClick &&
101
- div &&
102
- !div.contains(e.target as HTMLElement) &&
103
- (!context.anchorElement || !context.anchorElement.contains(e.target as HTMLElement))
104
- ) {
105
- handleClickOutside(e);
106
- }
107
- }
108
-
109
86
  function handleClickOutside(e: MouseEvent) {
110
87
  // Don't allow the user to click outside -- they must press a button or
111
88
  // the Esc key
112
89
  e.preventDefault();
113
90
  if (!modal) {
114
- popoverContext.state.visible = false;
115
- context.state.visible = false;
91
+ modalContext.state.visible = false;
116
92
  }
117
93
  }
118
94
 
@@ -138,17 +114,17 @@ export default function Dialog($props: any) {
138
114
 
139
115
  @render {
140
116
  <div
141
- {$props.id}
142
- class={`torp-dialog ${$props.class ?? ""}`.trim()}
117
+ id={$props?.id ?? defaultId}
118
+ class={`torp-dialog ${$props?.class ?? ""}`.trim()}
143
119
  tabindex="0"
144
- role={$props.alert ? "alertdialog" : "dialog"}
120
+ role={$props?.alert === true ? "alertdialog" : "dialog"}
145
121
  aria-modal={modal}
146
- aria-label={$props.ariaLabel}
147
- aria-labelledby={!$props.ariaLabel && $state.headerId ? $state.headerId : undefined}
122
+ aria-label={$props?.ariaLabel}
123
+ aria-labelledby={!$props?.ariaLabel && $state.headerId ? $state.headerId : undefined}
148
124
  aria-describedby={$state.bodyId ? $state.bodyId : undefined}
149
125
  onkeydown={handleKey}
150
126
  onmount={(el) => trapFocus(el, trapFocusOptions)}
151
- &ref={div}
127
+ @//&ref={div}
152
128
  >
153
129
  <slot />
154
130
  </div>
@@ -1,15 +1,21 @@
1
1
  import getId from "../utils/getId";
2
2
  import { DialogContextName, type DialogContext } from "./DialogTypes";
3
3
 
4
+ interface DialogBodyProps {
5
+ /** An ID for the root element */
6
+ id?: string;
7
+ /** Class name(s) for the root element */
8
+ class?: string,
9
+ /** Whether the body content will be announced by screen readers when the Dialog is opened */
10
+ ariaAnnounce?: boolean,
11
+ }
12
+
4
13
  /**
5
14
  * The body information for a Dialog. Content in the body will be announced by
6
15
  * screen readers when the Dialog is opened, unless ariaAnnounce is false.
7
- *
8
- * @prop {boolean} ariaAnnounce -- Whether the body content will be announced by screen readers when the Dialog is opened
9
16
  */
10
- export default function DialogBody($props: any) {
11
- $props.id ??= getId();
12
- $props.ariaAnnounce ??= true;
17
+ export default function DialogBody($props: DialogBodyProps | undefined) {
18
+ let defaultId = getId();
13
19
 
14
20
  // Get stuff out of the DialogContext
15
21
  const context = $context[DialogContextName] as DialogContext;
@@ -19,14 +25,14 @@ export default function DialogBody($props: any) {
19
25
  let $state = context.state;
20
26
 
21
27
  // Set the body id for using in the Dialog's ARIA attributes
22
- if ($props.ariaAnnounce) {
23
- $state.bodyId = $props.id;
28
+ if ($props?.ariaAnnounce !== false) {
29
+ $state.bodyId = $props?.id || defaultId;
24
30
  }
25
31
 
26
32
  @render {
27
33
  <div
28
- {$props.id}
29
- class={`torp-dialog-body ${$props.class ?? ""}`.trim()}
34
+ id={$props?.id ?? defaultId}
35
+ class={`torp-dialog-body ${$props?.class ?? ""}`.trim()}
30
36
  >
31
37
  <slot />
32
38
  </div>
@@ -1,13 +1,25 @@
1
1
  import { DialogContextName, type DialogContext } from "./DialogTypes";
2
2
 
3
+ interface DialogButtonProps {
4
+ /** An ID for the root element */
5
+ id?: string;
6
+ /** Class name(s) for the root element */
7
+ class?: string,
8
+ /** The value that should be returned when this button is pressed and the Dialog was invoked by calling showContextual, showPrompt or showPopover */
9
+ value?: any,
10
+ /** "confirm" if the button should respond to the Enter key or "cancel" if the button should respond to the Escape key */
11
+ type?: "confirm" | "cancel",
12
+ /** Whether this button is disabled */
13
+ disabled?: boolean,
14
+ /** Raised when the button is clicked */
15
+ onclick?: (e: MouseEvent) => void,
16
+ }
17
+
3
18
  /**
4
19
  * A button that is placed in a DialogFooter and signals a response by a user.
5
20
  *
6
- * @prop {any | undefined} value -- The value that should be returned when this button is pressed and the Dialog was invoked by calling showContextual, showPrompt or showPopover
7
- * @prop {"confirm" | "cancel" | undefined} type -- "confirm" if the button should respond to the Enter key or "cancel" if the button should respond to the Escape key
8
- * @prop {boolean} disabled -- Whether this button is disabled
9
21
  */
10
- export default function DialogButton($props: any) {
22
+ export default function DialogButton($props: DialogButtonProps | undefined) {
11
23
  let button: HTMLButtonElement;
12
24
 
13
25
  // Get stuff out of the DialogContext
@@ -19,26 +31,28 @@ export default function DialogButton($props: any) {
19
31
 
20
32
  $mount(() => {
21
33
  // Store the confirm or cancel button in the DialogContext
22
- if ($props.type === "confirm") {
34
+ if ($props?.type === "confirm") {
23
35
  context.confirmButton = button;
24
- } else if ($props.type === "cancel") {
36
+ } else if ($props?.type === "cancel") {
25
37
  context.cancelButton = button;
26
38
  }
27
39
  });
28
40
 
29
- function handleClick(e) {
30
- if ($props.onclick) {
31
- $props.onclick(e)
41
+ function handleClick(e: MouseEvent) {
42
+ if ($props?.onclick) {
43
+ $props?.onclick(e)
44
+ }
45
+ if (handleButton) {
46
+ handleButton($props?.type, $props?.value);
32
47
  }
33
- handleButton($props.type, $props.value);
34
48
  }
35
49
 
36
50
  @render {
37
51
  <button
38
52
  type="button"
39
- {$props.id}
40
- class={`torp-dialog-button ${$props.class ?? ""}`.trim()}
41
- disabled={$props.disabled}
53
+ {$props?.id}
54
+ class={`torp-dialog-button ${$props?.class ?? ""}`.trim()}
55
+ disabled={$props?.disabled}
42
56
  onclick={handleClick}
43
57
  &ref={button}
44
58
  >
@@ -1,11 +1,19 @@
1
+
2
+ interface DialogFooterProps {
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
  * The footer for a Dialog, which may contain one or more DialogButtons.
3
11
  */
4
- export default function DialogFooter($props: any) {
12
+ export default function DialogFooter($props: DialogFooterProps | undefined) {
5
13
  @render {
6
14
  <div
7
- {$props.id}
8
- class={`torp-dialog-footer ${$props.class ?? ""}`.trim()}
15
+ {$props?.id}
16
+ class={`torp-dialog-footer ${$props?.class ?? ""}`.trim()}
9
17
  >
10
18
  <slot />
11
19
  </div>
@@ -1,15 +1,22 @@
1
1
  import getId from "../utils/getId";
2
2
  import { DialogContextName, type DialogContext } from "./DialogTypes";
3
3
 
4
+ interface DialogHeaderProps {
5
+ /** An ID for the root element */
6
+ id?: string;
7
+ /** Class name(s) for the root element */
8
+ class?: string,
9
+ /** Whether the header will be announced by screen readers when the Dialog is opened */
10
+ ariaAnnounce?: boolean,
11
+ }
12
+
4
13
  /**
5
14
  * The header for a Dialog. Content in the header will be announced by screen
6
15
  * readers when the Dialog is opened, unless ariaAnnounce is false.
7
16
  *
8
- * @prop {boolean} ariaAnnounce -- Whether the header will be announced by screen readers when the Dialog is opened
9
17
  */
10
- export default function DialogHeader($props: any) {
11
- $props.id ??= getId();
12
- $props.ariaAnnounce ??= true;
18
+ export default function DialogHeader($props: DialogHeaderProps | undefined) {
19
+ let defaultId = getId();
13
20
 
14
21
  // Get stuff out of the DialogContext
15
22
  const context = $context[DialogContextName] as DialogContext;
@@ -19,14 +26,14 @@ export default function DialogHeader($props: any) {
19
26
  let $state = context.state;
20
27
 
21
28
  // Set the header id for using in the Dialog's ARIA attributes
22
- if ($props.ariaAnnounce) {
23
- $state.headerId = $props.id;
29
+ if ($props?.ariaAnnounce !== false) {
30
+ $state.headerId = $props?.id ?? defaultId;
24
31
  }
25
32
 
26
33
  @render {
27
34
  <div
28
- {$props.id}
29
- class={`torp-dialog-footer ${$props.class ?? ""}`.trim()}
35
+ id={$props?.id ?? defaultId}
36
+ class={`torp-dialog-footer ${$props?.class ?? ""}`.trim()}
30
37
  >
31
38
  <slot />
32
39
  </div>
@@ -1,7 +1,9 @@
1
1
  export const DialogContextName = "Dialog";
2
2
 
3
+ export type HandleButtonPress = (type: "confirm" | "cancel" | undefined, value?: any) => void;
4
+
3
5
  export interface DialogContext {
4
- handleButton: (type: "confirm" | "cancel" | undefined, value?: any) => void;
6
+ handleButton?: HandleButtonPress;
5
7
  state: DialogState;
6
8
  anchorElement?: HTMLElement;
7
9
  confirmButton?: HTMLButtonElement;
@@ -12,5 +14,4 @@ export interface DialogState {
12
14
  dialogId: string;
13
15
  headerId: string;
14
16
  bodyId: string;
15
- visible: boolean;
16
17
  }
@@ -1,4 +1,17 @@
1
- import { DisclosureContextName, type DisclosureContext } from "./DisclosureTypes";
1
+ import { DisclosureContextName, type DisclosureContext, type DisclosureState } from "./DisclosureTypes";
2
+
3
+ interface DisclosureProps {
4
+ /** An ID for the root element */
5
+ id?: string;
6
+ /** Class name(s) for the root element */
7
+ class?: string,
8
+ /** Whether the disclosure is expanded and its content visible */
9
+ expanded?: boolean,
10
+ /** If set to true, the user cannot interact with this disclosure */
11
+ disabled?: boolean,
12
+ /** Raised when the disclosure is opened or closed */
13
+ ontoggle?: (open: boolean) => void,
14
+ }
2
15
 
3
16
  /**
4
17
  * An interactive header that enables users to reveal or hide an associated section of content.
@@ -9,33 +22,29 @@ import { DisclosureContextName, type DisclosureContext } from "./DisclosureTypes
9
22
  *
10
23
  * ```
11
24
  * <Disclosure>
12
- * <DisclosureHeader>
13
- * <DisclosureTrigger />
14
- * </DisclosureHeader>
15
- * <DisclosureContent />
25
+ * <DisclosureHeader>
26
+ * <DisclosureTrigger />
27
+ * </DisclosureHeader>
28
+ * <DisclosureContent />
16
29
  * </Disclosure>
17
30
  * ```
18
- *
19
- * @prop {boolean} [expanded] -- Whether the Disclosure is expanded and its content visible
20
- * @prop {boolean} [disabled] -- If set to true, the user cannot interact with this Disclosure
21
- * @prop {(boolean) => void} [ontoggle] -- Raised when this item is opened or closed
22
31
  */
23
- export default function Disclosure($props: any) {
24
- $props.expanded ??= false;
25
- $props.disabled ??= false;
26
-
32
+ export default function Disclosure($props: DisclosureProps | undefined) {
27
33
  let $state: DisclosureState = $watch({
28
- expanded: $props.expanded && $props.expanded !== "false",
29
- disabled: $props.disabled,
30
- get dataState() {
31
- return this.expanded ? "open" : "closed";
32
- },
34
+ expanded: false,
35
+ disabled: false,
36
+ headerId: "",
37
+ contentId: "",
33
38
  });
34
39
 
35
40
  // Update $state with $props
36
41
  $run(() => {
37
- $state.expanded = $props.expanded && $props.expanded !== "false";
38
- $state.disabled = $props.disabled;
42
+ $state.expanded = $props?.expanded === true ||
43
+ // @ts-ignore
44
+ $props?.expanded === "true";
45
+ $state.disabled = $props?.disabled === true ||
46
+ // @ts-ignore
47
+ $props?.disabled === "true";
39
48
  });
40
49
 
41
50
  // Put stuff into a DisclosureContext
@@ -47,7 +56,7 @@ export default function Disclosure($props: any) {
47
56
  // Dispatch the toggle event when the value of expanded changes
48
57
  let firstToggle = true;
49
58
  $run(() => {
50
- const ev = $props.ontoggle;
59
+ const ev = $props?.ontoggle;
51
60
  const expanded = $state.expanded;
52
61
  if (firstToggle) {
53
62
  firstToggle = false;
@@ -58,10 +67,10 @@ export default function Disclosure($props: any) {
58
67
 
59
68
  @render {
60
69
  <div
61
- {$props.id}
62
- class={`torp-disclosure-item ${$props.class ?? ""}`.trim()}
63
- data-state={$state.dataState}
64
- data-disabled={$state.dataDisabled}
70
+ {$props?.id}
71
+ class={`torp-disclosure-item ${$props?.class ?? ""}`.trim()}
72
+ data-state={$state.expanded ? "open" : "closed"}
73
+ data-disabled={$state.disabled ? "true" : undefined}
65
74
  >
66
75
  <slot />
67
76
  </div>
@@ -1,32 +1,38 @@
1
1
  import getId from "../utils/getId";
2
2
  import { DisclosureContextName, type DisclosureContext } from "./DisclosureTypes";
3
3
 
4
+ interface DisclosureContentProps {
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 Disclosure */
10
+ ariaRegion?: boolean,
11
+ }
12
+
4
13
  /**
5
14
  * Content for a Disclosure, which can be revealed or hidden by an associated DisclosureTrigger.
6
- *
7
- * @prop {string} [id] -- An ID for the DisclosureContent'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 Disclosure
9
15
  */
10
- export default function DisclosureContent($props: any) {
11
- $props.id ||= getId();
16
+ export default function DisclosureContent($props: DisclosureContentProps | undefined) {
17
+ let defaultId = getId();
12
18
 
13
19
  const context = $context[DisclosureContextName] as DisclosureContext;
14
20
  if (!context) {
15
21
  throw new Error("DisclosureContent must be contained within a Disclosure");
16
22
  }
17
- let $state = $context[DisclosureContextName].state
23
+ let $state = context.state
18
24
 
19
25
  // Set the content ID so that it can be used with aria-controls in DisclosureTrigger
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-disclosure-content ${$props.class ?? ""}`.trim()}
26
- role={$props.ariaRegion ? "region" : undefined}
30
+ id={$props?.id ?? defaultId}
31
+ class={`torp-disclosure-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 { DisclosureContextName, type DisclosureContext } from "./DisclosureTypes";
2
2
 
3
+ interface DisclosureHeaderProps {
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 a Disclosure, which contains the DisclosureTrigger.
5
14
  *
@@ -7,26 +16,24 @@ import { DisclosureContextName, type DisclosureContext } from "./DisclosureTypes
7
16
  *
8
17
  * ```
9
18
  * <DisclosureHeader>
10
- * <DisclosureTrigger />
19
+ * <DisclosureTrigger />
11
20
  * </DisclosureHeader>
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 DisclosureHeader($props: any) {
23
+ export default function DisclosureHeader($props: DisclosureHeaderProps | undefined) {
17
24
  const context = $context[DisclosureContextName] as DisclosureContext;
18
25
  if (!context) {
19
26
  throw new Error("DisclosureHeader must be contained within a Disclosure");
20
27
  }
21
- let $state = $context[DisclosureContextName].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-disclosure-header ${$props.class ?? ""}`.trim()}
28
- data-state={$state.dataState}
29
- data-disabled={$state.dataDisabled}
33
+ {$props?.id}
34
+ class={`torp-disclosure-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,32 +1,39 @@
1
1
  import getId from "../utils/getId";
2
2
  import { DisclosureContextName, type DisclosureContext } from "./DisclosureTypes";
3
3
 
4
+ interface DisclosureTriggerProps {
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 a Disclosure, which can be used to reveal or hide an associated DisclosureContent.
6
13
  */
7
- export default function DisclosureTrigger() {
8
- $props.id ||= getId();
14
+ export default function DisclosureTrigger($props: DisclosureTriggerProps | undefined) {
15
+ let defaultId = getId();
9
16
 
10
17
  // Get stuff out of the DisclosureContext
11
18
  const context = $context[DisclosureContextName] as DisclosureContext;
12
19
  if (!context) {
13
20
  throw new Error("DisclosureTrigger must be contained within a Disclosure");
14
21
  }
15
- let $state = $context[DisclosureContextName].state;
22
+ let $state = context.state;
16
23
 
17
24
  // Set the header ID so that it can be used with aria-labelledby in DisclosureContent
18
- $state.headerId = $props.id;
25
+ $state.headerId = $props?.id ?? defaultId;
19
26
 
20
27
  @render {
21
28
  <button
22
29
  type="button"
23
- {$props.id}
24
- class={`torp-disclosure-trigger ${$props.class ?? ""}`.trim()}
25
- disabled={$state.disabled || $state.parentDisabled}
30
+ id={$props?.id ?? defaultId}
31
+ class={`torp-disclosure-trigger ${$props?.class ?? ""}`.trim()}
32
+ disabled={$state.disabled}
26
33
  aria-expanded={$state.expanded.toString()}
27
34
  aria-disabled={$state.disabled}
28
35
  aria-controls={$state.contentId}
29
- data-state={$state.dataState}
36
+ data-state={$state.expanded ? "open" : "closed"}
30
37
  data-disabled={$state.disabled}
31
38
  onclick={() => $state.expanded = !$state.expanded}
32
39
  >
@@ -10,5 +10,4 @@ export interface DisclosureState {
10
10
  contentId: string;
11
11
  expanded: boolean;
12
12
  disabled: boolean;
13
- dataState: "open" | "closed";
14
13
  }