@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
@@ -0,0 +1,57 @@
1
+ import { fireEvent, getByText, queryByText } from "@testing-library/dom";
2
+ import "@testing-library/jest-dom/vitest";
3
+ import { mount } from "@torpor/view";
4
+ import { describe, expect, it } from "vitest";
5
+ import MenuBasic from "./components/MenuBasic.torp";
6
+
7
+ describe("Menu", () => {
8
+ it("Basic operation", async () => {
9
+ const container = document.createElement("div");
10
+ document.body.appendChild(container);
11
+ mount(container, MenuBasic);
12
+
13
+ // By default, the top-level buttons should be displayed
14
+ expect(queryByText(container, "Menu button")).toBeInTheDocument();
15
+ expect(queryByText(container, "Check popout button")).toBeInTheDocument();
16
+ expect(queryByText(container, "Radio popout button")).toBeInTheDocument();
17
+
18
+ // Submenus should not be displayed
19
+ expect(queryByText(container, "Checked 1")).not.toBeInTheDocument();
20
+ expect(queryByText(container, "Radio 1")).not.toBeInTheDocument();
21
+
22
+ // Clicking a popout button should show the appropriate menu
23
+ fireEvent.click(getByText(container, "Check popout button"));
24
+ expect(queryByText(container, "Checked 1")).toBeInTheDocument();
25
+ expect(queryByText(container, "Radio 1")).not.toBeInTheDocument();
26
+
27
+ // Clicking another popout button should show that menu instead
28
+ fireEvent.click(getByText(container, "Radio popout button"));
29
+ //expect(queryByText(container, 'Checked 1')).not.toBeInTheDocument();
30
+ expect(queryByText(container, "Radio 1")).toBeInTheDocument();
31
+
32
+ // Checking a box should show or hide the indicator
33
+ fireEvent.click(getByText(container, "Check popout button"));
34
+ expect(queryByText(container, "Tick 1")).not.toBeInTheDocument();
35
+ expect(queryByText(container, "Tick 2")).not.toBeInTheDocument();
36
+ fireEvent.click(getByText(container, "Checked 1"));
37
+ expect(queryByText(container, "Tick 1")).toBeInTheDocument();
38
+ expect(queryByText(container, "Tick 2")).not.toBeInTheDocument();
39
+ fireEvent.click(getByText(container, "Checked 2"));
40
+ expect(queryByText(container, "Tick 1")).toBeInTheDocument();
41
+ expect(queryByText(container, "Tick 2")).toBeInTheDocument();
42
+ fireEvent.click(getByText(container, "Checked 1"));
43
+ expect(queryByText(container, "Tick 1")).not.toBeInTheDocument();
44
+ expect(queryByText(container, "Tick 2")).toBeInTheDocument();
45
+
46
+ // Checking a radio should show the indicator, and hide another indicator if already selected
47
+ fireEvent.click(getByText(container, "Radio popout button"));
48
+ expect(queryByText(container, "Circle 1")).not.toBeInTheDocument();
49
+ expect(queryByText(container, "Circle 2")).not.toBeInTheDocument();
50
+ fireEvent.click(getByText(container, "Radio 1"));
51
+ expect(queryByText(container, "Circle 1")).toBeInTheDocument();
52
+ expect(queryByText(container, "Circle 2")).not.toBeInTheDocument();
53
+ fireEvent.click(getByText(container, "Radio 2"));
54
+ expect(queryByText(container, "Circle 1")).not.toBeInTheDocument();
55
+ expect(queryByText(container, "Circle 2")).toBeInTheDocument();
56
+ });
57
+ });
@@ -0,0 +1,59 @@
1
+ import { Popover, PopoverContent } from "../../../src/Popover";
2
+ import {
3
+ Menu,
4
+ MenuButton,
5
+ MenuRadioGroup,
6
+ MenuCheck,
7
+ MenuRadio,
8
+ MenuIndicator,
9
+ MenuPopout,
10
+ MenuPopoutTrigger,
11
+ MenuPopoutContent,
12
+ MenuSeparator
13
+ } from "../../../src/Menu";
14
+
15
+ export default function MenuAccessibility() {
16
+ @render {
17
+ <Popover visible>
18
+ <PopoverContent>
19
+ <Menu ariaLabel="A menu">
20
+ <MenuButton>Menu button</MenuButton>
21
+ <MenuButton disabled>Disabled button</MenuButton>
22
+ <MenuSeparator>---</MenuSeparator>
23
+ <MenuPopout>
24
+ <MenuPopoutTrigger>Check popout button</MenuPopoutTrigger>
25
+ <MenuPopoutContent>
26
+ <Menu ariaLabel="A checked menu">
27
+ <MenuCheck>
28
+ <MenuIndicator>✔</MenuIndicator>
29
+ Checked 1
30
+ </MenuCheck>
31
+ <MenuCheck>
32
+ <MenuIndicator>✔</MenuIndicator>
33
+ Checked 2
34
+ </MenuCheck>
35
+ </Menu>
36
+ </MenuPopoutContent>
37
+ </MenuPopout>
38
+ <MenuPopout>
39
+ <MenuPopoutTrigger>Radio popout button</MenuPopoutTrigger>
40
+ <MenuPopoutContent>
41
+ <Menu ariaLabel="A radio menu">
42
+ <MenuRadioGroup ariaLabel="Options">
43
+ <MenuRadio value="radio1">
44
+ <MenuIndicator>•</MenuIndicator>
45
+ Radio 1
46
+ </MenuRadio>
47
+ <MenuRadio value="radio2">
48
+ <MenuIndicator>•</MenuIndicator>
49
+ Radio 2
50
+ </MenuRadio>
51
+ </MenuRadioGroup>
52
+ </Menu>
53
+ </MenuPopoutContent>
54
+ </MenuPopout>
55
+ </Menu>
56
+ </PopoverContent>
57
+ </Popover>
58
+ }
59
+ }
@@ -0,0 +1,58 @@
1
+ import { Popover, PopoverContent } from "../../../src/Popover";
2
+ import {
3
+ Menu,
4
+ MenuButton,
5
+ MenuRadioGroup,
6
+ MenuCheck,
7
+ MenuRadio,
8
+ MenuIndicator,
9
+ MenuPopout,
10
+ MenuPopoutTrigger,
11
+ MenuPopoutContent,
12
+ MenuSeparator
13
+ } from "../../../src/Menu";
14
+
15
+ export default function MenuBasic() {
16
+ @render {
17
+ <Popover visible>
18
+ <PopoverContent>
19
+ <Menu ariaLabel="A menu">
20
+ <MenuButton>Menu button</MenuButton>
21
+ <MenuSeparator>---</MenuSeparator>
22
+ <MenuPopout>
23
+ <MenuPopoutTrigger>Check popout button</MenuPopoutTrigger>
24
+ <MenuPopoutContent>
25
+ <Menu ariaLabel="A checked menu">
26
+ <MenuCheck>
27
+ <MenuIndicator>Tick 1</MenuIndicator>
28
+ Checked 1
29
+ </MenuCheck>
30
+ <MenuCheck>
31
+ <MenuIndicator>Tick 2</MenuIndicator>
32
+ Checked 2
33
+ </MenuCheck>
34
+ </Menu>
35
+ </MenuPopoutContent>
36
+ </MenuPopout>
37
+ <MenuPopout>
38
+ <MenuPopoutTrigger>Radio popout button</MenuPopoutTrigger>
39
+ <MenuPopoutContent>
40
+ <Menu ariaLabel="A radio menu">
41
+ <MenuRadioGroup ariaLabel="Font color">
42
+ <MenuRadio value="radio1">
43
+ <MenuIndicator>Circle 1</MenuIndicator>
44
+ Radio 1
45
+ </MenuRadio>
46
+ <MenuRadio value="radio2">
47
+ <MenuIndicator>Circle 2</MenuIndicator>
48
+ Radio 2
49
+ </MenuRadio>
50
+ </MenuRadioGroup>
51
+ </Menu>
52
+ </MenuPopoutContent>
53
+ </MenuPopout>
54
+ </Menu>
55
+ </PopoverContent>
56
+ </Popover>
57
+ }
58
+ }
@@ -0,0 +1,86 @@
1
+ import { fireEvent, getByText, queryByText } from "@testing-library/dom";
2
+ import "@testing-library/jest-dom/vitest";
3
+ import { mount } from "@torpor/view";
4
+ import { describe, expect, it } from "vitest";
5
+ import MenuBarAccessibility from "./components/MenuBarAccessibility.torp";
6
+
7
+ describe("MenuBar", () => {
8
+ it("Accessibility", async () => {
9
+ const container = document.createElement("div");
10
+ document.body.appendChild(container);
11
+ mount(container, MenuBarAccessibility);
12
+
13
+ // Tests from https://www.w3.org/WAI/ARIA/apg/patterns/menu/
14
+ // NOTE: MenuBar is a menubar
15
+
16
+ // A menu is a container of items that represent choices. The element serving as the menu has
17
+ // a role of either menu or menubar
18
+ expect(queryByText(container, "Top level")?.parentElement?.parentElement).toHaveAttribute(
19
+ "role",
20
+ "menubar",
21
+ );
22
+
23
+ // The items contained in a menu are child elements of the containing menu or menubar and have
24
+ // any of the following roles:
25
+ // * menuitem
26
+ // * menuitemcheckbox
27
+ // * menuitemradio
28
+ expect(queryByText(container, "Top level")).toHaveAttribute("role", "menuitem");
29
+
30
+ // If activating a menuitem opens a submenu, the menuitem is known as a parent menuitem. A submenu's
31
+ // menu element is:
32
+ // * Contained inside the same menu element as its parent menuitem
33
+ // * Is the sibling element immediately following its parent menuitem
34
+
35
+ // A parent menuitem has aria-haspopup set to either menu or true
36
+ expect(queryByText(container, "Top level")).toHaveAttribute("aria-haspopup", "true");
37
+
38
+ // A parent menuitem has aria-expanded set to false when its child menu is not visible and set
39
+ // to true when the child menu is visible
40
+ expect(queryByText(container, "Top level")).toHaveAttribute("aria-expanded", "false");
41
+ fireEvent.click(getByText(container, "Top level"));
42
+ expect(queryByText(container, "Top level")).toHaveAttribute("aria-expanded", "true");
43
+
44
+ // One of the following approaches is used to enable scripts to move focus among items in a
45
+ // menu as described in Keyboard Navigation Inside Components:
46
+ // * The menu container has tabindex set to -1 or 0 and aria-activedescendant set to the ID
47
+ // of the focused item
48
+ // * Each item in the menu has tabindex set to -1, except in a menubar, where the first item
49
+ // has tabindex set to 0
50
+
51
+ // When a menuitemcheckbox or menuitemradio is checked, aria-checked is set to true
52
+ // NOTE: We don't (currently?) have checkboxes or radios in MenuBars
53
+
54
+ // When a menu item is disabled, aria-disabled is set to true
55
+ expect(queryByText(container, "Top level")).not.toHaveAttribute("aria-disabled");
56
+ expect(queryByText(container, "Disabled")).toHaveAttribute("aria-disabled", "true");
57
+
58
+ // Items in a menu may be divided into groups by placing an element with a role of separator
59
+ // between groups. For example, this technique should be used when a menu contains a set of
60
+ // menuitemradio items
61
+ expect(queryByText(container, "---")).toHaveAttribute("role", "separator");
62
+
63
+ // All separators should have aria-orientation consistent with the separator's orientation
64
+ // NOTE: What does this mean? None of the example separators have aria-orientation set
65
+
66
+ // If a menubar has a visible label, the element with role menubar has aria-labelledby set to
67
+ // a value that refers to the labelling element. Otherwise, the menubar element has a label
68
+ // provided by aria-label
69
+ // NOTE: We only support aria-label and it's required
70
+ expect(queryByText(container, "Top level")?.parentElement?.parentElement).toHaveAttribute(
71
+ "aria-label",
72
+ "Window menu",
73
+ );
74
+
75
+ // If a menubar is vertically oriented, it has aria-orientation set to vertical. The default
76
+ // value of aria-orientation for a menubar is horizontal
77
+ expect(queryByText(container, "Top level")?.parentElement?.parentElement).toHaveAttribute(
78
+ "aria-orientation",
79
+ "horizontal",
80
+ );
81
+ expect(queryByText(container, "Sub item 1")?.parentElement).toHaveAttribute(
82
+ "aria-orientation",
83
+ "vertical",
84
+ );
85
+ });
86
+ });
@@ -0,0 +1,21 @@
1
+ import { fireEvent, getByText, queryByText } from "@testing-library/dom";
2
+ import "@testing-library/jest-dom/vitest";
3
+ import { mount } from "@torpor/view";
4
+ import { describe, expect, it } from "vitest";
5
+ import MenuBarBasic from "./components/MenuBarBasic.torp";
6
+
7
+ describe("MenuBar", () => {
8
+ it("Basic operation", async () => {
9
+ const container = document.createElement("div");
10
+ document.body.appendChild(container);
11
+ mount(container, MenuBarBasic);
12
+
13
+ // The top level item should be displayed
14
+ expect(queryByText(container, "Top level")).toBeInTheDocument();
15
+ expect(queryByText(container, "Sub item 1")).not.toBeInTheDocument();
16
+
17
+ // Clicking the top level item should show the sub item
18
+ fireEvent.click(getByText(container, "Top level"));
19
+ expect(queryByText(container, "Sub item 1")).toBeInTheDocument();
20
+ });
21
+ });
@@ -0,0 +1,34 @@
1
+ import {
2
+ MenuBar,
3
+ MenuBarItem,
4
+ MenuBarItemTrigger,
5
+ MenuBarItemContent
6
+ } from "../../../src/MenuBar";
7
+ import { Menu, MenuButton, MenuSeparator } from "../../../src/Menu";
8
+
9
+ export default function MenuBarAccessibility() {
10
+ @render {
11
+ <MenuBar ariaLabel="Window menu">
12
+ <MenuBarItem>
13
+ <MenuBarItemTrigger>Top level</MenuBarItemTrigger>
14
+ <MenuBarItemContent>
15
+ <Menu ariaLabel="Sub window menu">
16
+ <MenuButton>Sub item 1</MenuButton>
17
+ <MenuButton>Sub item 2</MenuButton>
18
+ <MenuSeparator>---</MenuSeparator>
19
+ <MenuButton>Sub item 3</MenuButton>
20
+ </Menu>
21
+ </MenuBarItemContent>
22
+ </MenuBarItem>
23
+ <MenuBarItem>
24
+ <MenuBarItemTrigger disabled>Disabled</MenuBarItemTrigger>
25
+ <MenuBarItemContent>
26
+ <Menu ariaLabel="Disabled sub window menu">
27
+ <MenuButton>Disabled sub 1</MenuButton>
28
+ <MenuButton>Disabled sub 2</MenuButton>
29
+ </Menu>
30
+ </MenuBarItemContent>
31
+ </MenuBarItem>
32
+ </MenuBar>
33
+ }
34
+ }
@@ -0,0 +1,25 @@
1
+ import {
2
+ MenuBar,
3
+ MenuBarItem,
4
+ MenuBarItemTrigger,
5
+ MenuBarItemContent
6
+ } from "../../../src/MenuBar";
7
+ import { Menu, MenuButton, MenuSeparator } from "../../../src/Menu";
8
+
9
+ export default function MenuBarBasic() {
10
+ @render {
11
+ <MenuBar ariaLabel="Window menu">
12
+ <MenuBarItem>
13
+ <MenuBarItemTrigger>Top level</MenuBarItemTrigger>
14
+ <MenuBarItemContent>
15
+ <Menu ariaLabel="Sub window menu">
16
+ <MenuButton>Sub item 1</MenuButton>
17
+ <MenuButton>Sub item 2</MenuButton>
18
+ <MenuSeparator />
19
+ <MenuButton>Sub item 3</MenuButton>
20
+ </Menu>
21
+ </MenuBarItemContent>
22
+ </MenuBarItem>
23
+ </MenuBar>
24
+ }
25
+ }
@@ -0,0 +1,21 @@
1
+ import { queryByText } from "@testing-library/dom";
2
+ import "@testing-library/jest-dom/vitest";
3
+ import { mount } from "@torpor/view";
4
+ import { describe, expect, it } from "vitest";
5
+ import NotificationAccessibility from "./components/NotificationAccessibility.torp";
6
+
7
+ describe("Notification", () => {
8
+ it("Accessibility", async () => {
9
+ const container = document.createElement("div");
10
+ document.body.appendChild(container);
11
+ mount(container, NotificationAccessibility);
12
+
13
+ // Tests from https://www.w3.org/WAI/ARIA/apg/patterns/alert/
14
+
15
+ // The widget has a role of alert
16
+ expect(queryByText(container, "Here's a notification")?.parentElement).toHaveAttribute(
17
+ "role",
18
+ "alert",
19
+ );
20
+ });
21
+ });
@@ -0,0 +1,14 @@
1
+ import {
2
+ Notification,
3
+ NotificationContent,
4
+ NotificationClose
5
+ } from "../../../src/Notification/index";
6
+
7
+ export default function CustomNotification() {
8
+ @render {
9
+ <Notification>
10
+ <NotificationContent>{$props.text}</NotificationContent>
11
+ <NotificationClose>Close me</NotificationClose>
12
+ </Notification>
13
+ }
14
+ }
@@ -0,0 +1,14 @@
1
+ import {
2
+ Notification,
3
+ NotificationContent,
4
+ NotificationClose
5
+ } from "../../../src/Notification/index";
6
+
7
+ export default function NotificationAccessibility() {
8
+ @render {
9
+ <Notification visible>
10
+ <NotificationContent>Here's a notification</NotificationContent>
11
+ <NotificationClose>Close me</NotificationClose>
12
+ </Notification>
13
+ }
14
+ }
@@ -0,0 +1,20 @@
1
+ import {
2
+ Notification,
3
+ NotificationContainer,
4
+ NotificationContent,
5
+ NotificationClose,
6
+ showNotification
7
+ } from "../../../src/Notification/index";
8
+ import CustomNotification from "./CustomNotification.torp";
9
+
10
+ export default function NotificationFunction() {
11
+ function show() {
12
+ showNotification(CustomNotification, { text: "Here's a notification" });
13
+ }
14
+
15
+ @render {
16
+ <button type="button" onclick={show}>Show a notification</button>
17
+
18
+ <NotificationContainer />
19
+ }
20
+ }
@@ -0,0 +1,22 @@
1
+ import {
2
+ Notification,
3
+ NotificationContent,
4
+ NotificationClose
5
+ } from "../../../src/Notification/index";
6
+
7
+ export default function NotificationVariable() {
8
+ let $state = $watch({
9
+ showNotification: false
10
+ });
11
+
12
+ @render {
13
+ <button type="button" onclick={(e) => ($state.showNotification = !$state.showNotification)}>
14
+ Show a notification
15
+ </button>
16
+
17
+ <Notification &visible={$state.showNotification}>
18
+ <NotificationContent>Here's a notification</NotificationContent>
19
+ <NotificationClose>Close me</NotificationClose>
20
+ </Notification>
21
+ }
22
+ }
@@ -0,0 +1,25 @@
1
+ import { getByText, queryByText } from "@testing-library/dom";
2
+ import "@testing-library/jest-dom/vitest";
3
+ import userEvent from "@testing-library/user-event";
4
+ import { mount } from "@torpor/view";
5
+ import { describe, expect, it } from "vitest";
6
+ import NotificationFunction from "./components/NotificationFunction.torp";
7
+
8
+ describe("Notification", () => {
9
+ it("Showing with a function", async () => {
10
+ const container = document.createElement("div");
11
+ document.body.appendChild(container);
12
+ mount(container, NotificationFunction);
13
+
14
+ // By default, the notification shouldn't be shown
15
+ expect(queryByText(container, "Here's a notification")).not.toBeInTheDocument();
16
+
17
+ // Clicking the button should show the notification
18
+ await userEvent.click(getByText(container, "Show a notification"));
19
+ expect(queryByText(container, "Here's a notification")).toBeInTheDocument();
20
+
21
+ // Clicking the close button should hide the notification
22
+ await userEvent.click(getByText(container, "Close me"));
23
+ expect(queryByText(container, "Here's a notification")).not.toBeInTheDocument();
24
+ });
25
+ });
@@ -0,0 +1,25 @@
1
+ import { getByText, queryByText } from "@testing-library/dom";
2
+ import "@testing-library/jest-dom/vitest";
3
+ import userEvent from "@testing-library/user-event";
4
+ import { mount } from "@torpor/view";
5
+ import { describe, expect, it } from "vitest";
6
+ import NotificationVariable from "./components/NotificationVariable.torp";
7
+
8
+ describe("Notification", () => {
9
+ it("Showing with a variable", async () => {
10
+ const container = document.createElement("div");
11
+ document.body.appendChild(container);
12
+ mount(container, NotificationVariable);
13
+
14
+ // By default, the notification shouldn't be shown
15
+ expect(queryByText(container, "Here's a notification")).not.toBeInTheDocument();
16
+
17
+ // Clicking the button should show the notification
18
+ await userEvent.click(getByText(container, "Show a notification"));
19
+ expect(queryByText(container, "Here's a notification")).toBeInTheDocument();
20
+
21
+ // Clicking the close button should hide the notification
22
+ await userEvent.click(getByText(container, "Close me"));
23
+ expect(queryByText(container, "Here's a notification")).not.toBeInTheDocument();
24
+ });
25
+ });
@@ -0,0 +1,25 @@
1
+ import { Popover, PopoverContent } from "../../../src/Popover/index";
2
+ import {
3
+ Dialog,
4
+ DialogBody,
5
+ DialogFooter,
6
+ DialogButton
7
+ } from "../../../src/Dialog/index";
8
+
9
+ export default function CustomDialog() {
10
+ @render {
11
+ <Popover visible {$props.callback}>
12
+ <PopoverContent>
13
+ <Dialog>
14
+ <DialogBody>
15
+ <p>Which color do you prefer?</p>
16
+ </DialogBody>
17
+ <DialogFooter>
18
+ <DialogButton value="blue">Blue</DialogButton>
19
+ <DialogButton value="red">Red</DialogButton>
20
+ </DialogFooter>
21
+ </Dialog>
22
+ </PopoverContent>
23
+ </Popover>
24
+ }
25
+ }
@@ -0,0 +1,19 @@
1
+ import { showPopover } from "../../../src/Popover/index";
2
+ import CustomDialog from "./CustomDialog.torp";
3
+
4
+ export default function PromptFunction() {
5
+ let anchor;
6
+ let $state = $watch({ color: "" });
7
+
8
+ async function show() {
9
+ showPopover(CustomDialog, anchor, { callback: (x) => $state.color = x });
10
+ }
11
+
12
+ @render {
13
+ <button type="button" &ref={anchor} onclick={show}>Show the prompt</button>
14
+
15
+ @if ($state.color) {
16
+ <p>Your favorite color is {$state.color}?!</p>
17
+ }
18
+ }
19
+ }
@@ -0,0 +1,38 @@
1
+ import { Popover, PopoverContent } from "../../../src/Popover/index";
2
+ import {
3
+ Dialog,
4
+ DialogBody,
5
+ DialogFooter,
6
+ DialogButton
7
+ } from "../../../src/Dialog/index";
8
+
9
+ export default function PromptVariable() {
10
+ let $state = $watch({
11
+ color: "",
12
+ showPopover: false
13
+ });
14
+
15
+ @render {
16
+ <button type="button" onclick={(e) => ($state.showPopover = !$state.showPopover)}>
17
+ Show the prompt
18
+ </button>
19
+
20
+ @if ($state.color) {
21
+ <p>Your favorite color is {$state.color}?!</p>
22
+ }
23
+
24
+ <Popover &visible={$state.showPopover}>
25
+ <PopoverContent>
26
+ <Dialog>
27
+ <DialogBody>
28
+ <p>Which color do you prefer?</p>
29
+ </DialogBody>
30
+ <DialogFooter>
31
+ <DialogButton value="blue" onclick={() => ($state.color = "blue")}>Blue</DialogButton>
32
+ <DialogButton value="red" onclick={() => ($state.color = "red")}>Red</DialogButton>
33
+ </DialogFooter>
34
+ </Dialog>
35
+ </PopoverContent>
36
+ </Popover>
37
+ }
38
+ }
@@ -0,0 +1,26 @@
1
+ import { getByText, queryByText } from "@testing-library/dom";
2
+ import "@testing-library/jest-dom/vitest";
3
+ import userEvent from "@testing-library/user-event";
4
+ import { mount } from "@torpor/view";
5
+ import { describe, expect, it } from "vitest";
6
+ import PromptFunction from "./components/PromptFunction.torp";
7
+
8
+ describe("Prompt", () => {
9
+ it("Showing with a function", async () => {
10
+ const container = document.createElement("div");
11
+ document.body.appendChild(container);
12
+ mount(container, PromptFunction);
13
+
14
+ // By default, the prompt shouldn't be shown
15
+ expect(queryByText(container, "Which color do you prefer?")).not.toBeInTheDocument();
16
+
17
+ // Clicking the button should show the prompt
18
+ await userEvent.click(getByText(container, "Show the prompt"));
19
+ expect(queryByText(container, "Which color do you prefer?")).toBeInTheDocument();
20
+
21
+ // Clicking the blue button should hide the prompt and set the value
22
+ await userEvent.click(getByText(container, "Blue"));
23
+ expect(queryByText(container, "Which color do you prefer?")).not.toBeInTheDocument();
24
+ expect(queryByText(container, "Your favorite color is blue?!")).toBeInTheDocument();
25
+ });
26
+ });
@@ -0,0 +1,27 @@
1
+ import { getByText, queryByText } from "@testing-library/dom";
2
+ import "@testing-library/jest-dom/vitest";
3
+ import userEvent from "@testing-library/user-event";
4
+ import { mount } from "@torpor/view";
5
+ import { describe, expect, it } from "vitest";
6
+ import PromptVariable from "./components/PromptVariable.torp";
7
+
8
+ describe("Prompt", () => {
9
+ it("Showing with a variable", async () => {
10
+ const container = document.createElement("div");
11
+ document.body.appendChild(container);
12
+ mount(container, PromptVariable);
13
+
14
+ // By default, the prompt shouldn't be shown
15
+ expect(queryByText(container, "Which color do you prefer?")).not.toBeInTheDocument();
16
+ expect(queryByText(container, "Your favorite color is blue?!")).not.toBeInTheDocument();
17
+
18
+ // Clicking the button should show the prompt
19
+ await userEvent.click(getByText(container, "Show the prompt"));
20
+ expect(queryByText(container, "Which color do you prefer?")).toBeInTheDocument();
21
+
22
+ // Clicking the blue button should hide the prompt and set the value
23
+ await userEvent.click(getByText(container, "Blue"));
24
+ expect(queryByText(container, "Which color do you prefer?")).not.toBeInTheDocument();
25
+ expect(queryByText(container, "Your favorite color is blue?!")).toBeInTheDocument();
26
+ });
27
+ });
package/tsup.config.ts CHANGED
@@ -8,15 +8,23 @@ type Config =
8
8
  export default defineConfig({
9
9
  entry: [
10
10
  "src/Accordion/index.ts",
11
+ "src/Breadcrumb/index.ts",
12
+ "src/Calendar/index.ts",
11
13
  "src/Dialog/index.ts",
14
+ "src/Disclosure/index.ts",
15
+ "src/Drawer/index.ts",
16
+ "src/Menu/index.ts",
17
+ "src/MenuBar/index.ts",
12
18
  "src/NavMenu/index.ts",
13
- "src/Offscreen/index.ts",
19
+ "src/Notification/index.ts",
14
20
  "src/Popover/index.ts",
15
21
  "src/TabGroup/index.ts",
16
- "src/motion.ts",
22
+ "src/form/index.ts",
23
+ "src/icons/index.ts",
24
+ "src/motion/index.ts",
17
25
  ],
18
- format: ["esm", "cjs"],
19
- dts: { entry: ["src/motion.ts"] },
26
+ format: "esm",
27
+ dts: { entry: ["src/motion/index.ts"] },
20
28
  clean: true,
21
29
  metafile: true,
22
30
  sourcemap: true,