@torpor/ui 0.3.4 → 0.3.6

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 (226) hide show
  1. package/dist/Form/Form.torp +1 -0
  2. package/dist/metafile-esm.json +1 -1
  3. package/package.json +12 -9
  4. package/CHANGELOG.md +0 -338
  5. package/scripts/postbuild.ts +0 -127
  6. package/src/Accordion/Accordion.torp +0 -230
  7. package/src/Accordion/AccordionContent.torp +0 -46
  8. package/src/Accordion/AccordionHeader.torp +0 -45
  9. package/src/Accordion/AccordionItem.torp +0 -101
  10. package/src/Accordion/AccordionTrigger.torp +0 -70
  11. package/src/Accordion/AccordionTypes.ts +0 -36
  12. package/src/Accordion/index.ts +0 -7
  13. package/src/Breadcrumb/Breadcrumb.torp +0 -45
  14. package/src/Breadcrumb/BreadcrumbItem.torp +0 -30
  15. package/src/Breadcrumb/BreadcrumbSeparator.torp +0 -27
  16. package/src/Breadcrumb/index.ts +0 -5
  17. package/src/Calendar/Calendar.torp +0 -277
  18. package/src/Calendar/CalendarDay.torp +0 -78
  19. package/src/Calendar/CalendarTypes.ts +0 -22
  20. package/src/Calendar/index.ts +0 -4
  21. package/src/Contextual/Contextual.torp +0 -129
  22. package/src/Contextual/ContextualContent.torp +0 -112
  23. package/src/Contextual/ContextualTrigger.torp +0 -70
  24. package/src/Contextual/ContextualTypes.ts +0 -30
  25. package/src/Contextual/index.ts +0 -5
  26. package/src/Dialog/Dialog.torp +0 -136
  27. package/src/Dialog/DialogBody.torp +0 -44
  28. package/src/Dialog/DialogButton.torp +0 -66
  29. package/src/Dialog/DialogFooter.torp +0 -25
  30. package/src/Dialog/DialogHeader.torp +0 -45
  31. package/src/Dialog/DialogTypes.ts +0 -17
  32. package/src/Dialog/index.ts +0 -7
  33. package/src/Disclosure/Disclosure.torp +0 -82
  34. package/src/Disclosure/DisclosureContent.torp +0 -46
  35. package/src/Disclosure/DisclosureHeader.torp +0 -45
  36. package/src/Disclosure/DisclosureTrigger.torp +0 -47
  37. package/src/Disclosure/DisclosureTypes.ts +0 -13
  38. package/src/Disclosure/index.ts +0 -6
  39. package/src/Drawer/Drawer.torp +0 -127
  40. package/src/Drawer/DrawerContent.torp +0 -83
  41. package/src/Drawer/DrawerOverlay.torp +0 -42
  42. package/src/Drawer/DrawerTrigger.torp +0 -39
  43. package/src/Drawer/DrawerTypes.ts +0 -24
  44. package/src/Drawer/index.ts +0 -6
  45. package/src/Form/CheckBox.torp +0 -94
  46. package/src/Form/Field.torp +0 -95
  47. package/src/Form/File.torp +0 -102
  48. package/src/Form/Form.torp +0 -146
  49. package/src/Form/FormTypes.ts +0 -35
  50. package/src/Form/Hidden.torp +0 -25
  51. package/src/Form/Input.torp +0 -112
  52. package/src/Form/Label.torp +0 -35
  53. package/src/Form/Message.torp +0 -39
  54. package/src/Form/Option.torp +0 -28
  55. package/src/Form/Select.torp +0 -101
  56. package/src/Form/StandardSchemaV1.ts +0 -70
  57. package/src/Form/TextArea.torp +0 -105
  58. package/src/Form/index.ts +0 -13
  59. package/src/Menu/Menu.torp +0 -174
  60. package/src/Menu/MenuButton.torp +0 -74
  61. package/src/Menu/MenuCheck.torp +0 -89
  62. package/src/Menu/MenuGroup.torp +0 -31
  63. package/src/Menu/MenuIndicator.torp +0 -40
  64. package/src/Menu/MenuPopout.torp +0 -83
  65. package/src/Menu/MenuPopoutContent.torp +0 -84
  66. package/src/Menu/MenuPopoutTrigger.torp +0 -128
  67. package/src/Menu/MenuRadio.torp +0 -103
  68. package/src/Menu/MenuRadioGroup.torp +0 -109
  69. package/src/Menu/MenuSeparator.torp +0 -26
  70. package/src/Menu/MenuTypes.ts +0 -60
  71. package/src/Menu/index.ts +0 -25
  72. package/src/MenuBar/MenuBar.torp +0 -162
  73. package/src/MenuBar/MenuBarItem.torp +0 -116
  74. package/src/MenuBar/MenuBarItemContent.torp +0 -119
  75. package/src/MenuBar/MenuBarItemTrigger.torp +0 -99
  76. package/src/MenuBar/MenuBarTypes.ts +0 -36
  77. package/src/MenuBar/index.ts +0 -6
  78. package/src/Modal/Modal.torp +0 -122
  79. package/src/Modal/ModalContent.torp +0 -81
  80. package/src/Modal/ModalOverlay.torp +0 -42
  81. package/src/Modal/ModalTrigger.torp +0 -54
  82. package/src/Modal/ModalTypes.ts +0 -22
  83. package/src/Modal/index.ts +0 -10
  84. package/src/Modal/showModal.ts +0 -19
  85. package/src/Modal/showPrompt.ts +0 -23
  86. package/src/NavMenu/NavMenu.torp +0 -190
  87. package/src/NavMenu/NavMenuButton.torp +0 -55
  88. package/src/NavMenu/NavMenuElement.torp +0 -55
  89. package/src/NavMenu/NavMenuGroup.torp +0 -41
  90. package/src/NavMenu/NavMenuGroupHeader.torp +0 -41
  91. package/src/NavMenu/NavMenuLink.torp +0 -60
  92. package/src/NavMenu/NavMenuPopout.torp +0 -89
  93. package/src/NavMenu/NavMenuPopoutButton.torp +0 -129
  94. package/src/NavMenu/NavMenuPopoutContent.torp +0 -92
  95. package/src/NavMenu/NavMenuSeparator.torp +0 -24
  96. package/src/NavMenu/NavMenuTypes.ts +0 -32
  97. package/src/NavMenu/index.ts +0 -23
  98. package/src/Notification/Notification.torp +0 -71
  99. package/src/Notification/NotificationClose.torp +0 -39
  100. package/src/Notification/NotificationContainer.torp +0 -26
  101. package/src/Notification/NotificationContent.torp +0 -25
  102. package/src/Notification/NotificationTypes.ts +0 -5
  103. package/src/Notification/index.ts +0 -13
  104. package/src/Notification/showNotification.ts +0 -30
  105. package/src/Popover/Popover.torp +0 -129
  106. package/src/Popover/PopoverContent.torp +0 -117
  107. package/src/Popover/PopoverTrigger.torp +0 -62
  108. package/src/Popover/PopoverTypes.ts +0 -30
  109. package/src/Popover/index.ts +0 -6
  110. package/src/Popover/showPopover.ts +0 -24
  111. package/src/Slider/Slider.torp +0 -84
  112. package/src/Slider/index.ts +0 -3
  113. package/src/TabGroup/TabContent.torp +0 -49
  114. package/src/TabGroup/TabGroup.torp +0 -250
  115. package/src/TabGroup/TabGroupTypes.ts +0 -44
  116. package/src/TabGroup/TabHeader.torp +0 -81
  117. package/src/TabGroup/TabList.torp +0 -61
  118. package/src/TabGroup/TabTrigger.torp +0 -76
  119. package/src/TabGroup/index.ts +0 -7
  120. package/src/ambient.d.ts +0 -7
  121. package/src/icons/ArrowDown.torp +0 -18
  122. package/src/icons/ArrowLeft.torp +0 -18
  123. package/src/icons/ArrowRight.torp +0 -18
  124. package/src/icons/ArrowUp.torp +0 -18
  125. package/src/icons/Bars.torp +0 -20
  126. package/src/icons/Check.torp +0 -18
  127. package/src/icons/ChevronDown.torp +0 -18
  128. package/src/icons/ChevronLeft.torp +0 -18
  129. package/src/icons/ChevronRight.torp +0 -18
  130. package/src/icons/ChevronUp.torp +0 -18
  131. package/src/icons/Cross.torp +0 -19
  132. package/src/icons/IconTypes.ts +0 -10
  133. package/src/icons/Loading.torp +0 -19
  134. package/src/icons/Minus.torp +0 -18
  135. package/src/icons/Plus.torp +0 -19
  136. package/src/icons/index.ts +0 -31
  137. package/src/motion/fade.ts +0 -16
  138. package/src/motion/grow.ts +0 -23
  139. package/src/motion/index.ts +0 -6
  140. package/src/motion/measure.ts +0 -28
  141. package/src/motion/slide.ts +0 -45
  142. package/src/mount/clickPopover.ts +0 -51
  143. package/src/mount/contextPopover.ts +0 -51
  144. package/src/mount/disableScroll.ts +0 -28
  145. package/src/mount/hoverPopover.ts +0 -58
  146. package/src/mount/hoverTrigger.ts +0 -59
  147. package/src/mount/trapFocus.ts +0 -58
  148. package/src/utils/dateUtils.ts +0 -244
  149. package/src/utils/documentEvents.ts +0 -17
  150. package/src/utils/getId.ts +0 -6
  151. package/src/utils/getScrollParent.ts +0 -22
  152. package/src/utils/setContextPosition.ts +0 -31
  153. package/src/utils/setPopoverPosition.ts +0 -142
  154. package/test/Accordion/accessibility.test.ts +0 -59
  155. package/test/Accordion/components/AccordionAccessibility.torp +0 -44
  156. package/test/Accordion/components/AccordionKeyboard.torp +0 -32
  157. package/test/Accordion/components/AccordionList.torp +0 -23
  158. package/test/Accordion/components/AccordionMultiple.torp +0 -32
  159. package/test/Accordion/components/AccordionSingle.torp +0 -32
  160. package/test/Accordion/for-items.test.ts +0 -52
  161. package/test/Accordion/keyboard.test.ts +0 -64
  162. package/test/Accordion/multiple-item-toggle.test.ts +0 -32
  163. package/test/Accordion/multiple-item-value.test.ts +0 -17
  164. package/test/Accordion/single-item-toggle.test.ts +0 -31
  165. package/test/Accordion/single-item-value.test.ts +0 -17
  166. package/test/Breadcrumb/accessibility.test.ts +0 -29
  167. package/test/Breadcrumb/basic.test.ts +0 -17
  168. package/test/Breadcrumb/components/BreadcrumbTest.torp +0 -15
  169. package/test/Calendar/components/CalendarTest.torp +0 -9
  170. package/test/Calendar/default.test.ts +0 -18
  171. package/test/Dialog/accessibility-alert.test.ts +0 -40
  172. package/test/Dialog/accessibility-modal.test.ts +0 -52
  173. package/test/Dialog/components/DialogAccessibility.torp +0 -25
  174. package/test/Dialog/components/DialogFunction.torp +0 -36
  175. package/test/Dialog/components/DialogModal.torp +0 -30
  176. package/test/Dialog/components/DialogVariable.torp +0 -33
  177. package/test/Dialog/function.test.ts +0 -26
  178. package/test/Dialog/variable.test.ts +0 -27
  179. package/test/Disclosure/accessibility.test.ts +0 -31
  180. package/test/Disclosure/components/DisclosureTest.torp +0 -17
  181. package/test/Disclosure/default.test.ts +0 -15
  182. package/test/Disclosure/toggle.test.ts +0 -20
  183. package/test/Form/components/FieldTest.torp +0 -25
  184. package/test/Form/components/FormTest.torp +0 -31
  185. package/test/Form/components/InputTest.torp +0 -9
  186. package/test/Form/field.test.ts +0 -34
  187. package/test/Form/form.test.ts +0 -34
  188. package/test/Form/input.test.ts +0 -19
  189. package/test/Menu/accessibility.test.ts +0 -83
  190. package/test/Menu/basic.test.ts +0 -58
  191. package/test/Menu/components/MenuAccessibility.torp +0 -59
  192. package/test/Menu/components/MenuBasic.torp +0 -58
  193. package/test/MenuBar/accessibility.test.ts +0 -87
  194. package/test/MenuBar/basic.test.ts +0 -22
  195. package/test/MenuBar/components/MenuBarAccessibility.torp +0 -34
  196. package/test/MenuBar/components/MenuBarBasic.torp +0 -25
  197. package/test/NavMenu/accessibility.test.ts +0 -97
  198. package/test/NavMenu/basic.test.ts +0 -22
  199. package/test/NavMenu/components/NavMenuAccessibility.torp +0 -35
  200. package/test/NavMenu/components/NavMenuBasic.torp +0 -28
  201. package/test/Notification/accessibility.test.ts +0 -21
  202. package/test/Notification/components/CustomNotification.torp +0 -14
  203. package/test/Notification/components/NotificationAccessibility.torp +0 -14
  204. package/test/Notification/components/NotificationFunction.torp +0 -17
  205. package/test/Notification/components/NotificationVariable.torp +0 -22
  206. package/test/Notification/function.test.ts +0 -25
  207. package/test/Notification/variable.test.ts +0 -25
  208. package/test/Popover/components/CustomDialog.torp +0 -25
  209. package/test/Popover/components/PopoverFunction.torp +0 -37
  210. package/test/Popover/components/PopoverTrigger.torp +0 -36
  211. package/test/Popover/components/PopoverVariable.torp +0 -40
  212. package/test/Popover/function.test.ts +0 -21
  213. package/test/Popover/trigger.test.ts +0 -27
  214. package/test/Popover/variable.test.ts +0 -27
  215. package/test/TabGroup/accessibility.test.ts +0 -67
  216. package/test/TabGroup/components/TabGroupAccessibility.torp +0 -28
  217. package/test/TabGroup/components/TabGroupKeyboard.torp +0 -28
  218. package/test/TabGroup/components/TabGroupList.torp +0 -26
  219. package/test/TabGroup/components/TabGroupTrigger.torp +0 -28
  220. package/test/TabGroup/for-items.test.ts +0 -52
  221. package/test/TabGroup/item-trigger.test.ts +0 -33
  222. package/test/TabGroup/item-value.test.ts +0 -17
  223. package/test/TabGroup/keyboard.test.ts +0 -72
  224. package/tsconfig.json +0 -4
  225. package/tsup.config.ts +0 -37
  226. package/vitest.config.ts +0 -12
