@torpor/ui 0.1.6 → 0.2.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 (278) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/dist/Accordion/Accordion.torp +2 -2
  3. package/dist/Accordion/AccordionContent.torp +2 -2
  4. package/dist/Accordion/AccordionHeader.torp +2 -2
  5. package/dist/Accordion/AccordionItem.torp +2 -2
  6. package/dist/Accordion/AccordionTrigger.torp +2 -2
  7. package/dist/Accordion/index.d.ts +92 -0
  8. package/dist/Breadcrumb/Breadcrumb.torp +33 -0
  9. package/dist/Breadcrumb/BreadcrumbItem.torp +19 -0
  10. package/dist/Breadcrumb/BreadcrumbSeparator.torp +16 -0
  11. package/dist/Breadcrumb/index.d.ts +56 -0
  12. package/dist/Breadcrumb/index.js +14 -0
  13. package/dist/Calendar/Calendar.torp +265 -0
  14. package/dist/Calendar/CalendarDay.torp +67 -0
  15. package/dist/Calendar/CalendarTypes.ts +22 -0
  16. package/dist/Calendar/index.d.ts +38 -0
  17. package/dist/Calendar/index.js +10 -0
  18. package/dist/Calendar/index.js.map +1 -0
  19. package/dist/Dialog/Dialog.torp +3 -3
  20. package/dist/Dialog/DialogBody.torp +2 -2
  21. package/dist/Dialog/DialogButton.torp +2 -2
  22. package/dist/Dialog/DialogFooter.torp +2 -2
  23. package/dist/Dialog/DialogHeader.torp +2 -2
  24. package/dist/Dialog/index.d.ts +92 -0
  25. package/dist/Disclosure/Disclosure.torp +69 -0
  26. package/dist/Disclosure/DisclosureContent.torp +36 -0
  27. package/dist/Disclosure/DisclosureHeader.torp +34 -0
  28. package/dist/Disclosure/DisclosureTrigger.torp +36 -0
  29. package/dist/Disclosure/DisclosureTypes.ts +14 -0
  30. package/dist/Disclosure/index.d.ts +74 -0
  31. package/dist/Disclosure/index.js +18 -0
  32. package/dist/Disclosure/index.js.map +1 -0
  33. package/{src/Offscreen/Offscreen.torp → dist/Drawer/Drawer.torp} +10 -19
  34. package/dist/Drawer/index.d.ts +20 -0
  35. package/dist/Drawer/index.js +6 -0
  36. package/dist/Drawer/index.js.map +1 -0
  37. package/dist/Menu/Menu.torp +160 -0
  38. package/dist/Menu/MenuButton.torp +53 -0
  39. package/dist/Menu/MenuCheck.torp +70 -0
  40. package/dist/Menu/MenuGroup.torp +19 -0
  41. package/dist/Menu/MenuIndicator.torp +29 -0
  42. package/dist/Menu/MenuPopout.torp +71 -0
  43. package/dist/Menu/MenuPopoutContent.torp +74 -0
  44. package/dist/Menu/MenuPopoutTrigger.torp +117 -0
  45. package/dist/Menu/MenuRadio.torp +88 -0
  46. package/dist/Menu/MenuRadioGroup.torp +86 -0
  47. package/dist/Menu/MenuSeparator.torp +14 -0
  48. package/dist/Menu/MenuTypes.ts +58 -0
  49. package/dist/Menu/index.d.ts +200 -0
  50. package/dist/Menu/index.js +46 -0
  51. package/dist/Menu/index.js.map +1 -0
  52. package/dist/MenuBar/MenuBar.torp +150 -0
  53. package/dist/MenuBar/MenuBarItem.torp +104 -0
  54. package/dist/MenuBar/MenuBarItemContent.torp +108 -0
  55. package/dist/MenuBar/MenuBarItemTrigger.torp +89 -0
  56. package/dist/MenuBar/MenuBarTypes.ts +36 -0
  57. package/dist/MenuBar/index.d.ts +74 -0
  58. package/dist/MenuBar/index.js +18 -0
  59. package/dist/MenuBar/index.js.map +1 -0
  60. package/dist/NavMenu/NavMenu.torp +2 -2
  61. package/dist/NavMenu/NavMenuButton.torp +2 -2
  62. package/dist/NavMenu/NavMenuElement.torp +2 -2
  63. package/dist/NavMenu/NavMenuGroup.torp +2 -2
  64. package/dist/NavMenu/NavMenuGroupHeader.torp +2 -2
  65. package/dist/NavMenu/NavMenuLink.torp +2 -2
  66. package/dist/NavMenu/NavMenuPopout.torp +2 -2
  67. package/dist/NavMenu/NavMenuPopoutButton.torp +3 -3
  68. package/dist/NavMenu/NavMenuPopoutContent.torp +29 -27
  69. package/dist/NavMenu/NavMenuSeparator.torp +2 -2
  70. package/dist/NavMenu/index.d.ts +182 -0
  71. package/dist/Notification/Notification.torp +48 -0
  72. package/dist/Notification/NotificationClose.torp +28 -0
  73. package/dist/Notification/NotificationContainer.torp +14 -0
  74. package/dist/Notification/NotificationContent.torp +13 -0
  75. package/dist/Notification/NotificationTypes.ts +5 -0
  76. package/dist/Notification/index.d.ts +74 -0
  77. package/dist/Notification/index.js +36 -0
  78. package/dist/Notification/index.js.map +1 -0
  79. package/dist/Notification/showNotification.ts +30 -0
  80. package/dist/Popover/Popover.torp +2 -2
  81. package/dist/Popover/PopoverContent.torp +31 -28
  82. package/dist/Popover/PopoverContentAnchored.torp +39 -38
  83. package/dist/Popover/PopoverContentContextual.torp +39 -36
  84. package/dist/Popover/PopoverOverlay.torp +3 -3
  85. package/dist/Popover/PopoverTrigger.torp +2 -2
  86. package/dist/Popover/PopoverTriggerContextual.torp +2 -2
  87. package/dist/Popover/PopoverTriggerHover.torp +3 -3
  88. package/dist/Popover/index.d.ts +146 -0
  89. package/dist/TabGroup/TabContent.torp +2 -2
  90. package/dist/TabGroup/TabGroup.torp +2 -2
  91. package/dist/TabGroup/TabHeader.torp +3 -3
  92. package/dist/TabGroup/TabList.torp +2 -2
  93. package/dist/TabGroup/TabTrigger.torp +2 -2
  94. package/dist/TabGroup/index.d.ts +92 -0
  95. package/dist/icons/ArrowDown.torp +15 -0
  96. package/dist/icons/ArrowLeft.torp +15 -0
  97. package/dist/icons/ArrowRight.torp +15 -0
  98. package/dist/icons/ArrowUp.torp +15 -0
  99. package/dist/icons/Bars.torp +17 -0
  100. package/dist/icons/Check.torp +15 -0
  101. package/dist/icons/ChevronDown.torp +15 -0
  102. package/dist/icons/ChevronLeft.torp +15 -0
  103. package/dist/icons/ChevronRight.torp +15 -0
  104. package/dist/icons/ChevronUp.torp +15 -0
  105. package/dist/icons/Cross.torp +16 -0
  106. package/dist/icons/Loading.torp +16 -0
  107. package/dist/icons/Minus.torp +15 -0
  108. package/dist/icons/Plus.torp +16 -0
  109. package/dist/icons/index.d.ts +254 -0
  110. package/dist/icons/index.js +58 -0
  111. package/dist/icons/index.js.map +1 -0
  112. package/dist/{motion.d.cts → index.d.ts} +2 -2
  113. package/dist/metafile-esm.json +1 -1
  114. package/dist/motion/fade.ts +7 -0
  115. package/dist/motion/index.d.ts +2 -0
  116. package/dist/{motion.js → motion/index.js} +1 -1
  117. package/dist/motion/index.js.map +1 -0
  118. package/dist/mount/index.d.ts +2 -0
  119. package/dist/utils/dateUtils.ts +244 -0
  120. package/dist/utils/index.d.ts +2 -0
  121. package/dist/utils/setPopoverPosition.ts +4 -0
  122. package/package.json +51 -35
  123. package/scripts/postbuild.ts +42 -5
  124. package/src/Accordion/Accordion.torp +2 -2
  125. package/src/Accordion/AccordionContent.torp +2 -2
  126. package/src/Accordion/AccordionHeader.torp +2 -2
  127. package/src/Accordion/AccordionItem.torp +2 -2
  128. package/src/Accordion/AccordionTrigger.torp +2 -2
  129. package/src/Breadcrumb/Breadcrumb.torp +33 -0
  130. package/src/Breadcrumb/BreadcrumbItem.torp +19 -0
  131. package/src/Breadcrumb/BreadcrumbSeparator.torp +16 -0
  132. package/src/Breadcrumb/index.ts +5 -0
  133. package/src/Calendar/Calendar.torp +265 -0
  134. package/src/Calendar/CalendarDay.torp +67 -0
  135. package/src/Calendar/CalendarTypes.ts +22 -0
  136. package/src/Calendar/index.ts +4 -0
  137. package/src/Dialog/Dialog.torp +3 -3
  138. package/src/Dialog/DialogBody.torp +2 -2
  139. package/src/Dialog/DialogButton.torp +2 -2
  140. package/src/Dialog/DialogFooter.torp +2 -2
  141. package/src/Dialog/DialogHeader.torp +2 -2
  142. package/src/Disclosure/Disclosure.torp +69 -0
  143. package/src/Disclosure/DisclosureContent.torp +36 -0
  144. package/src/Disclosure/DisclosureHeader.torp +34 -0
  145. package/src/Disclosure/DisclosureTrigger.torp +36 -0
  146. package/src/Disclosure/DisclosureTypes.ts +14 -0
  147. package/src/Disclosure/index.ts +6 -0
  148. package/{dist/Offscreen/Offscreen.torp → src/Drawer/Drawer.torp} +10 -19
  149. package/src/Drawer/index.ts +3 -0
  150. package/src/Menu/Menu.torp +160 -0
  151. package/src/Menu/MenuButton.torp +53 -0
  152. package/src/Menu/MenuCheck.torp +70 -0
  153. package/src/Menu/MenuGroup.torp +19 -0
  154. package/src/Menu/MenuIndicator.torp +29 -0
  155. package/src/Menu/MenuPopout.torp +71 -0
  156. package/src/Menu/MenuPopoutContent.torp +74 -0
  157. package/src/Menu/MenuPopoutTrigger.torp +117 -0
  158. package/src/Menu/MenuRadio.torp +88 -0
  159. package/src/Menu/MenuRadioGroup.torp +86 -0
  160. package/src/Menu/MenuSeparator.torp +14 -0
  161. package/src/Menu/MenuTypes.ts +58 -0
  162. package/src/Menu/index.ts +25 -0
  163. package/src/MenuBar/MenuBar.torp +150 -0
  164. package/src/MenuBar/MenuBarItem.torp +104 -0
  165. package/src/MenuBar/MenuBarItemContent.torp +108 -0
  166. package/src/MenuBar/MenuBarItemTrigger.torp +89 -0
  167. package/src/MenuBar/MenuBarTypes.ts +36 -0
  168. package/src/MenuBar/index.ts +6 -0
  169. package/src/NavMenu/NavMenu.torp +2 -2
  170. package/src/NavMenu/NavMenuButton.torp +2 -2
  171. package/src/NavMenu/NavMenuElement.torp +2 -2
  172. package/src/NavMenu/NavMenuGroup.torp +2 -2
  173. package/src/NavMenu/NavMenuGroupHeader.torp +2 -2
  174. package/src/NavMenu/NavMenuLink.torp +2 -2
  175. package/src/NavMenu/NavMenuPopout.torp +2 -2
  176. package/src/NavMenu/NavMenuPopoutButton.torp +3 -3
  177. package/src/NavMenu/NavMenuPopoutContent.torp +29 -27
  178. package/src/NavMenu/NavMenuSeparator.torp +2 -2
  179. package/src/Notification/Notification.torp +48 -0
  180. package/src/Notification/NotificationClose.torp +28 -0
  181. package/src/Notification/NotificationContainer.torp +14 -0
  182. package/src/Notification/NotificationContent.torp +13 -0
  183. package/src/Notification/NotificationTypes.ts +5 -0
  184. package/src/Notification/index.ts +13 -0
  185. package/src/Notification/showNotification.ts +30 -0
  186. package/src/Popover/Popover.torp +2 -2
  187. package/src/Popover/PopoverContent.torp +31 -28
  188. package/src/Popover/PopoverContentAnchored.torp +39 -38
  189. package/src/Popover/PopoverContentContextual.torp +39 -36
  190. package/src/Popover/PopoverOverlay.torp +3 -3
  191. package/src/Popover/PopoverTrigger.torp +2 -2
  192. package/src/Popover/PopoverTriggerContextual.torp +2 -2
  193. package/src/Popover/PopoverTriggerHover.torp +3 -3
  194. package/src/Slider/Slider.torp +83 -0
  195. package/src/Slider/index.ts +3 -0
  196. package/src/TabGroup/TabContent.torp +2 -2
  197. package/src/TabGroup/TabGroup.torp +2 -2
  198. package/src/TabGroup/TabHeader.torp +3 -3
  199. package/src/TabGroup/TabList.torp +2 -2
  200. package/src/TabGroup/TabTrigger.torp +2 -2
  201. package/src/icons/ArrowDown.torp +15 -0
  202. package/src/icons/ArrowLeft.torp +15 -0
  203. package/src/icons/ArrowRight.torp +15 -0
  204. package/src/icons/ArrowUp.torp +15 -0
  205. package/src/icons/Bars.torp +17 -0
  206. package/src/icons/Check.torp +15 -0
  207. package/src/icons/ChevronDown.torp +15 -0
  208. package/src/icons/ChevronLeft.torp +15 -0
  209. package/src/icons/ChevronRight.torp +15 -0
  210. package/src/icons/ChevronUp.torp +15 -0
  211. package/src/icons/Cross.torp +16 -0
  212. package/src/icons/Loading.torp +16 -0
  213. package/src/icons/Minus.torp +15 -0
  214. package/src/icons/Plus.torp +16 -0
  215. package/src/icons/index.ts +31 -0
  216. package/src/motion/fade.ts +2 -2
  217. package/src/motion/index.ts +3 -0
  218. package/src/utils/dateUtils.ts +244 -0
  219. package/src/utils/setPopoverPosition.ts +4 -0
  220. package/test/Breadcrumb/accessibility.test.ts +29 -0
  221. package/test/Breadcrumb/basic.test.ts +17 -0
  222. package/test/Breadcrumb/components/BreadcrumbTest.torp +15 -0
  223. package/test/Calendar/components/CalendarTest.torp +9 -0
  224. package/test/Calendar/default.test.ts +18 -0
  225. package/test/Dialog/components/DialogAccessibility.torp +5 -5
  226. package/test/Dialog/components/DialogFunction.torp +4 -6
  227. package/test/Dialog/components/DialogVariable.torp +19 -21
  228. package/test/Disclosure/accessibility.test.ts +30 -0
  229. package/test/Disclosure/components/DisclosureTest.torp +17 -0
  230. package/test/Disclosure/default.test.ts +15 -0
  231. package/test/Disclosure/toggle.test.ts +19 -0
  232. package/test/Menu/accessibility.test.ts +82 -0
  233. package/test/Menu/basic.test.ts +57 -0
  234. package/test/Menu/components/MenuAccessibility.torp +59 -0
  235. package/test/Menu/components/MenuBasic.torp +58 -0
  236. package/test/MenuBar/accessibility.test.ts +86 -0
  237. package/test/MenuBar/basic.test.ts +21 -0
  238. package/test/MenuBar/components/MenuBarAccessibility.torp +34 -0
  239. package/test/MenuBar/components/MenuBarBasic.torp +25 -0
  240. package/test/Notification/accessibility.test.ts +21 -0
  241. package/test/Notification/components/CustomNotification.torp +14 -0
  242. package/test/Notification/components/NotificationAccessibility.torp +14 -0
  243. package/test/Notification/components/NotificationFunction.torp +20 -0
  244. package/test/Notification/components/NotificationVariable.torp +22 -0
  245. package/test/Notification/function.test.ts +25 -0
  246. package/test/Notification/variable.test.ts +25 -0
  247. package/test/Popover/components/CustomDialog.torp +25 -0
  248. package/test/Popover/components/PromptFunction.torp +19 -0
  249. package/test/Popover/components/PromptVariable.torp +38 -0
  250. package/test/Popover/function.test.ts +26 -0
  251. package/test/Popover/variable.test.ts +27 -0
  252. package/tsup.config.ts +12 -4
  253. package/dist/Accordion/index.cjs +0 -53
  254. package/dist/Accordion/index.cjs.map +0 -1
  255. package/dist/Dialog/index.cjs +0 -53
  256. package/dist/Dialog/index.cjs.map +0 -1
  257. package/dist/NavMenu/index.cjs +0 -78
  258. package/dist/NavMenu/index.cjs.map +0 -1
  259. package/dist/Offscreen/index.cjs +0 -33
  260. package/dist/Offscreen/index.cjs.map +0 -1
  261. package/dist/Offscreen/index.js +0 -6
  262. package/dist/Popover/index.cjs +0 -222
  263. package/dist/Popover/index.cjs.map +0 -1
  264. package/dist/TabGroup/index.cjs +0 -53
  265. package/dist/TabGroup/index.cjs.map +0 -1
  266. package/dist/metafile-cjs.json +0 -1
  267. package/dist/motion.cjs +0 -34
  268. package/dist/motion.cjs.map +0 -1
  269. package/dist/motion.d.ts +0 -6
  270. package/dist/motion.js.map +0 -1
  271. package/src/Accordion.ts +0 -7
  272. package/src/Dialog.ts +0 -7
  273. package/src/NavMenu.ts +0 -23
  274. package/src/Offscreen/index.ts +0 -3
  275. package/src/Popover.ts +0 -29
  276. package/src/TabGroup.ts +0 -7
  277. package/src/motion.ts +0 -3
  278. /package/dist/{Offscreen → Breadcrumb}/index.js.map +0 -0
