@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
@@ -18,10 +18,7 @@ interface NavMenuLinkProps {
18
18
  * A link that is placed in a NavMenu and signals a response by a user.
19
19
  *
20
20
  */
21
- export default function NavMenuLink($props: NavMenuLinkProps) {
22
- $props ??= $watch({ href: "#" });
23
- $props.newWindow ??= false;
24
-
21
+ export default function NavMenuLink($props: NavMenuLinkProps | undefined) {
25
22
  let link: HTMLAnchorElement;
26
23
 
27
24
  // Get stuff out of the NavMenuContext
@@ -40,14 +37,14 @@ export default function NavMenuLink($props: NavMenuLinkProps) {
40
37
 
41
38
  @render {
42
39
  <a
43
- {$props.id}
44
- class={`torp-nav-menu-link ${$props.class ?? ""}`.trim()}
45
- href={$props.href}
46
- {$props.disabled}
47
- target={$props.newWindow ? "_blank" : undefined}
40
+ {$props?.id}
41
+ class={`torp-nav-menu-link ${$props?.class ?? ""}`.trim()}
42
+ {$props?.href}
43
+ {$props?.disabled}
44
+ target={$props?.newWindow ? "_blank" : undefined}
48
45
  role="menuitem"
49
- aria-disabled={$props.disabled ? "true" : undefined}
50
- data-disabled={$props.disabled ? "true" : undefined}
46
+ aria-disabled={$props?.disabled ? "true" : undefined}
47
+ data-disabled={$props?.disabled ? "true" : undefined}
51
48
  onkeydown
52
49
  onkeydown={handleItemKey}
53
50
  onclick
@@ -7,6 +7,12 @@ interface NavMenuPopoutProps {
7
7
  class?: string,
8
8
  /** Whether the popout is visible */
9
9
  visible?: boolean,
10
+ /** Raised when the popout is opened or closed */
11
+ ontoggle?: (open: boolean) => void,
12
+ /** Raised when the popout has opened */
13
+ onopen?: () => void,
14
+ /** Raised when the popout has closed */
15
+ onclose?: (result: any) => void,
10
16
  }
11
17
 
12
18
  /**
@@ -16,17 +22,24 @@ interface NavMenuPopoutProps {
16
22
  *
17
23
  * ```
18
24
  * <NavMenuPopout>
19
- * <NavMenuPopoutButton />
25
+ * <NavMenuPopoutButton />
20
26
  * <NavMenuPopoutContent />
21
27
  * </NavMenuPopout>
22
28
  * ```
23
29
  */
24
- export default function NavMenuPopout($props: NavMenuPopoutProps) {
25
- $props ??= $watch({});
26
- $props.visible ??= false;
27
-
30
+ export default function NavMenuPopout($props: NavMenuPopoutProps | undefined) {
28
31
  let $state = $watch({
29
- visible: $props.visible
32
+ visible: false
33
+ });
34
+
35
+ // Sync props and state
36
+ $run(() => {
37
+ $state.visible = $props?.visible ?? false;
38
+ });
39
+ $run(() => {
40
+ if ($props !== undefined) {
41
+ $props.visible = $state.visible;
42
+ }
30
43
  });
31
44
 
32
45
  let result: any;
@@ -37,18 +50,13 @@ export default function NavMenuPopout($props: NavMenuPopoutProps) {
37
50
  };
38
51
  $context[NavMenuPopoutContextName] = context;
39
52
 
40
- // Copy props into state whenever they change
41
- $run(() => {
42
- $state.visible = $props.visible ?? false;
43
- });
44
-
45
53
  // Dispatch the toggle event when the popout is opened or closed
46
54
  let firstToggle = true;
47
55
  $run(() => {
48
- const ontoggle = $props.ontoggle;
49
- const onopen = $props.onopen;
50
- const onclose = $props.onclose;
51
- const visible = $props.visible;
56
+ const ontoggle = $props?.ontoggle;
57
+ const onopen = $props?.onopen;
58
+ const onclose = $props?.onclose;
59
+ const visible = $state.visible;
52
60
  if (firstToggle) {
53
61
  firstToggle = false;
54
62
  } else {
@@ -67,8 +75,8 @@ export default function NavMenuPopout($props: NavMenuPopoutProps) {
67
75
 
68
76
  @render {
69
77
  <div
70
- {$props.id}
71
- class={`torp-nav-menu-popout ${$props.class ?? ""}`.trim()}
78
+ {$props?.id}
79
+ class={`torp-nav-menu-popout ${$props?.class ?? ""}`.trim()}
72
80
  onmouseleave={handleMouseLeave}
73
81
  >
74
82
  <slot />
@@ -20,9 +20,8 @@ interface NavMenuPopoutButtonProps {
20
20
  * A button that is placed in a NavMenu and signals a response by a user.
21
21
  *
22
22
  */
23
- export default function NavMenuPopoutButton($props: NavMenuPopoutButtonProps) {
24
- $props ??= $watch({});
25
- $props.hoverDelay ??= 500;
23
+ export default function NavMenuPopoutButton($props: NavMenuPopoutButtonProps | undefined) {
24
+ let defaultHoverDelay = 500;
26
25
 
27
26
  let button: HTMLButtonElement;
28
27
  let interval: NodeJS.Timeout | undefined;
@@ -72,16 +71,16 @@ export default function NavMenuPopoutButton($props: NavMenuPopoutButtonProps) {
72
71
  }
73
72
 
74
73
  function handleMouseEnter() {
75
- if ($props.disabled) return;
74
+ if ($props?.disabled) return;
76
75
 
77
76
  // Handle the hover after a delay
78
77
  if (!interval) {
79
- interval = setTimeout(() => $state.visible = true, $props.hoverDelay);
78
+ interval = setTimeout(() => $state.visible = true, $props?.hoverDelay ?? defaultHoverDelay);
80
79
  }
81
80
  }
82
81
 
83
82
  function handleMouseLeave() {
84
- if ($props.disabled) return;
83
+ if ($props?.disabled) return;
85
84
 
86
85
  // Prevent short hovers or touches from firing the event
87
86
  if (interval) {
@@ -91,26 +90,26 @@ export default function NavMenuPopoutButton($props: NavMenuPopoutButtonProps) {
91
90
  }
92
91
 
93
92
  function handleMouseMove() {
94
- if ($props.disabled) return;
93
+ if ($props?.disabled) return;
95
94
 
96
95
  // Reset the interval on mouse move
97
96
  if (interval) {
98
97
  clearTimeout(interval);
99
- interval = setTimeout(() => $state.visible = true, $props.hoverDelay);
98
+ interval = setTimeout(() => $state.visible = true, $props?.hoverDelay ?? defaultHoverDelay);
100
99
  }
101
100
  }
102
101
 
103
102
  @render {
104
103
  <button
105
- {$props.id}
106
- class={`torp-nav-menu-popout-button ${$props.class ?? ""}`.trim()}
104
+ {$props?.id}
105
+ class={`torp-nav-menu-popout-button ${$props?.class ?? ""}`.trim()}
107
106
  type="button"
108
- {$props.disabled}
107
+ {$props?.disabled}
109
108
  role="menuitem"
110
109
  aria-haspopup="true"
111
110
  aria-expanded={$state.visible.toString()}
112
- aria-disabled={$props.disabled ? "true" : undefined}
113
- data-disabled={$state.disabled ? "true" : undefined}
111
+ aria-disabled={$props?.disabled ? "true" : undefined}
112
+ data-disabled={$props?.disabled ? "true" : undefined}
114
113
  onkeydown={handlePopoutKey}
115
114
  onclick={handleClick}
116
115
  onfocus={() => handleItemFocus(index)}
@@ -18,11 +18,7 @@ interface NavMenuPopoutContentProps {
18
18
  * The content that is displayed for a NavMenuPopout when it is open.
19
19
  *
20
20
  */
21
- export default function NavMenuPopoutContent($props: NavMenuPopoutContentProps) {
22
- $props ??= $watch({});
23
- $props.side ??= "bottom";
24
- $props.alignment ??= "start";
25
-
21
+ export default function NavMenuPopoutContent($props: NavMenuPopoutContentProps | undefined) {
26
22
  let div: HTMLDivElement;
27
23
  let shown = false;
28
24
 
@@ -44,7 +40,8 @@ export default function NavMenuPopoutContent($props: NavMenuPopoutContentProps)
44
40
 
45
41
  // Set the position and listen for window resize and scroll to reset the position
46
42
  setPosition();
47
- const scrollParent = getScrollParent(context.anchorElement)
43
+ const anchorElement = context.anchorElement!
44
+ const scrollParent = getScrollParent(anchorElement)
48
45
  scrollParent.addEventListener("resize", setPosition);
49
46
  scrollParent.addEventListener("scroll", setPosition);
50
47
  if (context.focusFirstElement) {
@@ -56,11 +53,12 @@ export default function NavMenuPopoutContent($props: NavMenuPopoutContentProps)
56
53
  if (!shown) return;
57
54
 
58
55
  // Stop listening for window resize and focus the anchor element per WAI guidelines
59
- const scrollParent = getScrollParent(context.anchorElement)
56
+ const anchorElement = context.anchorElement!
57
+ const scrollParent = getScrollParent(anchorElement)
60
58
  scrollParent.removeEventListener("resize", setPosition);
61
59
  scrollParent.removeEventListener("scroll", setPosition);
62
- if (context.anchorElement?.focus) {
63
- context.anchorElement.focus();
60
+ if (anchorElement.focus) {
61
+ anchorElement.focus();
64
62
  }
65
63
  }
66
64
 
@@ -70,15 +68,17 @@ export default function NavMenuPopoutContent($props: NavMenuPopoutContentProps)
70
68
  }
71
69
 
72
70
  if (div) {
73
- setPopoverPosition(context.anchorElement, div, $props.side, $props.alignment);
71
+ let side = $props?.side ?? "bottom";
72
+ let alignment = $props?.alignment ?? "start";
73
+ setPopoverPosition(context.anchorElement, div, side, alignment);
74
74
  }
75
75
  }
76
76
 
77
77
  @render {
78
78
  @if ($state.visible) {
79
79
  <div
80
- {$props.id}
81
- class={`torp-nav-menu-popout-content ${$props.class ?? ""}`.trim()}
80
+ {$props?.id}
81
+ class={`torp-nav-menu-popout-content ${$props?.class ?? ""}`.trim()}
82
82
  &ref={div}
83
83
  onmount={show}
84
84
  >
@@ -9,13 +9,11 @@ interface NavMenuSeparatorProps {
9
9
  /**
10
10
  * An element in a menu that separates logical sets of menu items.
11
11
  */
12
- export default function NavMenuSeparator($props: NavMenuSeparatorProps) {
13
- $props ??= $watch({});
14
-
12
+ export default function NavMenuSeparator($props: NavMenuSeparatorProps | undefined) {
15
13
  @render {
16
14
  <div
17
- {$props.id}
18
- class={`torp-nav-menu-separator ${$props.class ?? ""}`.trim()} role="separator"
15
+ {$props?.id}
16
+ class={`torp-nav-menu-separator ${$props?.class ?? ""}`.trim()} role="separator"
19
17
  >
20
18
  <slot />
21
19
  </div>
@@ -19,10 +19,21 @@ interface NotificationProps {
19
19
  *
20
20
  * See [the WAI ARIA guidelines for Alerts](https://www.w3.org/WAI/ARIA/apg/patterns/alert/).
21
21
  */
22
- export default function Notification($props: NotificationProps) {
23
- $props ??= $watch({});
24
- $props.visible ??= true;
25
- $props.duration ??= 5000;
22
+ export default function Notification($props: NotificationProps | undefined) {
23
+ let defaultDuration = 5000;
24
+
25
+ let $state = $watch({
26
+ visible: false
27
+ });
28
+
29
+ $run(() => {
30
+ $state.visible = $props?.visible ?? true;
31
+ });
32
+ $run(() => {
33
+ if ($props !== undefined) {
34
+ $props.visible = $state.visible;
35
+ }
36
+ });
26
37
 
27
38
  // Set the context to pass down to items
28
39
  let context: NotificationContext = {
@@ -31,24 +42,22 @@ export default function Notification($props: NotificationProps) {
31
42
  $context[NotificationContextName] = context;
32
43
 
33
44
  $mount(() => {
34
- if ($props.duration) {
35
- setTimeout(closeNotification, $props.duration);
36
- }
45
+ setTimeout(closeNotification, $props?.duration ?? defaultDuration);
37
46
  });
38
47
 
39
48
  function closeNotification() {
40
- $props.visible = false;
49
+ $state.visible = false;
41
50
 
42
- if ($props.onclose) {
43
- $props.onclose();
51
+ if ($props?.onclose) {
52
+ $props?.onclose();
44
53
  }
45
54
  }
46
55
 
47
56
  @render {
48
- @if ($props.visible) {
57
+ @if ($state.visible) {
49
58
  <div
50
- {$props.id}
51
- class={`torp-notification ${$props.class ?? ""}`.trim()}
59
+ {$props?.id}
60
+ class={`torp-notification ${$props?.class ?? ""}`.trim()}
52
61
  role="alert"
53
62
  >
54
63
  <slot />
@@ -10,9 +10,7 @@ interface NotificationCloseProps {
10
10
  /**
11
11
  * The button that a user can press to close this Notification.
12
12
  */
13
- export default function NotificationClose($props: NotificationCloseProps) {
14
- $props ??= $watch({});
15
-
13
+ export default function NotificationClose($props: NotificationCloseProps | undefined) {
16
14
  // Get stuff out of the NotificationContext
17
15
  const context = $context[NotificationContextName] as NotificationContext;
18
16
  if (!context) {
@@ -26,8 +24,8 @@ export default function NotificationClose($props: NotificationCloseProps) {
26
24
 
27
25
  @render {
28
26
  <button
29
- {$props.id}
30
- class={`torp-notification-close ${$props.class ?? ""}`.trim()}
27
+ {$props?.id}
28
+ class={`torp-notification-close ${$props?.class ?? ""}`.trim()}
31
29
  type="button"
32
30
  onclick={handleClick}
33
31
  >
@@ -10,13 +10,11 @@ interface NotificationContainerProps {
10
10
  * The container for one or more Notifications, which can be used to position
11
11
  * the notifications inside the viewport.
12
12
  */
13
- export default function NotificationContainer($props: NotificationContainerProps) {
14
- $props ??= $watch({});
15
-
13
+ export default function NotificationContainer($props: NotificationContainerProps | undefined) {
16
14
  @render {
17
15
  <div
18
- {$props.id}
19
- class={`torp-notification-container ${$props.class ?? ""}`.trim()}
16
+ {$props?.id}
17
+ class={`torp-notification-container ${$props?.class ?? ""}`.trim()}
20
18
  >
21
19
  <slot />
22
20
  </div>
@@ -9,13 +9,11 @@ interface NotificationContentProps {
9
9
  /**
10
10
  * The content to display within a Notification.
11
11
  */
12
- export default function NotificationContent($props: NotificationContentProps) {
13
- $props ??= $watch({});
14
-
12
+ export default function NotificationContent($props: NotificationContentProps | undefined) {
15
13
  @render {
16
14
  <div
17
- {$props.id}
18
- class={`torp-notification-content ${$props.class ?? ""}`.trim()}
15
+ {$props?.id}
16
+ class={`torp-notification-content ${$props?.class ?? ""}`.trim()}
19
17
  >
20
18
  <slot />
21
19
  </div>
@@ -15,31 +15,43 @@ interface PopoverProps {
15
15
  position?: Point,
16
16
  /** A function to be called when the user selects a response */
17
17
  callback?: ((value: any) => void),
18
+ /** Raised when the popover is opened or closed */
19
+ ontoggle?: (open: boolean) => void,
20
+ /** Raised when the popover has opened */
21
+ onopen?: () => void,
22
+ /** Raised when the popover has closed */
23
+ onclose?: (result: any) => void,
18
24
  }
19
25
 
20
26
  /**
21
- * A popover that can be used to show rich content or obtain information from a user.
22
- *
23
- * See [the WAI ARIA guidelines for Dialogs](https://www.w3.org/WAI/ARIA/apg/patterns/dialogmodal/).
27
+ * A popover window that is shown to the user relative to an anchor element.
24
28
  *
25
29
  * The structure of a Popover is:
26
30
  *
27
31
  * ```
28
32
  * <Popover>
29
- * <PopoverOverlay /> (optional, if modal)
30
- * <PopoverTrigger/PopoverTriggerContextual/PopoverTriggerHover /> (optional)
31
- * <PopoverContent/PopoverContentAnchored/PopoverContentContextual />
33
+ * <PopoverTrigger /> (optional)
34
+ * <PopoverContent />
32
35
  * </Popover>
33
36
  * ```
34
37
  */
35
- export default function Popover($props: PopoverProps) {
36
- $props ??= $watch({});
37
-
38
+ export default function Popover($props: PopoverProps | undefined) {
38
39
  let $state: PopoverState = $watch({
39
40
  visible: false,
40
41
  position: { x: 0, y: 0 }
41
42
  })
42
43
 
44
+ // Sync props and state
45
+ $run(() => {
46
+ $state.visible = $props?.visible ?? false;
47
+ $state.position = $props?.position ?? { x: 0, y: 0 };
48
+ });
49
+ $run(() => {
50
+ if ($props !== undefined) {
51
+ $props.visible = $state.visible;
52
+ }
53
+ });
54
+
43
55
  let result: any;
44
56
 
45
57
  // Set the context to pass down to items
@@ -47,23 +59,17 @@ export default function Popover($props: PopoverProps) {
47
59
  handleButton,
48
60
  handleClickOutside,
49
61
  state: $state,
50
- modal: $props.modal,
51
- anchorElement: $unwrap($props.anchor),
62
+ modal: $props?.modal,
63
+ anchorElement: $props?.anchor ? $unwrap($props.anchor) : undefined,
52
64
  };
53
65
  $context[PopoverContextName] = context;
54
66
 
55
- // Copy props into state whenever they change
56
- $run(() => {
57
- $state.visible = $props.visible ?? false;
58
- $state.position = $props.position ?? { x: 0, y: 0 };
59
- })
60
-
61
- // Dispatch the toggle event when the popout is opened or closed
67
+ // Dispatch the toggle event when the popover is opened or closed
62
68
  let firstToggle = true;
63
69
  $run(() => {
64
- const ontoggle = $props.ontoggle;
65
- const onopen = $props.onopen;
66
- const onclose = $props.onclose;
70
+ const ontoggle = $props?.ontoggle;
71
+ const onopen = $props?.onopen;
72
+ const onclose = $props?.onclose;
67
73
  const visible = $state.visible;
68
74
  if (firstToggle) {
69
75
  firstToggle = false;
@@ -98,8 +104,8 @@ export default function Popover($props: PopoverProps) {
98
104
  $state.visible = false;
99
105
 
100
106
  // Call the callback
101
- if ($props.callback) {
102
- $props.callback(result);
107
+ if ($props?.callback) {
108
+ $props?.callback(result);
103
109
  }
104
110
  }
105
111
 
@@ -110,8 +116,8 @@ export default function Popover($props: PopoverProps) {
110
116
 
111
117
  @render {
112
118
  <div
113
- {$props.id}
114
- class={`torp-popover ${$props.class ?? ""}`.trim()}
119
+ {$props?.id}
120
+ class={`torp-popover ${$props?.class ?? ""}`.trim()}
115
121
  >
116
122
  <slot />
117
123
  </div>
@@ -1,4 +1,6 @@
1
1
  import { addDocumentEvent, removeDocumentEvent } from "../utils/documentEvents";
2
+ import getScrollParent from "../utils/getScrollParent";
3
+ import setPopoverPosition from "../utils/setPopoverPosition";
2
4
  import { PopoverContextName, type PopoverContext } from "./PopoverTypes";
3
5
 
4
6
  interface PopoverContentProps {
@@ -6,15 +8,17 @@ interface PopoverContentProps {
6
8
  id?: string;
7
9
  /** Class name(s) for the root element */
8
10
  class?: string,
11
+ /** Where the popover will be shown, relative to the popover trigger */
12
+ side?: "top" | "right" | "bottom" | "left",
13
+ /** How the popover will be aligned, relative to the popover trigger */
14
+ alignment?: "start" | "center" | "end",
9
15
  }
10
16
 
11
17
  /**
12
- * The content that is displayed for a Popover when it is open, such as a Dialog
13
- * in the middle of the screen or a div that slides in from the side.
18
+ * The content that is displayed for a Popover when it is open, displayed
19
+ * alongside an element.
14
20
  */
15
- export default function PopoverContent($props: PopoverContentProps) {
16
- $props ??= $watch({});
17
-
21
+ export default function PopoverContent($props?: PopoverContentProps | undefined) {
18
22
  let div: HTMLDivElement;
19
23
  let shown = false;
20
24
  let closeOnClick = false;
@@ -41,6 +45,12 @@ export default function PopoverContent($props: PopoverContentProps) {
41
45
  addDocumentEvent("mousedown", handleDocumentMouseDown);
42
46
  addDocumentEvent("click", handleDocumentClick);
43
47
 
48
+ // Set the position and listen for window resize and scroll to reset the position
49
+ setPosition();
50
+ const anchorElement = context.anchorElement!
51
+ const scrollParent = getScrollParent(anchorElement)
52
+ scrollParent.addEventListener("resize", setPosition);
53
+ scrollParent.addEventListener("scroll", setPosition);
44
54
  if (context.focusFirstElement) {
45
55
  context.focusFirstElement();
46
56
  }
@@ -52,9 +62,13 @@ export default function PopoverContent($props: PopoverContentProps) {
52
62
  removeDocumentEvent("mousedown", handleDocumentMouseDown);
53
63
  removeDocumentEvent("click", handleDocumentClick);
54
64
 
55
- // Focus the anchor element per WAI guidelines
56
- if (context.anchorElement?.focus) {
57
- context.anchorElement.focus();
65
+ // Stop listening for window resize and focus the anchor element per WAI guidelines
66
+ const anchorElement = context.anchorElement!
67
+ const scrollParent = getScrollParent(anchorElement)
68
+ scrollParent.removeEventListener("resize", setPosition);
69
+ scrollParent.removeEventListener("scroll", setPosition);
70
+ if (anchorElement.focus) {
71
+ anchorElement.focus();
58
72
  }
59
73
  }
60
74
 
@@ -69,15 +83,26 @@ export default function PopoverContent($props: PopoverContentProps) {
69
83
  !div.contains(e.target as HTMLElement) &&
70
84
  (!context.anchorElement || !context.anchorElement.contains(e.target as HTMLElement))
71
85
  ) {
86
+ e.preventDefault();
72
87
  context.handleClickOutside!(e);
73
88
  }
74
89
  }
75
90
 
91
+ function setPosition() {
92
+ if (!context.anchorElement) {
93
+ throw new Error("Popover must have an anchor element");
94
+ }
95
+
96
+ let side = $props?.side ?? "bottom";
97
+ let alignment = $props?.alignment ?? "center";
98
+ setPopoverPosition(context.anchorElement, div, side, alignment);
99
+ }
100
+
76
101
  @render {
77
102
  @if ($state.visible) {
78
103
  <div
79
- {$props.id}
80
- class={`torp-popover-content ${$props.class ?? ""}`.trim()}
104
+ {$props?.id}
105
+ class={`torp-popover-content ${$props?.class ?? ""}`.trim()}
81
106
  &ref={div}
82
107
  onmount={show}
83
108
  >
@@ -1,17 +1,20 @@
1
1
  import { PopoverContextName, type PopoverContext } from "./PopoverTypes";
2
+ import hoverTrigger from "../mount/hoverTrigger";
2
3
 
3
4
  interface PopoverTriggerProps {
4
5
  /** An ID for the root element */
5
6
  id?: string;
6
7
  /** Class name(s) for the root element */
7
8
  class?: string,
9
+ /** Whether the popover is activated by click/press or by hover **/
10
+ activation?: "press" | "hover"
8
11
  }
9
12
 
10
13
  /**
11
14
  * The button that causes a Popover to appear or disappear.
12
15
  */
13
- export default function PopoverTrigger($props: PopoverTriggerProps) {
14
- $props ??= $watch({});
16
+ export default function PopoverTrigger($props: PopoverTriggerProps | undefined) {
17
+ let activation = $props?.activation ?? "press";
15
18
 
16
19
  // Get stuff out of the PopoverContext
17
20
  const context = $context[PopoverContextName] as PopoverContext;
@@ -21,15 +24,32 @@ export default function PopoverTrigger($props: PopoverTriggerProps) {
21
24
  let $state = context.state;
22
25
 
23
26
  function handleClick() {
27
+ if (activation !== "press") return;
28
+
24
29
  $state.visible = !$state.visible;
25
30
  }
26
31
 
32
+ function handleHover(node: HTMLElement, e: MouseEvent) {
33
+ if (activation !== "hover") return;
34
+
35
+ if ($state.position) {
36
+ // Get the position relative to the element, so we can reposition on scroll
37
+ const rect = node.getBoundingClientRect();
38
+ const x = e.clientX - rect.left;
39
+ const y = e.clientY - rect.top;
40
+ $state.position = { x, y };
41
+ //$state.position = { x: window.scrollX + e.clientX, y: window.scrollY + e.clientY };
42
+ }
43
+ $state.visible = !$state.visible
44
+ }
45
+
27
46
  @render {
28
47
  <button
29
48
  type="button"
30
- {$props.id}
31
- class={`torp-popover-trigger ${$props.class ?? ""}`.trim()}
49
+ {$props?.id}
50
+ class={`torp-popover-trigger ${$props?.class ?? ""}`.trim()}
32
51
  onclick={handleClick}
52
+ onmount={(el) => hoverTrigger(el, { onHover: handleHover, onExit: handleHover })}
33
53
  &ref={context.anchorElement}
34
54
  >
35
55
  <slot />
@@ -7,7 +7,7 @@ export interface PopoverContext {
7
7
  // There may be a more elegant way to accomplish this too
8
8
  handleClickOutside?: (e: MouseEvent) => void;
9
9
  state: PopoverState;
10
- modal: boolean;
10
+ //modal: boolean;
11
11
  anchorElement?: HTMLElement;
12
12
  // HACK: focusFirstElement is necessary because if we focus the first element e.g. in a Dialog's
13
13
  // onMount, it will scroll the page to the focused element and mess up our careful positioning
@@ -1,29 +1,6 @@
1
1
  import Popover from "./Popover.torp";
2
2
  import PopoverContent from "./PopoverContent.torp";
3
- import PopoverContentAnchored from "./PopoverContentAnchored.torp";
4
- import PopoverContentContextual from "./PopoverContentContextual.torp";
5
- import PopoverOverlay from "./PopoverOverlay.torp";
6
3
  import PopoverTrigger from "./PopoverTrigger.torp";
7
- import PopoverTriggerContextual from "./PopoverTriggerContextual.torp";
8
- import PopoverTriggerHover from "./PopoverTriggerHover.torp";
9
- import clickPopover from "./mountClickPopover";
10
- import contextPopover from "./mountContextPopover";
11
- import hoverPopover from "./mountHoverPopover";
12
4
  import showPopover from "./showPopover";
13
- import showPopoverPrompt from "./showPopoverPrompt";
14
5
 
15
- export {
16
- Popover,
17
- PopoverOverlay,
18
- PopoverTrigger,
19
- PopoverTriggerHover,
20
- PopoverTriggerContextual,
21
- PopoverContentAnchored,
22
- PopoverContentContextual,
23
- PopoverContent,
24
- showPopover,
25
- showPopoverPrompt,
26
- clickPopover,
27
- contextPopover,
28
- hoverPopover,
29
- };
6
+ export { Popover, PopoverTrigger, PopoverContent, showPopover };