monochrome 0.1.0 → 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.
package/README.md CHANGED
@@ -2,7 +2,9 @@
2
2
 
3
3
  Accessible UI component library. Best-in-class performance. HTML-first, React supported.
4
4
 
5
- <!-- badges -->![gzip](https://img.shields.io/badge/gzip-2.2kB-brightgreen) ![tests](https://img.shields.io/badge/tests-350_passing-brightgreen) ![WCAG](https://img.shields.io/badge/WCAG_2.2-AA-blue) ![license](https://img.shields.io/badge/license-MIT-blue)<!-- /badges -->
5
+ <!-- badges -->
6
+ ![gzip](https://img.shields.io/badge/gzip-2.2kB-brightgreen) ![tests](https://img.shields.io/badge/tests-350_passing-brightgreen) ![WCAG](https://img.shields.io/badge/WCAG_2.2-AA-blue) ![license](https://img.shields.io/badge/license-MIT-blue)
7
+ <!-- /badges -->
6
8
 
7
9
  ## Install
8
10
 
@@ -0,0 +1,2 @@
1
+ "use client";
2
+ import{createContext as Y,useContext as Z,useId as N}from"react";import{jsx as X}from"react/jsx-runtime";var m=(a,t)=>t?`${a}:${t}`:a,i=()=>X("script",{dangerouslySetInnerHTML:{__html:"document.currentScript.parentNode.setAttribute('hidden','until-found')"}});import{jsx as w,jsxs as A}from"react/jsx-runtime";var E=Y(null);function _(){let a=Z(E);if(!a)throw Error("Accordion components must be used within Accordion.Item");return a}function G({children:a,type:t,...b}){let f=N();return w("div",{...b,"data-mode":t??"single",id:`mcr:accordion:${f}`,children:a})}function F({children:a,open:t,disabled:b,...f}){let v=N();return w(E.Provider,{value:{baseId:v,open:t??!1,disabled:b??!1},children:w("div",{...f,children:a})})}function W({children:a,as:t,...b}){return w(t??"h3",{...b,children:a})}function R({children:a,...t}){let b=_(),f=b.baseId,v=b.open;return w("button",{...t,type:"button",id:`mct:accordion:${f}`,"aria-expanded":v,"aria-controls":`mcc:accordion:${f}`,"aria-disabled":b.disabled||void 0,children:a})}function M({children:a,...t}){let b=_(),f=b.baseId,v=b.open;return A("div",{...t,id:`mcc:accordion:${f}`,role:"region","aria-labelledby":`mct:accordion:${f}`,"aria-hidden":!v,hidden:v?void 0:!0,children:[!v&&w(i,{}),a]})}var k={Root:G,Item:F,Header:W,Trigger:R,Panel:M};import{createContext as O,useContext as n,useId as I}from"react";import{jsx as g,jsxs as r}from"react/jsx-runtime";var D=O(null);function P(){let a=n(D);if(!a)throw Error("Collapsible components must be used within Collapsible.Root");return a}function o({children:a,open:t,...b}){let f=I();return g(D.Provider,{value:{baseId:f,open:t??!1},children:g("div",{...b,children:a})})}function l({children:a,...t}){let b=P(),f=b.baseId,v=b.open;return g("button",{...t,type:"button",id:`mct:collapsible:${f}`,"aria-expanded":v,"aria-controls":`mcc:collapsible:${f}`,children:a})}function C({children:a,...t}){let b=P(),f=b.baseId,v=b.open;return r("div",{...t,id:`mcc:collapsible:${f}`,"aria-labelledby":`mct:collapsible:${f}`,"aria-hidden":!v,hidden:v?void 0:!0,children:[!v&&g(i,{}),a]})}var d={Root:o,Trigger:l,Panel:C};import{createContext as q,useContext as J,useId as K,useRef as h}from"react";import{jsx as u}from"react/jsx-runtime";var H=q(null),Q=q(null);function L(){let a=J(H);if(!a)throw Error("Menu components must be used within Menu.Root");return a}function j(){let a=J(Q);if(!a)throw Error("Menu components must be used within Menu.Popover");return a}function c({children:a,menubar:t,...b}){let f=K();return u(H.Provider,{value:{id:f,root:!0,menubar:t},children:u("div",{...b,id:`mcr:menu:${f}`,children:a})})}function s({children:a,...t}){let b=L();return u("button",{...t,type:"button",id:`mct:menu:${b.id}`,"aria-controls":`mcc:menu:${b.id}`,"aria-expanded":"false","aria-haspopup":"menu",tabIndex:b.root||b.first?0:-1,role:b.submenu?"menuitem":"button",children:a})}function e({children:a,...t}){let b=L(),f=h(!1);f.current=!1;let v=u(Q.Provider,{value:{claimFirst:()=>{if(!f.current)return f.current=!0,!0;return!1}},children:a});return b.menubar?u("ul",{...t,role:"menubar",children:v}):u("ul",{...t,role:"menu",id:`mcc:menu:${b.id}`,"aria-labelledby":`mct:menu:${b.id}`,"aria-hidden":"true",popover:"manual",children:v})}function x({children:a,disabled:t,href:b,...f}){return u("li",{role:"none",children:t?u("span",{...f,role:"menuitem","aria-disabled":"true",tabIndex:-1,children:a}):b?u("a",{...f,role:"menuitem",href:b,tabIndex:-1,children:a}):u("button",{...f,type:"button",role:"menuitem",tabIndex:-1,children:a})})}function p({children:a,checked:t,disabled:b,...f}){return u("li",{role:"none",children:b?u("span",{...f,role:"menuitemcheckbox","aria-checked":t??!1,"aria-disabled":"true",tabIndex:-1,children:a}):u("button",{...f,type:"button",role:"menuitemcheckbox","aria-checked":t??!1,tabIndex:-1,children:a})})}function aa({children:a,checked:t,disabled:b,...f}){return u("li",{role:"none",children:b?u("span",{...f,role:"menuitemradio","aria-checked":t??!1,"aria-disabled":"true",tabIndex:-1,children:a}):u("button",{...f,type:"button",role:"menuitemradio","aria-checked":t??!1,tabIndex:-1,children:a})})}function ta({children:a,...t}){return u("li",{...t,role:"presentation",children:a})}function ba(a){return u("li",{...a,role:"separator"})}function fa({children:a,...t}){let b=L(),v=j().claimFirst(),T=K(),y=v&&b.menubar&&!b.submenu;return u(H.Provider,{value:{id:T,submenu:!0,first:y},children:u("li",{...t,role:"none",children:a})})}var va={Root:c,Trigger:s,Popover:e,Item:x,CheckboxItem:p,RadioItem:aa,Label:ta,Separator:ba,Group:fa};import{createContext as ua,isValidElement as Ta,useContext as ya,useId as $a}from"react";import{jsx as V,jsxs as ma}from"react/jsx-runtime";var U=ua(null);function z(){let a=ya(U);if(!a)throw Error("Tabs components must be used within Tabs.Root");return a}function S(a){if(!a||typeof a!=="object")return;if(Ta(a)){let t=a.props;if(t.value!==void 0)return t.value;return S(t.children)}if(Array.isArray(a))for(let t of a){let b=S(t);if(b!==void 0)return b}}function ia({children:a,defaultValue:t,orientation:b,...f}){let v=$a(),T=b??"horizontal";return V(U.Provider,{value:{baseId:v,selected:t??S(a),orientation:T},children:V("div",{...f,"data-orientation":T,id:`mcr:tabs:${v}`,children:a})})}function wa({children:a,...t}){let b=z();return V("div",{...t,role:"tablist","aria-orientation":b.orientation,children:a})}function Ba({children:a,value:t,id:b,selected:f,disabled:v,...T}){let y=z(),B=m(y.baseId,b??t),$=f??t===y.selected;return V("button",{...T,type:"button",role:"tab",id:`mct:tabs:${B}`,"aria-selected":$,"aria-controls":`mcc:tabs:${B}`,tabIndex:$?0:-1,"aria-disabled":v||void 0,children:a})}function Va({children:a,value:t,id:b,selected:f,focusable:v=!0,...T}){let y=z(),B=m(y.baseId,b??t),$=f??t===y.selected;return ma("div",{...T,role:"tabpanel",id:`mcc:tabs:${B}`,"aria-labelledby":`mct:tabs:${B}`,"aria-hidden":!$,hidden:$?void 0:!0,tabIndex:v?$?0:-1:void 0,"data-orientation":y.orientation,children:[!$&&V(i,{}),a]})}var ga={Root:ia,List:wa,Tab:Ba,Panel:Va};export{ga as Tabs,va as Menu,d as Collapsible,k as Accordion};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "monochrome",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Accessible UI component library. Best-in-class performance. HTML-first, React supported.",
5
5
  "author": "Colin van Eenige",
6
6
  "license": "MIT",
@@ -10,9 +10,33 @@
10
10
  },
11
11
  "homepage": "https://github.com/vaneenige/monochrome-ui#readme",
12
12
  "bugs": "https://github.com/vaneenige/monochrome-ui/issues",
13
- "keywords": ["accessible", "a11y", "aria", "wai-aria", "ui", "component", "components", "component-library", "library", "headless", "unstyled", "lightweight", "keyboard-navigation", "html", "react", "typescript", "accordion", "collapsible", "menu", "tabs"],
13
+ "keywords": [
14
+ "accessible",
15
+ "a11y",
16
+ "aria",
17
+ "wai-aria",
18
+ "ui",
19
+ "component",
20
+ "components",
21
+ "component-library",
22
+ "library",
23
+ "headless",
24
+ "unstyled",
25
+ "lightweight",
26
+ "keyboard-navigation",
27
+ "html",
28
+ "react",
29
+ "typescript",
30
+ "accordion",
31
+ "collapsible",
32
+ "menu",
33
+ "tabs"
34
+ ],
14
35
  "type": "module",
15
- "sideEffects": ["./dist/index.js", "./src/index.ts"],
36
+ "sideEffects": [
37
+ "./dist/index.js",
38
+ "./src/index.ts"
39
+ ],
16
40
  "exports": {
17
41
  ".": {
18
42
  "types": "./src/index.ts",
@@ -21,17 +45,22 @@
21
45
  "./src": "./src/index.ts",
22
46
  "./react": {
23
47
  "types": "./src/react/index.ts",
24
- "default": "./src/react/index.ts"
48
+ "default": "./dist/react/index.js"
25
49
  }
26
50
  },
27
51
  "typesVersions": {
28
52
  "*": {
29
- "react": ["./src/react/index.ts"]
53
+ "react": [
54
+ "./src/react/index.ts"
55
+ ]
30
56
  }
31
57
  },
32
- "files": ["dist", "src"],
58
+ "files": [
59
+ "dist",
60
+ "src"
61
+ ],
33
62
  "scripts": {
34
- "build": "bun build.ts",
63
+ "build": "NODE_ENV=production bun build.ts",
35
64
  "test": "playwright test",
36
65
  "lint": "biome check src tests",
37
66
  "lint:fix": "biome check --write src tests",
@@ -58,5 +87,15 @@
58
87
  "@types/react-dom": "19.2.3",
59
88
  "react": "19.2.4",
60
89
  "react-dom": "19.2.4"
90
+ },
91
+ "versionMeta": {
92
+ "gzipSize": 2219,
93
+ "tests": {
94
+ "total": 350,
95
+ "collapsible": 41,
96
+ "accordion": 65,
97
+ "menu": 175,
98
+ "tabs": 69
99
+ }
61
100
  }
62
101
  }
@@ -1,498 +0,0 @@
1
- // src/index.ts
2
- if (typeof document !== "undefined") {
3
- let shouldPreventDefault = null;
4
- let shouldMatchLetter = null;
5
- let shouldResetRadio = null;
6
- let radioHeadDone = null;
7
- let radioTailChain = [];
8
- const menuPopovers = [];
9
- let rovingBoundary = null;
10
- let safeGroup = null;
11
- let safeRect = null;
12
- let safeDir = 0;
13
- const isElement = (el) => el instanceof HTMLElement;
14
- const isTrigger = (el, prefix) => el instanceof HTMLButtonElement && (!prefix || el.id.startsWith(prefix));
15
- const isMenuItem = (el) => isElement(el) && el.role?.startsWith("menuitem") === true && el.ariaDisabled !== "true";
16
- const getContent = (el) => document.getElementById(el.getAttribute("aria-controls") || "");
17
- const findAncestor = (el, prefix) => {
18
- while (el) {
19
- if (el.id.startsWith(prefix))
20
- return el;
21
- el = el.parentElement;
22
- }
23
- return null;
24
- };
25
- const roving = (focus) => {
26
- const next = (origin) => origin ? focus(origin.nextElementSibling || origin.parentElement?.firstElementChild, next) : null;
27
- const previous = (origin) => origin ? focus(origin.previousElementSibling || origin.parentElement?.lastElementChild, previous) : null;
28
- return [next, previous];
29
- };
30
- const menuRoving = (element, fallback) => {
31
- if (isElement(element)) {
32
- const menuitem = element.firstElementChild;
33
- if (shouldResetRadio) {
34
- if (isElement(menuitem)) {
35
- if (menuitem === shouldResetRadio) {
36
- for (const item of radioTailChain)
37
- item.ariaChecked = "false";
38
- return menuitem;
39
- }
40
- if (menuitem.role === "menuitemradio") {
41
- if (!radioHeadDone) {
42
- menuitem.ariaChecked = "false";
43
- } else {
44
- radioTailChain.push(menuitem);
45
- }
46
- return fallback(element);
47
- }
48
- }
49
- radioHeadDone = true;
50
- radioTailChain = [];
51
- return fallback(element);
52
- }
53
- if (isMenuItem(menuitem) && (!shouldMatchLetter || menuitem.textContent?.toLowerCase().startsWith(shouldMatchLetter))) {
54
- menuitem.focus();
55
- shouldPreventDefault = true;
56
- return menuitem;
57
- } else if (rovingBoundary !== element) {
58
- if (!rovingBoundary)
59
- rovingBoundary = element;
60
- return fallback(element);
61
- } else {
62
- rovingBoundary = null;
63
- }
64
- }
65
- return null;
66
- };
67
- const accordionRoving = (node, fallback) => {
68
- if (isElement(node)) {
69
- if (rovingBoundary === node)
70
- return null;
71
- if (!rovingBoundary)
72
- rovingBoundary = node;
73
- const trigger = node.firstElementChild?.firstElementChild;
74
- if (isTrigger(trigger, "mct:a" /* TriggerAccordion */)) {
75
- if (trigger.ariaDisabled === "true")
76
- return fallback(node);
77
- shouldPreventDefault = true;
78
- trigger.focus();
79
- return trigger;
80
- }
81
- }
82
- return fallback(node);
83
- };
84
- const tabsRoving = (node, fallback) => {
85
- if (isTrigger(node, "mct:t" /* TriggerTabs */)) {
86
- if (rovingBoundary === node)
87
- return null;
88
- if (!rovingBoundary)
89
- rovingBoundary = node;
90
- if (node.ariaDisabled === "true")
91
- return fallback(node);
92
- shouldPreventDefault = true;
93
- node.focus();
94
- return node;
95
- } else {
96
- return fallback(node);
97
- }
98
- };
99
- const [menuNext, menuPrevious] = roving(menuRoving);
100
- const [accordionNext, accordionPrevious] = roving(accordionRoving);
101
- const [tabNext, tabPrevious] = roving(tabsRoving);
102
- const collapsible = (trigger) => {
103
- const content = getContent(trigger);
104
- if (content) {
105
- const isOpen = trigger.ariaExpanded !== "true";
106
- trigger.ariaExpanded = isOpen ? "true" : "false";
107
- content.ariaHidden = isOpen ? "false" : "true";
108
- isOpen ? content.removeAttribute("hidden") : content.setAttribute("hidden", "until-found");
109
- }
110
- };
111
- const accordion = (trigger) => {
112
- if (trigger.ariaDisabled === "true")
113
- return;
114
- if (trigger.ariaExpanded === "true") {
115
- collapsible(trigger);
116
- } else {
117
- const root = findAncestor(trigger, "mcr:a" /* RootAccordion */);
118
- if (!root || root.getAttribute("data-mode") !== "single") {
119
- collapsible(trigger);
120
- } else {
121
- let item = root.firstElementChild;
122
- while (item) {
123
- const itemTrigger = item.firstElementChild?.firstElementChild;
124
- if (isElement(itemTrigger) && (itemTrigger === trigger || itemTrigger.ariaExpanded === "true")) {
125
- collapsible(itemTrigger);
126
- }
127
- item = item.nextElementSibling;
128
- }
129
- }
130
- }
131
- };
132
- const tabs = (trigger) => {
133
- if (trigger.ariaDisabled !== "true" && trigger.ariaSelected !== "true") {
134
- let tab = trigger.parentElement?.firstElementChild;
135
- while (isElement(tab)) {
136
- if (tab === trigger || tab.ariaSelected === "true") {
137
- const content = getContent(tab);
138
- if (content) {
139
- const isSelected = tab.ariaSelected !== "true";
140
- tab.ariaSelected = isSelected ? "true" : "false";
141
- tab.tabIndex = isSelected ? 0 : -1;
142
- content.ariaHidden = isSelected ? "false" : "true";
143
- if (content.hasAttribute("tabindex"))
144
- content.tabIndex = isSelected ? 0 : -1;
145
- isSelected ? content.removeAttribute("hidden") : content.setAttribute("hidden", "until-found");
146
- }
147
- }
148
- tab = tab.nextElementSibling;
149
- }
150
- }
151
- };
152
- const menu = (trigger, mode = 0 /* Trigger */) => {
153
- if (trigger?.id.startsWith("mct:m" /* TriggerMenu */)) {
154
- const content = getContent(trigger);
155
- if (content) {
156
- if (trigger.ariaExpanded === "true") {
157
- if (safeGroup)
158
- safeGroup.removeAttribute("data-safe");
159
- safeGroup = null;
160
- if (mode !== 3 /* None */)
161
- trigger.focus();
162
- content.hidePopover();
163
- trigger.ariaExpanded = "false";
164
- content.ariaHidden = "true";
165
- } else {
166
- menuPopovers.push(trigger);
167
- content.showPopover();
168
- trigger.ariaExpanded = "true";
169
- content.ariaHidden = "false";
170
- const rect = trigger.getBoundingClientRect();
171
- content.style.setProperty("--top", `${rect.top}px`);
172
- content.style.setProperty("--right", `${rect.right}px`);
173
- content.style.setProperty("--bottom", `${rect.bottom}px`);
174
- content.style.setProperty("--left", `${rect.left}px`);
175
- const group = trigger.parentElement;
176
- if (group) {
177
- const cr = content.getBoundingClientRect();
178
- const right = cr.left > rect.right;
179
- const sx = right ? cr.left : cr.right;
180
- safeGroup = group;
181
- safeRect = rect;
182
- safeDir = right ? -4 : 4;
183
- group.style.setProperty("--right", `${sx}px`);
184
- group.style.setProperty("--top", `${cr.top}px`);
185
- group.style.setProperty("--bottom", `${cr.bottom}px`);
186
- }
187
- if (mode === 0 /* Trigger */) {
188
- trigger.focus();
189
- } else if (mode === 1 /* First */) {
190
- menuRoving(content.firstElementChild, menuNext);
191
- } else if (mode === 2 /* Last */) {
192
- menuRoving(content.lastElementChild, menuPrevious);
193
- }
194
- }
195
- }
196
- }
197
- };
198
- const menuHideAll = (keep = 0) => {
199
- while (menuPopovers[keep])
200
- menu(menuPopovers.pop(), 3 /* None */);
201
- };
202
- const menuItemAction = (el) => {
203
- if (el.role === "menuitemcheckbox") {
204
- el.ariaChecked = el.ariaChecked === "true" ? "false" : "true";
205
- } else if (el.role === "menuitemradio") {
206
- shouldResetRadio = el;
207
- radioHeadDone = null;
208
- radioTailChain = [];
209
- menuNext(el.parentElement);
210
- shouldResetRadio = null;
211
- el.ariaChecked = "true";
212
- } else {
213
- menuHideAll();
214
- }
215
- };
216
- addEventListener("click", (event) => {
217
- shouldPreventDefault = null;
218
- const keyboard = event.detail === 0;
219
- const start = isElement(event.target) ? event.target : event.target instanceof Element ? event.target.parentElement : null;
220
- if (start) {
221
- let target = start;
222
- while (target) {
223
- const id = target.id;
224
- if (id.startsWith("mct:" /* Trigger */)) {
225
- if (id.startsWith("mct:m" /* TriggerMenu */)) {
226
- const focusMode = keyboard ? 1 /* First */ : 3 /* None */;
227
- const inPopover = findAncestor(target.parentElement, "mcc:m" /* ContentMenu */);
228
- if (inPopover) {
229
- if (!menuPopovers.includes(target))
230
- menu(target, focusMode);
231
- } else {
232
- if (menuPopovers[0]) {
233
- const openTarget = target !== menuPopovers[0];
234
- menuHideAll();
235
- if (openTarget)
236
- menu(target, focusMode);
237
- } else {
238
- menu(target, focusMode);
239
- }
240
- }
241
- } else {
242
- if (menuPopovers[0])
243
- menuHideAll();
244
- if (id.startsWith("mct:a" /* TriggerAccordion */))
245
- accordion(target);
246
- else if (id.startsWith("mct:c" /* TriggerCollapsible */))
247
- collapsible(target);
248
- else if (id.startsWith("mct:t" /* TriggerTabs */))
249
- tabs(target);
250
- }
251
- break;
252
- } else if (id.startsWith("mcc:m" /* ContentMenu */) && menuPopovers[0]) {
253
- let el = start;
254
- while (el && el !== target) {
255
- if (isMenuItem(el) && !isTrigger(el, "mct:m" /* TriggerMenu */)) {
256
- menuItemAction(el);
257
- break;
258
- }
259
- el = el.parentElement;
260
- }
261
- break;
262
- }
263
- target = target.parentElement;
264
- }
265
- if (!target && menuPopovers[0])
266
- menuHideAll();
267
- }
268
- if (shouldPreventDefault)
269
- event.preventDefault();
270
- });
271
- addEventListener("pointermove", (event) => {
272
- if (event.pointerType === "touch")
273
- return;
274
- if (menuPopovers[0]) {
275
- if (menuPopovers[1] && safeGroup && safeRect) {
276
- if (event.clientX >= safeRect.left && event.clientX <= safeRect.right && event.clientY >= safeRect.top && event.clientY <= safeRect.bottom) {
277
- safeGroup.style.setProperty("--left", `${event.clientX + safeDir}px`);
278
- safeGroup.style.setProperty("--center", `${event.clientY}px`);
279
- if (!safeGroup.hasAttribute("data-safe"))
280
- safeGroup.setAttribute("data-safe", "");
281
- } else if (safeGroup.hasAttribute("data-safe") && (event.target !== safeGroup || safeDir * event.movementX > 0)) {
282
- safeGroup.removeAttribute("data-safe");
283
- }
284
- }
285
- const el = event.target;
286
- if (isElement(el)) {
287
- const popoverTriggers = [];
288
- let target = el;
289
- let bail = false;
290
- let foundItem = false;
291
- while (target) {
292
- if (isMenuItem(target)) {
293
- foundItem = true;
294
- }
295
- if (!foundItem && target.id.startsWith("mcc:" /* Content */)) {
296
- bail = true;
297
- break;
298
- }
299
- const firstChild = target.firstElementChild;
300
- if (isTrigger(firstChild, "mct:m" /* TriggerMenu */)) {
301
- popoverTriggers.unshift(firstChild);
302
- }
303
- target = target.parentElement;
304
- }
305
- if (!bail && popoverTriggers[0]) {
306
- let i = 0;
307
- while (menuPopovers[i] && menuPopovers[i] === popoverTriggers[i])
308
- i++;
309
- if (i === 0 && popoverTriggers[0].role !== "menuitem")
310
- return;
311
- menuHideAll(i);
312
- menu(popoverTriggers[i], 3 /* None */);
313
- }
314
- }
315
- }
316
- });
317
- addEventListener("keydown", (event) => {
318
- shouldPreventDefault = null;
319
- shouldMatchLetter = null;
320
- rovingBoundary = null;
321
- const target = event.target;
322
- if (isTrigger(target, "mct:a" /* TriggerAccordion */)) {
323
- const item = target.parentElement?.parentElement;
324
- if (item) {
325
- switch (event.key) {
326
- case "ArrowDown":
327
- accordionNext(item);
328
- break;
329
- case "ArrowUp":
330
- accordionPrevious(item);
331
- break;
332
- case "Home": {
333
- const root = item.parentElement;
334
- if (root)
335
- accordionRoving(root.firstElementChild, accordionNext);
336
- break;
337
- }
338
- case "End": {
339
- const root = item.parentElement;
340
- if (root)
341
- accordionRoving(root.lastElementChild, accordionPrevious);
342
- break;
343
- }
344
- }
345
- }
346
- } else if (isTrigger(target, "mct:t" /* TriggerTabs */)) {
347
- const vertical = target.parentElement?.ariaOrientation === "vertical";
348
- switch (event.key) {
349
- case "ArrowDown":
350
- if (vertical)
351
- tabNext(target);
352
- break;
353
- case "ArrowUp":
354
- if (vertical)
355
- tabPrevious(target);
356
- break;
357
- case "ArrowRight":
358
- if (!vertical)
359
- tabNext(target);
360
- break;
361
- case "ArrowLeft":
362
- if (!vertical)
363
- tabPrevious(target);
364
- break;
365
- case "Home":
366
- tabsRoving(target.parentElement?.firstElementChild, tabNext);
367
- break;
368
- case "End":
369
- tabsRoving(target.parentElement?.lastElementChild, tabPrevious);
370
- break;
371
- }
372
- } else {
373
- if (isTrigger(target, "mct:m" /* TriggerMenu */)) {
374
- const isRootTrigger = findAncestor(target, "mcc:m" /* ContentMenu */) === null;
375
- switch (event.key) {
376
- case "ArrowDown":
377
- if (isRootTrigger) {
378
- if (target.ariaExpanded !== "true") {
379
- menu(target, 1 /* First */);
380
- } else {
381
- const content = getContent(target);
382
- if (content)
383
- menuRoving(content.firstElementChild, menuNext);
384
- }
385
- }
386
- break;
387
- case "ArrowUp":
388
- if (isRootTrigger) {
389
- if (target.ariaExpanded !== "true") {
390
- menu(target, 2 /* Last */);
391
- } else {
392
- const content = getContent(target);
393
- if (content)
394
- menuRoving(content.lastElementChild, menuPrevious);
395
- }
396
- }
397
- break;
398
- case "ArrowRight":
399
- if (!isRootTrigger)
400
- menu(target, 1 /* First */);
401
- break;
402
- }
403
- }
404
- if (!shouldPreventDefault && isElement(target) && target.role?.startsWith("menuitem") && target.parentElement) {
405
- const parent = target.parentElement;
406
- const menubarRoot = menuPopovers[0]?.parentElement || parent;
407
- const inPopover = findAncestor(target.parentElement, "mcc:m" /* ContentMenu */);
408
- switch (event.key) {
409
- case "Tab":
410
- if (menuPopovers[0])
411
- menuPopovers[0].focus();
412
- menuHideAll();
413
- break;
414
- case "ArrowDown":
415
- if (inPopover)
416
- menuNext(parent);
417
- break;
418
- case "ArrowUp":
419
- if (inPopover)
420
- menuPrevious(parent);
421
- break;
422
- case "ArrowRight": {
423
- const nextNode = menuNext(menubarRoot);
424
- if (nextNode) {
425
- const hadOpenMenu = menuPopovers[0];
426
- menuHideAll();
427
- if (hadOpenMenu && isTrigger(nextNode, "mct:m" /* TriggerMenu */)) {
428
- menu(nextNode, 3 /* None */);
429
- }
430
- }
431
- break;
432
- }
433
- case "ArrowLeft":
434
- if (menuPopovers[1]) {
435
- menu(menuPopovers.pop(), 0 /* Trigger */);
436
- } else {
437
- const nextNode = menuPrevious(menubarRoot);
438
- if (nextNode) {
439
- const hadOpenMenu = menuPopovers[0];
440
- menuHideAll();
441
- if (hadOpenMenu && isTrigger(nextNode, "mct:m" /* TriggerMenu */)) {
442
- menu(nextNode, 3 /* None */);
443
- }
444
- }
445
- }
446
- break;
447
- case "Home":
448
- menuRoving(parent.parentElement?.firstElementChild, menuNext);
449
- break;
450
- case "End":
451
- menuRoving(parent.parentElement?.lastElementChild, menuPrevious);
452
- break;
453
- default:
454
- if (/^[a-zA-Z]$/.test(event.key)) {
455
- shouldMatchLetter = event.key.toLowerCase();
456
- menuNext(parent);
457
- }
458
- break;
459
- }
460
- }
461
- }
462
- if (event.key === "Escape" && menuPopovers[0]) {
463
- menu(menuPopovers.pop(), 0 /* Trigger */);
464
- }
465
- if (shouldPreventDefault)
466
- event.preventDefault();
467
- });
468
- addEventListener("scroll", (event) => {
469
- if (menuPopovers[0] && (!isElement(event.target) || !event.target.id.startsWith("mcc:m" /* ContentMenu */))) {
470
- menuHideAll();
471
- }
472
- }, true);
473
- addEventListener("resize", () => {
474
- if (menuPopovers[0])
475
- menuHideAll();
476
- });
477
- addEventListener("beforematch", (event) => {
478
- if (isElement(event.target)) {
479
- let target = event.target;
480
- while (target) {
481
- const triggerId = target.getAttribute("aria-labelledby");
482
- if (triggerId) {
483
- const trigger = document.getElementById(triggerId);
484
- if (isTrigger(trigger, "mct:a" /* TriggerAccordion */)) {
485
- if (trigger.ariaExpanded !== "true")
486
- accordion(trigger);
487
- } else if (isTrigger(trigger, "mct:c" /* TriggerCollapsible */)) {
488
- if (trigger.ariaExpanded !== "true")
489
- collapsible(trigger);
490
- } else if (isTrigger(trigger, "mct:t" /* TriggerTabs */)) {
491
- tabs(trigger);
492
- }
493
- }
494
- target = target.parentElement;
495
- }
496
- }
497
- });
498
- }