@@ -1,244 +0,0 @@
1
- // TODO: Can we get these from the locale?
2
- const monthNames: string[] = [
3
- "January",
4
- "February",
5
- "March",
6
- "April",
7
- "May",
8
- "June",
9
- "July",
10
- "August",
11
- "September",
12
- "October",
13
- "November",
14
- "December",
15
- ];
16
- const shortMonthNames: string[] = monthNames.map((n) => n.substring(0, 3).toLowerCase());
17
-
18
- const dayNames: string[] = [
19
- "Sunday",
20
- "Monday",
21
- "Tuesday",
22
- "Wednesday",
23
- "Thursday",
24
- "Friday",
25
- "Saturday",
26
- "Sunday",
27
- ];
28
- const shortDayNames: string[] = dayNames.map((n) => n.substring(0, 3).toLowerCase());
29
-
30
- export { monthNames, shortMonthNames, dayNames, shortDayNames };
31
-
32
- export function areDatesEqual(date1: Date, date2: Date): boolean {
33
- if ((date1 && !date2) || (date2 && !date1)) {
34
- return false;
35
- }
36
- return (
37
- date1.getFullYear() === date2.getFullYear() &&
38
- date1.getMonth() === date2.getMonth() &&
39
- date1.getDate() === date2.getDate()
40
- );
41
- }
42
-
43
- export function parseDateTime(text: string, dateOrder: string): Date {
44
- const parts = text
45
- .toString()
46
- .toLowerCase()
47
- .split(/[.,/ :-]/);
48
-
49
- const today = new Date();
50
- let day = today.getDate();
51
- let month = today.getMonth();
52
- let year = today.getFullYear();
53
- let hour = 9;
54
- let minute = 0;
55
- //let ampm = "";
56
-
57
- let dayPart = -1;
58
- let monthPart = -1;
59
- let yearPart = -1;
60
- //let hourPart = -1;
61
-
62
- // Try to get the month if it's been supplied as a word
63
- for (let i = 0; i < parts.length; i++) {
64
- const index = shortMonthNames.indexOf(parts[i].substring(0, 3));
65
- if (index !== -1) {
66
- month = index;
67
- monthPart = i;
68
- break;
69
- }
70
- }
71
-
72
- // Get each date part based on the dateOrder supplied
73
- const dateOrderLower = dateOrder.toLowerCase();
74
- for (let i = 0; i < dateOrder.length; i++) {
75
- if (dateOrderLower[i] === "d") {
76
- const dayResult = getDayPart(parts, monthPart, yearPart);
77
- if (dayResult) {
78
- day = dayResult.value;
79
- dayPart = dayResult.part;
80
- }
81
- }
82
- if (dateOrderLower[i] === "m" && monthPart === -1) {
83
- const monthResult = getMonthPart(parts, dayPart, yearPart);
84
- if (monthResult) {
85
- month = monthResult.value;
86
- monthPart = monthResult.part;
87
- }
88
- }
89
- if (dateOrderLower[i] === "y") {
90
- const yearResult = getYearPart(parts, dayPart, monthPart);
91
- if (yearResult) {
92
- year = yearResult.value;
93
- yearPart = yearResult.part;
94
- }
95
- }
96
- }
97
-
98
- // TODO: Time...
99
- //if (includeTime) {
100
- // // Hour part is the first part that isn't a date part
101
- // for (let i = 0; i < parts.length; i++) {
102
- // if (i !== yearPart && i !== monthPart && i !== dayPart) {
103
- // const maybehour = parseInt(parts[i])
104
- // if (!isNaN(maybehour)) {
105
- // hour = maybehour
106
- // hourPart = i
107
- // break
108
- // }
109
- // }
110
- // }
111
- //
112
- // // Minute part is the first part that isn't a date part or the hour part
113
- // for (let i = 0; i < parts.length; i++) {
114
- // if (i !== yearPart && i !== monthPart && i !== dayPart && i !== hourPart) {
115
- // const maybeminute = parseInt(parts[i])
116
- // if (!isNaN(maybeminute)) {
117
- // minute = maybeminute
118
- // break
119
- // }
120
- // }
121
- // }
122
- //
123
- // // Look for AM or PM
124
- // for (let i = 0; i < parts.length; i++) {
125
- // if (parts[i] === 'am' || parts[i] === 'pm') {
126
- // ampm = parts[i].toString().toUpperCase()
127
- // if (ampm === 'PM') {
128
- // hour = hour + 12
129
- // }
130
- // break
131
- // }
132
- // }
133
- //}
134
-
135
- return new Date(year, month, day, hour, minute);
136
- }
137
-
138
- interface DatePart {
139
- value: number;
140
- part: number;
141
- }
142
-
143
- function getDayPart(parts: string[], monthPart: number, yearPart: number): DatePart | undefined {
144
- for (let i = 0; i < parts.length; i++) {
145
- if (i !== monthPart && i !== yearPart) {
146
- const maybeday = parseInt(parts[i]);
147
- if (!isNaN(maybeday)) {
148
- const value = maybeday;
149
- const part = i;
150
- return { value, part };
151
- }
152
- }
153
- }
154
- }
155
-
156
- function getMonthPart(parts: string[], dayPart: number, yearPart: number): DatePart | undefined {
157
- for (let i = 0; i < parts.length; i++) {
158
- if (i !== dayPart && i !== yearPart) {
159
- const maybemonth = parseInt(parts[i]);
160
- if (!isNaN(maybemonth)) {
161
- const value = maybemonth - 1;
162
- const part = i;
163
- return { value, part };
164
- }
165
- }
166
- }
167
- }
168
-
169
- function getYearPart(parts: string[], dayPart: number, monthPart: number): DatePart | undefined {
170
- for (let i = 0; i < parts.length; i++) {
171
- if (i !== monthPart && i !== dayPart) {
172
- const maybeyear = parseInt(parts[i]);
173
- if (!isNaN(maybeyear)) {
174
- const value = maybeyear < 100 ? maybeyear + 2000 : maybeyear;
175
- const part = i;
176
- return { value, part };
177
- }
178
- }
179
- }
180
- }
181
-
182
- export function formatDate(value: Date, dateFormat: string): string {
183
- if (!value) {
184
- return "";
185
- }
186
-
187
- const date = new Date(value);
188
-
189
- // Build the text that will be displayed
190
- return dateFormat.replace(/(d+)|(M+)|(y+)/g, (m) => {
191
- if (m.indexOf("d") >= 0) {
192
- return formatDay(date, m);
193
- } else if (m.indexOf("M") >= 0) {
194
- return formatMonth(date, m);
195
- } else if (m.indexOf("y") >= 0) {
196
- return formatYear(date, m);
197
- } else {
198
- throw new Error("Invalid date format string");
199
- }
200
- });
201
-
202
- // TODO: Time
203
- //if (includeTime) {
204
- // const ampm = hour >= 12 ? 'PM' : 'AM'
205
- // hour = hour % 12
206
- // hour = hour || 12 // the hour '0' should be '12'
207
- //
208
- // minute = minute < 10 ? '0' + minute : minute
209
- // text = text + ' ' + hour + ':' + minute + ' ' + ampm
210
- //}
211
- }
212
-
213
- function formatDay(date: Date, d: string): string {
214
- if (d.length >= 4) {
215
- return dayNames[date.getDay()];
216
- } else if (d.length === 3) {
217
- return dayNames[date.getDay()].substring(0, 3);
218
- } else if (d.length == 2) {
219
- let text = date.getDate().toString();
220
- return text.length < 2 ? "0" + text : text;
221
- } else {
222
- return date.getDate().toString();
223
- }
224
- }
225
-
226
- function formatMonth(date: Date, m: string): string {
227
- if (m.length >= 4) {
228
- return monthNames[date.getMonth()];
229
- } else if (m.length === 3) {
230
- return monthNames[date.getMonth()].substring(0, 3);
231
- } else if (m.length == 2) {
232
- let text = date.getMonth().toString();
233
- return text.length < 2 ? "0" + text : text;
234
- } else {
235
- return date.getMonth().toString();
236
- }
237
- }
238
-
239
- function formatYear(date: Date, y: string): string {
240
- return date
241
- .getFullYear()
242
- .toString()
243
- .substring(4 - y.length, y.length);
244
- }
@@ -1,17 +0,0 @@
1
- export function addDocumentEvent<K extends keyof DocumentEventMap>(
2
- type: K,
3
- listener: (this: Document, ev: DocumentEventMap[K]) => any
4
- ): void {
5
- if (typeof document !== 'undefined') {
6
- document.addEventListener(type, listener);
7
- }
8
- }
9
-
10
- export function removeDocumentEvent<K extends keyof DocumentEventMap>(
11
- type: K,
12
- listener: (this: Document, ev: DocumentEventMap[K]) => any
13
- ): void {
14
- if (typeof document !== 'undefined') {
15
- document.removeEventListener(type, listener);
16
- }
17
- }
@@ -1,6 +0,0 @@
1
- let nextId = 0;
2
-
3
- /** Returns a unique ID for use by components that need one, e.g. for accessibility */
4
- export default function getId(): string {
5
- return `torp-id-${nextId++}`;
6
- }
@@ -1,22 +0,0 @@
1
- // From https://stackoverflow.com/a/76535387
2
- export default function getScrollParent(node: Element): Element {
3
- let currentParent = node.parentElement;
4
- while (currentParent) {
5
- if (isScrollable(currentParent)) {
6
- return currentParent;
7
- }
8
- currentParent = currentParent.parentElement;
9
- }
10
- return document.scrollingElement || document.documentElement;
11
- }
12
-
13
- function isScrollable(node: Element): boolean {
14
- if (!(node instanceof HTMLElement || node instanceof SVGElement)) {
15
- return false;
16
- }
17
- const style = getComputedStyle(node);
18
- return ["overflow", "overflow-x", "overflow-y"].some((propertyName) => {
19
- const value = style.getPropertyValue(propertyName);
20
- return value === "auto" || value === "scroll";
21
- });
22
- }
@@ -1,31 +0,0 @@
1
- interface Point {
2
- x: number;
3
- y: number;
4
- }
5
-
6
- export default function setContextPosition(
7
- anchor: HTMLElement,
8
- content: HTMLElement,
9
- position: Point,
10
- ): void {
11
- var anchorRect = anchor.getBoundingClientRect();
12
- var contentRect = content.getBoundingClientRect();
13
-
14
- content.style.position = "fixed";
15
-
16
- // Try to make sure the content is entirely on the screen horizontally
17
- // Just move it left or right -- the pointer is outside the content vertically so moving it left
18
- // or right won't make the content appear over the cursor
19
- let left = anchorRect.left + position.x;
20
- left = Math.min(left, window.innerWidth - contentRect.width);
21
- left = Math.max(left, 0);
22
- content.style.left = left + "px";
23
-
24
- // Try to make sure the content is entirely on the screen vertically
25
- // Show it above the position if it wouldn't fit
26
- let top = anchorRect.top + position.y;
27
- if (top + contentRect.height > window.innerHeight) {
28
- top -= contentRect.height;
29
- }
30
- content.style.top = top + "px";
31
- }
@@ -1,142 +0,0 @@
1
- export default function setPopoverPosition(
2
- anchor: HTMLElement,
3
- content: HTMLElement,
4
- side: "top" | "right" | "bottom" | "left",
5
- alignment: "start" | "center" | "end",
6
- ): void {
7
- var anchorRect = anchor.getBoundingClientRect();
8
- var contentRect = content.getBoundingClientRect();
9
-
10
- content.style.position = "fixed";
11
-
12
- // Check that we there is enough room to show the content on the side requested
13
- // Otherwise, if there is enough room on the other side, show it there instead
14
- let calculatedSide = side;
15
- const canShowOnTop = anchorRect.top - contentRect.height >= 0;
16
- const canShowAtRight = anchorRect.right + contentRect.width <= window.innerWidth;
17
- const canShowOnBottom = anchorRect.bottom + contentRect.height <= window.innerHeight;
18
- const canShowAtLeft = anchorRect.left - contentRect.width >= 0;
19
- switch (side) {
20
- case "top": {
21
- if (!canShowOnTop && canShowOnBottom) {
22
- calculatedSide = "bottom";
23
- }
24
- break;
25
- }
26
- case "right": {
27
- if (!canShowAtRight && canShowAtLeft) {
28
- calculatedSide = "left";
29
- }
30
- break;
31
- }
32
- case "bottom": {
33
- if (!canShowOnBottom && canShowOnTop) {
34
- calculatedSide = "top";
35
- }
36
- break;
37
- }
38
- case "left": {
39
- if (!canShowAtLeft && canShowAtRight) {
40
- calculatedSide = "right";
41
- }
42
- break;
43
- }
44
- default: {
45
- // eslint-disable-next-line restrict-template-expressions
46
- throw new Error(`Invalid MenuPopout side: ${side}`);
47
- }
48
- }
49
-
50
- switch (calculatedSide) {
51
- case "top": {
52
- content.style.top = anchorRect.top - contentRect.height + "px";
53
- setVerticalAlignment(content, anchorRect, contentRect, alignment);
54
- break;
55
- }
56
- case "right": {
57
- content.style.left = anchorRect.right + "px";
58
- setHorizontalAlignment(content, anchorRect, contentRect, alignment);
59
- break;
60
- }
61
- case "bottom": {
62
- content.style.top = anchorRect.bottom + "px";
63
- setVerticalAlignment(content, anchorRect, contentRect, alignment);
64
- break;
65
- }
66
- case "left": {
67
- content.style.left = anchorRect.left - contentRect.width + "px";
68
- setHorizontalAlignment(content, anchorRect, contentRect, alignment);
69
- break;
70
- }
71
- default: {
72
- // eslint-disable-next-line restrict-template-expressions
73
- throw new Error(`Invalid MenuPopout side: ${side}`);
74
- }
75
- }
76
- }
77
-
78
- function setVerticalAlignment(
79
- content: HTMLElement,
80
- anchorRect: DOMRect,
81
- contentRect: DOMRect,
82
- alignment: "start" | "center" | "end",
83
- ) {
84
- let left = 0;
85
- switch (alignment) {
86
- case "start": {
87
- left = anchorRect.left;
88
- break;
89
- }
90
- case "center": {
91
- left = anchorRect.left + anchorRect.width / 2 - contentRect.width / 2;
92
- break;
93
- }
94
- case "end": {
95
- left = anchorRect.right - contentRect.width;
96
- break;
97
- }
98
- default: {
99
- // eslint-disable-next-line restrict-template-expressions
100
- throw new Error(`Invalid Popout alignment: ${alignment}`);
101
- }
102
- }
103
-
104
- // Try to make sure the content is entirely on the screen horizontally
105
- left = Math.min(left, window.innerWidth - contentRect.width);
106
- left = Math.max(left, 0);
107
-
108
- content.style.left = left + "px";
109
- }
110
-
111
- function setHorizontalAlignment(
112
- content: HTMLElement,
113
- anchorRect: DOMRect,
114
- contentRect: DOMRect,
115
- alignment: "start" | "center" | "end",
116
- ) {
117
- let top = 0;
118
- switch (alignment) {
119
- case "start": {
120
- top = anchorRect.top;
121
- break;
122
- }
123
- case "center": {
124
- top = anchorRect.top + anchorRect.height / 2 - contentRect.height / 2;
125
- break;
126
- }
127
- case "end": {
128
- top = anchorRect.bottom - contentRect.height;
129
- break;
130
- }
131
- default: {
132
- // eslint-disable-next-line restrict-template-expressions
133
- throw new Error(`Invalid Popout alignment: ${alignment}`);
134
- }
135
- }
136
-
137
- // Try to make sure the content is entirely on the screen vertically
138
- top = Math.min(top, window.innerHeight - contentRect.height);
139
- top = Math.max(top, 0);
140
-
141
- content.style.top = top + "px";
142
- }
@@ -1,59 +0,0 @@
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 AccordionAccessibility from "./components/AccordionAccessibility.torp";
6
-
7
- describe("Accordion", () => {
8
- it("Accessibility", async () => {
9
- const container = document.createElement("div");
10
- document.body.appendChild(container);
11
- mount(container, AccordionAccessibility, { value: ["1", "3"] });
12
-
13
- // Tests from https://www.w3.org/WAI/ARIA/apg/patterns/accordion/
14
-
15
- // The title of each accordion header is contained in an element with role button
16
- expect(queryByText(container, "Role Header")?.tagName.toLowerCase()).toMatch("button");
17
-
18
- // Each accordion header button is wrapped in an element with role heading that has a value set
19
- // for aria-level that is appropriate for the information architecture of the page
20
- // * If the native host language has an element with an implicit heading and aria-level, such
21
- // as an HTML heading tag, a native host language element may be used
22
- // * The button element is the only element inside the heading element. That is, if there are
23
- // other visually persistent elements, they are not included inside the heading element
24
- // NOTE: This is kind of up to the user -- should we check this at runtime?
25
- expect(queryByText(container, "Role Header")?.parentElement?.tagName.toLowerCase()).toMatch(
26
- "h4",
27
- );
28
- expect(
29
- queryByText(container, "Role Header")?.parentElement?.childElementCount.toString(),
30
- ).toMatch("1");
31
-
32
- // If the accordion panel associated with an accordion header is visible, the header button
33
- // element has aria-expanded set to true. If the panel is not visible, aria-expanded is set
34
- // to false
35
- expect(queryByText(container, "Open Header")).toHaveAttribute("aria-expanded", "true");
36
- expect(queryByText(container, "Closed Header")).toHaveAttribute("aria-expanded", "false");
37
-
38
- // The accordion header button element has aria-controls set to the ID of the element containing
39
- // the accordion panel content
40
- const headerId = queryByText(container, "Open Header")?.id;
41
- const contentId = queryByText(container, "Open Content")?.id;
42
- expect(queryByText(container, "Open Header")).toHaveAttribute("aria-controls", contentId);
43
-
44
- // If the accordion panel associated with an accordion header is visible, and if the accordion
45
- // does not permit the panel to be collapsed, the header button element has aria-disabled set
46
- // to true
47
- expect(queryByText(container, "Disabled Header")).toHaveAttribute("aria-disabled", "true");
48
-
49
- // Optionally, each element that serves as a container for panel content has role region and
50
- // aria-labelledby with a value that refers to the button that controls display of the panel
51
- // * Avoid using the region role in circumstances that create landmark region proliferation,
52
- // e.g., in an accordion that contains more than approximately 6 panels that can be expanded
53
- // at the same time
54
- // * Role region is especially helpful to the perception of structure by screen reader users
55
- // when panels contain heading elements or a nested accordion
56
- expect(queryByText(container, "Open Content")).toHaveAttribute("aria-labelledby", headerId);
57
- expect(queryByText(container, "Region Content")).toHaveAttribute("role", "region");
58
- });
59
- });
@@ -1,44 +0,0 @@
1
- import {
2
- Accordion,
3
- AccordionItem,
4
- AccordionHeader,
5
- AccordionTrigger,
6
- AccordionContent,
7
- } from "../../../src/Accordion/index";
8
-
9
- export default function AccordionAccessibility($props: any) {
10
- @render {
11
- <Accordion value={$props.value} type="multiple">
12
- <AccordionItem>
13
- <AccordionHeader as="h4">
14
- <AccordionTrigger>Role Header</AccordionTrigger>
15
- </AccordionHeader>
16
- <AccordionContent>Role Content</AccordionContent>
17
- </AccordionItem>
18
- <AccordionItem>
19
- <AccordionHeader as="h4">
20
- <AccordionTrigger>Open Header</AccordionTrigger>
21
- </AccordionHeader>
22
- <AccordionContent>Open Content</AccordionContent>
23
- </AccordionItem>
24
- <AccordionItem>
25
- <AccordionHeader as="h4">
26
- <AccordionTrigger>Closed Header</AccordionTrigger>
27
- </AccordionHeader>
28
- <AccordionContent>Closed Content</AccordionContent>
29
- </AccordionItem>
30
- <AccordionItem>
31
- <AccordionHeader as="h4">
32
- <AccordionTrigger>Region Header</AccordionTrigger>
33
- </AccordionHeader>
34
- <AccordionContent ariaRegion>Region Content</AccordionContent>
35
- </AccordionItem>
36
- <AccordionItem disabled>
37
- <AccordionHeader as="h4">
38
- <AccordionTrigger>Disabled Header</AccordionTrigger>
39
- </AccordionHeader>
40
- <AccordionContent>Disabled Content</AccordionContent>
41
- </AccordionItem>
42
- </Accordion>
43
- }
44
- }
@@ -1,32 +0,0 @@
1
- import {
2
- Accordion,
3
- AccordionItem,
4
- AccordionHeader,
5
- AccordionTrigger,
6
- AccordionContent,
7
- } from "../../../src/Accordion/index";
8
-
9
- export default function AccordionKeyboard($props: any) {
10
- @render {
11
- <Accordion value={$props.value} type="multiple">
12
- <AccordionItem>
13
- <AccordionHeader as="h4">
14
- <AccordionTrigger>Header 1</AccordionTrigger>
15
- </AccordionHeader>
16
- <AccordionContent>Content 1</AccordionContent>
17
- </AccordionItem>
18
- <AccordionItem>
19
- <AccordionHeader as="h4">
20
- <AccordionTrigger>Header 2</AccordionTrigger>
21
- </AccordionHeader>
22
- <AccordionContent>Content 2</AccordionContent>
23
- </AccordionItem>
24
- <AccordionItem>
25
- <AccordionHeader as="h4">
26
- <AccordionTrigger>Header 3</AccordionTrigger>
27
- </AccordionHeader>
28
- <AccordionContent>Content 3</AccordionContent>
29
- </AccordionItem>
30
- </Accordion>
31
- }
32
- }
@@ -1,23 +0,0 @@
1
- import {
2
- Accordion,
3
- AccordionItem,
4
- AccordionHeader,
5
- AccordionTrigger,
6
- AccordionContent,
7
- } from "../../../src/Accordion/index";
8
-
9
- export default function AccordionList($props: any) {
10
- @render {
11
- <Accordion value={$props.value}>
12
- @for (let item of $props.items) {
13
- @key = item.id
14
- <AccordionItem>
15
- <AccordionHeader as="h4">
16
- <AccordionTrigger>{item.header}</AccordionTrigger>
17
- </AccordionHeader>
18
- <AccordionContent>{item.text}</AccordionContent>
19
- </AccordionItem>
20
- }
21
- </Accordion>
22
- }
23
- }
@@ -1,32 +0,0 @@
1
- import {
2
- Accordion,
3
- AccordionItem,
4
- AccordionHeader,
5
- AccordionTrigger,
6
- AccordionContent,
7
- } from "../../../src/Accordion/index";
8
-
9
- export default function AccordionMultiple($props: any) {
10
- @render {
11
- <Accordion value={$props?.value} type="multiple">
12
- <AccordionItem>
13
- <AccordionHeader as="h4">
14
- <AccordionTrigger>Header 1</AccordionTrigger>
15
- </AccordionHeader>
16
- <AccordionContent>Content 1</AccordionContent>
17
- </AccordionItem>
18
- <AccordionItem>
19
- <AccordionHeader as="h4">
20
- <AccordionTrigger>Header 2</AccordionTrigger>
21
- </AccordionHeader>
22
- <AccordionContent>Content 2</AccordionContent>
23
- </AccordionItem>
24
- <AccordionItem>
25
- <AccordionHeader as="h4">
26
- <AccordionTrigger>Header 3</AccordionTrigger>
27
- </AccordionHeader>
28
- <AccordionContent>Content 3</AccordionContent>
29
- </AccordionItem>
30
- </Accordion>
31
- }
32
- }
@@ -1,32 +0,0 @@
1
- import {
2
- Accordion,
3
- AccordionItem,
4
- AccordionHeader,
5
- AccordionTrigger,
6
- AccordionContent,
7
- } from "../../../src/Accordion/index";
8
-
9
- export default function AccordionSingle($props: any) {
10
- @render {
11
- <Accordion value={$props?.value}>
12
- <AccordionItem>
13
- <AccordionHeader as="h4">
14
- <AccordionTrigger>Header 1</AccordionTrigger>
15
- </AccordionHeader>
16
- <AccordionContent>Content 1</AccordionContent>
17
- </AccordionItem>
18
- <AccordionItem>
19
- <AccordionHeader as="h4">
20
- <AccordionTrigger>Header 2</AccordionTrigger>
21
- </AccordionHeader>
22
- <AccordionContent>Content 2</AccordionContent>
23
- </AccordionItem>
24
- <AccordionItem>
25
- <AccordionHeader as="h4">
26
- <AccordionTrigger>Header 3</AccordionTrigger>
27
- </AccordionHeader>
28
- <AccordionContent>Content 3</AccordionContent>
29
- </AccordionItem>
30
- </Accordion>
31
- }
32
- }