@@ -27,7 +27,7 @@ export default function NavMenuButton($props: any) {
27
27
 
28
28
  @render {
29
29
  <button
30
- id={$props.id}
30
+ {$props.id}
31
31
  class={`torp-nav-menu-button ${$props.class ?? ""}`.trim()}
32
32
  type="button"
33
33
  {$props.disabled}
@@ -40,7 +40,7 @@ export default function NavMenuButton($props: any) {
40
40
  onfocus={() => handleItemFocus(index)}
41
41
  &ref={button}
42
42
  >
43
- <:slot />
43
+ <slot />
44
44
  </button>
45
45
  }
46
46
  }
@@ -26,7 +26,7 @@ export default function NavMenuElement($props: any) {
26
26
 
27
27
  @render {
28
28
  <div
29
- id={$props.id}
29
+ {$props.id}
30
30
  class={`torp-nav-menu-div ${$props.class ?? ""}`.trim()}
31
31
  type="div"
32
32
  role="menuitem"
@@ -37,7 +37,7 @@ export default function NavMenuElement($props: any) {
37
37
  onclick
38
38
  onfocus={() => handleItemFocus(index)}
39
39
  >
40
- <:slot />
40
+ <slot />
41
41
  </div>
42
42
  }
43
43
  }
@@ -18,13 +18,13 @@ export default function NavMenuGroup($props: any) {
18
18
 
19
19
  @render {
20
20
  <div
21
- id={$props.id}
21
+ {$props.id}
22
22
  class={`torp-nav-menu-group ${$props.class ?? ""}`.trim()}
23
23
  role="group"
24
24
  aria-label={$props.ariaLabel}
25
25
  aria-labelledby={$state.headerId}
26
26
  >
27
- <:slot />
27
+ <slot />
28
28
  </div>
29
29
  }
30
30
  }
@@ -21,10 +21,10 @@ export default function NavMenuGroupHeader($props: any) {
21
21
  @render {
22
22
  <h4
23
23
  @// TODO: self={$props.as}
24
- id={$props.id}
24
+ {$props.id}
25
25
  class={`torp-nav-menu-group-header ${$props.class ?? ""}`.trim()}
26
26
  >
27
- <:slot />
27
+ <slot />
28
28
  </h4>
29
29
  }
30
30
  }
@@ -32,7 +32,7 @@ export default function NavMenuLink($props: any) {
32
32
 
33
33
  @render {
34
34
  <a
35
- id={$props.id}
35
+ {$props.id}
36
36
  class={`torp-nav-menu-link ${$props.class ?? ""}`.trim()}
37
37
  href={$props.href}
38
38
  {$props.disabled}
@@ -46,7 +46,7 @@ export default function NavMenuLink($props: any) {
46
46
  onfocus={() => handleItemFocus(index)}
47
47
  &ref={link}
48
48
  >
49
- <:slot />
49
+ <slot />
50
50
  </a>
51
51
  }
52
52
  }
@@ -59,11 +59,11 @@ export default function NavMenuPopout($props: any) {
59
59
 
60
60
  @render {
61
61
  <div
62
- id={$props.id}
62
+ {$props.id}
63
63
  class={`torp-nav-menu-popout ${$props.class ?? ""}`.trim()}
64
64
  onmouseleave={handleMouseLeave}
65
65
  >
66
- <:slot />
66
+ <slot />
67
67
  </div>
68
68
  }
69
69
  }
@@ -96,7 +96,7 @@ export default function NavMenuPopoutButton($props: any) {
96
96
 
97
97
  @render {
98
98
  <button
99
- id={$props.id}
99
+ {$props.id}
100
100
  class={`torp-nav-menu-popout-button ${$props.class ?? ""}`.trim()}
101
101
  type="button"
102
102
  {$props.disabled}
@@ -112,9 +112,9 @@ export default function NavMenuPopoutButton($props: any) {
112
112
  onmouseleave={handleMouseLeave}
113
113
  onmousemove={handleMouseMove}
114
114
  &ref={button}
115
- :onmount={(el) => popoutContext.anchorElement = el }
115
+ onmount={(el) => popoutContext.anchorElement = el }
116
116
  >
117
- <:slot />
117
+ <slot />
118
118
  </button>
119
119
  }
120
120
  }
@@ -14,6 +14,7 @@ export default function NavMenuPopoutContent($props: any) {
14
14
  $props.alignment ??= "start";
15
15
 
16
16
  let div: HTMLDivElement;
17
+ let shown = false;
17
18
 
18
19
  // Get stuff out of the NavMenuPopoutContext
19
20
  const context = $context[NavMenuPopoutContextName] as NavMenuPopoutContext;
@@ -22,35 +23,36 @@ export default function NavMenuPopoutContent($props: any) {
22
23
  }
23
24
  let $state = context.state;
24
25
 
25
- let first = true;
26
26
  $run(() => {
27
- let visible = $state.visible;
27
+ if (!$state.visible) {
28
+ hide();
29
+ }
30
+ });
28
31
 
29
- if (first) {
30
- first = false;
31
- return;
32
+ function show() {
33
+ shown = true;
34
+
35
+ // Set the position and listen for window resize and scroll to reset the position
36
+ setPosition();
37
+ const scrollParent = getScrollParent(context.anchorElement)
38
+ scrollParent.addEventListener("resize", setPosition);
39
+ scrollParent.addEventListener("scroll", setPosition);
40
+ if (context.focusFirstElement) {
41
+ context.focusFirstElement();
32
42
  }
43
+ }
33
44
 
34
- if (visible) {
35
- // Wait for the content div to be shown, set its position, and listen for window resize to re-position
36
- //await tick();
37
- setPosition();
38
- if (context.focusFirstElement) {
39
- context.focusFirstElement();
40
- }
41
- const scrollParent = getScrollParent(context.anchorElement)
42
- scrollParent.addEventListener("resize", setPosition);
43
- scrollParent.addEventListener("scroll", setPosition);
44
- } else {
45
- // Stop listening for window resize and focus the anchor element per WAI guidelines
46
- const scrollParent = getScrollParent(context.anchorElement)
47
- scrollParent.removeEventListener("resize", setPosition);
48
- scrollParent.removeEventListener("scroll", setPosition);
49
- if (context.anchorElement?.focus) {
50
- context.anchorElement.focus();
51
- }
45
+ function hide() {
46
+ if (!shown) return;
47
+
48
+ // Stop listening for window resize and focus the anchor element per WAI guidelines
49
+ const scrollParent = getScrollParent(context.anchorElement)
50
+ scrollParent.removeEventListener("resize", setPosition);
51
+ scrollParent.removeEventListener("scroll", setPosition);
52
+ if (context.anchorElement?.focus) {
53
+ context.anchorElement.focus();
52
54
  }
53
- });
55
+ }
54
56
 
55
57
  function setPosition() {
56
58
  if (!context.anchorElement) {
@@ -65,12 +67,12 @@ export default function NavMenuPopoutContent($props: any) {
65
67
  @render {
66
68
  @if ($state.visible) {
67
69
  <div
68
- id={$props.id}
70
+ {$props.id}
69
71
  class={`torp-nav-menu-popout-content ${$props.class ?? ""}`.trim()}
70
72
  &ref={div}
71
- :onmount={(el) => setPopoverPosition(context.anchorElement, el, $props.side, $props.alignment)}
73
+ onmount={show}
72
74
  >
73
- <:slot />
75
+ <slot />
74
76
  </div>
75
77
  }
76
78
  }
@@ -5,10 +5,10 @@
5
5
  export default function NavMenuSeparator($props: any) {
6
6
  @render {
7
7
  <div
8
- id={$props.id}
8
+ {$props.id}
9
9
  class={`torp-nav-menu-separator ${$props.class ?? ""}`.trim()} role="separator"
10
10
  >
11
- <:slot />
11
+ <slot />
12
12
  </div>
13
13
  }
14
14
  }
@@ -0,0 +1,48 @@
1
+ import { NotificationContextName, type NotificationContext } from "./NotificationTypes";
2
+
3
+ /**
4
+ * An element that displays a brief, important message in a way that attracts
5
+ * the user's attention without interrupting the user's task.
6
+ *
7
+ * See [the WAI ARIA guidelines for Alerts](https://www.w3.org/WAI/ARIA/apg/patterns/alert/).
8
+ *
9
+ * @prop {boolean} visible -- Whether the notification is visible
10
+ * @prop {number | undefined} duration -- The duration, in milliseconds, to keep the notification visible
11
+ * @prop {() => void} onclose -- Raised when the notification has closed, either after the duration has elapsed, or when the user has pressed the close button
12
+ */
13
+ export default function Notification($props) {
14
+ $props.visible ??= true;
15
+ $props.duration ??= 5000;
16
+
17
+ // Set the context to pass down to items
18
+ let context: NotificationContext = {
19
+ closeNotification
20
+ };
21
+ $context[NotificationContextName] = context;
22
+
23
+ $mount(() => {
24
+ if ($props.duration) {
25
+ setTimeout(closeNotification, $props.duration);
26
+ }
27
+ });
28
+
29
+ function closeNotification() {
30
+ $props.visible = false;
31
+
32
+ if ($props.onclose) {
33
+ $props.onclose();
34
+ }
35
+ }
36
+
37
+ @render {
38
+ @if ($props.visible) {
39
+ <div
40
+ {$props.id}
41
+ class={`torp-notification ${$props.class ?? ""}`.trim()}
42
+ role="alert"
43
+ >
44
+ <slot />
45
+ </div>
46
+ }
47
+ }
48
+ }
@@ -0,0 +1,28 @@
1
+ import { NotificationContextName, type NotificationContext } from "./NotificationTypes";
2
+
3
+ /**
4
+ * The button that a user can press to close this Notification.
5
+ */
6
+ export default function NotificationClose() {
7
+ // Get stuff out of the NotificationContext
8
+ const context = $context[NotificationContextName] as NotificationContext;
9
+ if (!context) {
10
+ throw new Error("NotificationClose must be contained within a Notification");
11
+ }
12
+ const { closeNotification } = context;
13
+
14
+ function handleClick() {
15
+ closeNotification();
16
+ }
17
+
18
+ @render {
19
+ <button
20
+ {$props.id}
21
+ class={`torp-notification-close ${$props.class ?? ""}`.trim()}
22
+ type="button"
23
+ onclick={handleClick}
24
+ >
25
+ <slot />
26
+ </button>
27
+ }
28
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * The container for one or more Notifications, which can be used to position
3
+ * the notifications inside the viewport.
4
+ */
5
+ export default function NotificationContainer() {
6
+ @render {
7
+ <div
8
+ {$props.id}
9
+ class={`torp-notification-container ${$props.class ?? ""}`.trim()}
10
+ >
11
+ <slot />
12
+ </div>
13
+ }
14
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * The content to display within a Notification.
3
+ */
4
+ export default function NotificationContent() {
5
+ @render {
6
+ <div
7
+ {$props.id}
8
+ class={`torp-notification-content ${$props.class ?? ""}`.trim()}
9
+ >
10
+ <slot />
11
+ </div>
12
+ }
13
+ }
@@ -0,0 +1,5 @@
1
+ export const NotificationContextName = 'Notification';
2
+
3
+ export interface NotificationContext {
4
+ closeNotification: () => void;
5
+ }
@@ -0,0 +1,13 @@
1
+ import Notification from "./Notification.torp";
2
+ import NotificationClose from "./NotificationClose.torp";
3
+ import NotificationContainer from "./NotificationContainer.torp";
4
+ import NotificationContent from "./NotificationContent.torp";
5
+ import showNotification from "./showNotification";
6
+
7
+ export {
8
+ Notification,
9
+ NotificationContainer,
10
+ NotificationContent,
11
+ NotificationClose,
12
+ showNotification,
13
+ };
@@ -0,0 +1,30 @@
1
+ import { mount } from "@torpor/view";
2
+
3
+ /**
4
+ * Shows a notification component in code.
5
+ * @param notification The notification component
6
+ * @param props The properties for the notification component
7
+ * @param target The target element to show the notification in
8
+ */
9
+ export default function showNotification(notification: any, props: any, target?: Element): void {
10
+ if (!target) {
11
+ // Put the notification in the first NotificationContainer, or the
12
+ // document body if there are no NotificationContainers
13
+ target = document.getElementsByClassName("torp-notification-container")[0];
14
+ if (!target) {
15
+ throw new Error("No notification container found");
16
+ }
17
+ }
18
+
19
+ // HACK: Should allow mounting in a non-empty container
20
+ // Move existing nodes into a fragment, and add them back after mounting
21
+ var fragment = document.createDocumentFragment();
22
+ while (target.firstChild) {
23
+ fragment.append(target.firstChild);
24
+ }
25
+
26
+ // Create the notification
27
+ mount(target, notification, props);
28
+
29
+ target.prepend(fragment);
30
+ }
@@ -96,10 +96,10 @@ export default function Popover($props: any) {
96
96
 
97
97
  @render {
98
98
  <div
99
- id={$props.id}
99
+ {$props.id}
100
100
  class={`torp-popover ${$props.class ?? ""}`.trim()}
101
101
  >
102
- <:slot />
102
+ <slot />
103
103
  </div>
104
104
  }
105
105
  }
@@ -7,6 +7,8 @@ import { PopoverContextName, type PopoverContext } from "./PopoverTypes";
7
7
  */
8
8
  export default function PopoverContent($props: any) {
9
9
  let div: HTMLDivElement;
10
+ let shown = false;
11
+ let closeOnClick = false;
10
12
 
11
13
  // Get stuff out of the PopoverContext
12
14
  const context = $context[PopoverContextName] as PopoverContext;
@@ -15,37 +17,37 @@ export default function PopoverContent($props: any) {
15
17
  }
16
18
  let $state = context.state;
17
19
 
18
- let closeOnClick = false;
19
-
20
- let first = true;
21
20
  $run(() => {
22
- let visible = $state.visible;
21
+ if (!$state.visible) {
22
+ hide();
23
+ }
24
+ });
25
+
26
+ function show() {
27
+ shown = true;
23
28
 
24
- if (first) {
25
- first = false;
26
- return;
29
+ // HACK: Because this Popover could be shown with a click, we need to wait for another mousedown
30
+ // before we close on click. Otherwise the click immediately bubbles to the document
31
+ closeOnClick = false;
32
+ addDocumentEvent("mousedown", handleDocumentMouseDown);
33
+ addDocumentEvent("click", handleDocumentClick);
34
+
35
+ if (context.focusFirstElement) {
36
+ context.focusFirstElement();
27
37
  }
38
+ }
39
+
40
+ function hide() {
41
+ if (!shown) return;
28
42
 
29
- if (visible) {
30
- // HACK: Because this Popover could be shown with a click, we need to wait for another mousedown
31
- // before we close on click. Otherwise the click immediately bubbles to the document
32
- closeOnClick = false;
33
- addDocumentEvent("mousedown", handleDocumentMouseDown);
34
- addDocumentEvent("click", handleDocumentClick);
35
- // Wait for the content div to be shown, set its position, and listen for window resize to re-position
36
- //await tick();
37
- if (context.focusFirstElement) {
38
- context.focusFirstElement();
39
- }
40
- } else {
41
- removeDocumentEvent("mousedown", handleDocumentMouseDown);
42
- removeDocumentEvent("click", handleDocumentClick);
43
- // Focus the anchor element per WAI guidelines
44
- if (context.anchorElement?.focus) {
45
- context.anchorElement.focus();
46
- }
43
+ removeDocumentEvent("mousedown", handleDocumentMouseDown);
44
+ removeDocumentEvent("click", handleDocumentClick);
45
+
46
+ // Focus the anchor element per WAI guidelines
47
+ if (context.anchorElement?.focus) {
48
+ context.anchorElement.focus();
47
49
  }
48
- });
50
+ }
49
51
 
50
52
  function handleDocumentMouseDown() {
51
53
  closeOnClick = true;
@@ -65,11 +67,12 @@ export default function PopoverContent($props: any) {
65
67
  @render {
66
68
  @if ($state.visible) {
67
69
  <div
68
- id={$props.id}
70
+ {$props.id}
69
71
  class={`torp-popover-content ${$props.class ?? ""}`.trim()}
70
72
  &ref={div}
73
+ onmount={show}
71
74
  >
72
- <:slot />
75
+ <slot />
73
76
  </div>
74
77
  }
75
78
  }
@@ -17,7 +17,7 @@ export default function PopoverContentAnchored($props: any) {
17
17
  $props.alignment ??= "center";
18
18
 
19
19
  let div: HTMLDivElement;
20
-
20
+ let shown = false;
21
21
  let closeOnClick = false;
22
22
 
23
23
  // Get stuff out of the PopoverContext
@@ -27,42 +27,45 @@ export default function PopoverContentAnchored($props: any) {
27
27
  }
28
28
  let $state = context.state;
29
29
 
30
- let first = true;
31
30
  $run(() => {
32
- let visible = $state.visible;
31
+ if (!$state.visible) {
32
+ hide();
33
+ }
34
+ });
33
35
 
34
- if (first) {
35
- first = false;
36
- return;
36
+ function show() {
37
+ shown = true;
38
+
39
+ // HACK: Because this Popover could be shown with a click, we need to wait for another mousedown
40
+ // before we close on click. Otherwise the click immediately bubbles to the document
41
+ closeOnClick = false;
42
+ addDocumentEvent("mousedown", handleDocumentMouseDown);
43
+ addDocumentEvent("click", handleDocumentClick);
44
+
45
+ // Set the position and listen for window resize and scroll to reset the position
46
+ setPosition();
47
+ const scrollParent = getScrollParent(context.anchorElement)
48
+ scrollParent.addEventListener("resize", setPosition);
49
+ scrollParent.addEventListener("scroll", setPosition);
50
+ if (context.focusFirstElement) {
51
+ context.focusFirstElement();
37
52
  }
53
+ }
38
54
 
39
- if (visible) {
40
- // HACK: Because this Popover could be shown with a click, we need to wait for another mousedown
41
- // before we close on click. Otherwise the click immediately bubbles to the document
42
- closeOnClick = false;
43
- addDocumentEvent("mousedown", handleDocumentMouseDown);
44
- addDocumentEvent("click", handleDocumentClick);
45
- // Wait for the content div to be shown, set its position, and listen for window resize to re-position
46
- //await tick();
47
- setPosition();
48
- if (context.focusFirstElement) {
49
- context.focusFirstElement();
50
- }
51
- const scrollParent = getScrollParent(context.anchorElement)
52
- scrollParent.addEventListener("resize", setPosition);
53
- scrollParent.addEventListener("scroll", setPosition);
54
- } else {
55
- removeDocumentEvent("mousedown", handleDocumentMouseDown);
56
- removeDocumentEvent("click", handleDocumentClick);
57
- // Stop listening for window resize and focus the anchor element per WAI guidelines
58
- const scrollParent = getScrollParent(context.anchorElement)
59
- scrollParent.removeEventListener("resize", setPosition);
60
- scrollParent.removeEventListener("scroll", setPosition);
61
- if (context.anchorElement?.focus) {
62
- context.anchorElement.focus();
63
- }
55
+ function hide() {
56
+ if (!shown) return;
57
+
58
+ removeDocumentEvent("mousedown", handleDocumentMouseDown);
59
+ removeDocumentEvent("click", handleDocumentClick);
60
+
61
+ // Stop listening for window resize and focus the anchor element per WAI guidelines
62
+ const scrollParent = getScrollParent(context.anchorElement)
63
+ scrollParent.removeEventListener("resize", setPosition);
64
+ scrollParent.removeEventListener("scroll", setPosition);
65
+ if (context.anchorElement?.focus) {
66
+ context.anchorElement.focus();
64
67
  }
65
- });
68
+ }
66
69
 
67
70
  function handleDocumentMouseDown() {
68
71
  closeOnClick = true;
@@ -85,20 +88,18 @@ export default function PopoverContentAnchored($props: any) {
85
88
  throw new Error("PopoverContentAnchored must have an anchor element");
86
89
  }
87
90
 
88
- if (div) {
89
- setPopoverPosition(context.anchorElement, div, $props.side, $props.alignment);
90
- }
91
+ setPopoverPosition(context.anchorElement, div, $props.side, $props.alignment);
91
92
  }
92
93
 
93
94
  @render {
94
95
  @if ($state.visible) {
95
96
  <div
96
- id={$props.id}
97
+ {$props.id}
97
98
  class={`torp-popover-content-anchored ${$props.class ?? ""}`.trim()}
98
99
  &ref={div}
99
- :onmount={(el) => setPopoverPosition(context.anchorElement, el, $props.side, $props.alignment)}
100
+ onmount={show}
100
101
  >
101
- <:slot />
102
+ <slot />
102
103
  </div>
103
104
  }
104
105
  }