ember-aria-voyager 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,155 @@
1
+ # ember-aria-voyager
2
+
3
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/6bd88c10540e66d94e2a/test_coverage)](https://codeclimate.com/github/hokulea/aria-voyager/test_coverage)
4
+ [![Maintainability](https://api.codeclimate.com/v1/badges/6bd88c10540e66d94e2a/maintainability)](https://codeclimate.com/github/hokulea/aria-voyager/maintainability)
5
+
6
+ _Canoe vessel that navigates your aria._
7
+
8
+ Ember reactivity bindings for [`aria-voyager`](https://github.com/hokulea/aria-voyager).
9
+
10
+ ## BYOM: Bring Your Own Markup
11
+
12
+ ... and this library will make it interactive, according to applicable [ARIA
13
+ patterns](https://www.w3.org/WAI/ARIA/apg/patterns/). This library does not
14
+ apply styling, it will operate on the accessibility tree.
15
+
16
+ ## Supported Features
17
+
18
+ See [`hokulea/aria-voyager`](https://github.com/hokulea/aria-voyager/) for a
19
+ full list of supported features.
20
+
21
+ ## Installation
22
+
23
+ ```sh
24
+ pnpm add ember-aria-voyager
25
+ ```
26
+
27
+ ## Usage
28
+
29
+ ### `{{listbox}}`
30
+
31
+ Basic example:
32
+
33
+ ```gts
34
+ import { listbox } from 'ember-aria-voyager';
35
+ const options = ['apple', 'banana', 'pineapple'];
36
+
37
+ <template>
38
+ <ul role="listbox" {{listbox items=options}}>
39
+ {{#each options as |option|}}
40
+ <li role="option">{{option}}</li>
41
+ {{/each}}
42
+ </ul>
43
+ </template>
44
+ ```
45
+
46
+ Here are the options, you can pass to `{{listbox}}`
47
+
48
+ ```ts
49
+ type ListboxSignature<T = HTMLElement> = {
50
+ items?: T[];
51
+ selection?: T | T[];
52
+ activateItem?: (item: T) => void;
53
+ } & (
54
+ | {
55
+ multi: true;
56
+ select?: (selection: T[]) => void;
57
+ }
58
+ | {
59
+ multi?: false;
60
+ select?: (selection: T) => void;
61
+ }
62
+ )
63
+ ```
64
+
65
+ When passing `items` the `select()` and `selection` can work off of your passed items, anyway will fall back to the HTMLElement
66
+
67
+ Full example:
68
+
69
+ ```gts
70
+ import { listbox } from 'ember-aria-voyager';
71
+ const options = ['apple', 'banana', 'pineapple'];
72
+ const context = new class {
73
+ @tracked selection = [options[0]];
74
+ @tracked disabled = false;
75
+
76
+ select: (fruits: string[]) => {
77
+ this.selection = fruits;
78
+ }
79
+ };
80
+
81
+ const selection = ['banana'];
82
+
83
+ <template>
84
+ <ul role="listbox" {{listbox
85
+ items=options
86
+ multi=true
87
+ disabled=context.disabled
88
+ selection=context.selection
89
+ select=context.select
90
+ }}>
91
+ {{#each options as |option|}}
92
+ <li role="option">{{option}}</li>
93
+ {{/each}}
94
+ </ul>
95
+ </template>
96
+ ```
97
+
98
+ ### `{{menu}}`
99
+
100
+ Basic example:
101
+
102
+ ```gts
103
+ import { menu } from 'ember-aria-voyager';
104
+
105
+ <template>
106
+ <div role="menu" {{menu}}>
107
+ <button role="menuitem">Version Info</button>
108
+ <a role="menuitem" href="https://github.com/hokulea/aria-voyager" target="_blank">Github</a>
109
+ <button role="menuitem" popovertarget="authormenu">Author</button>
110
+ <div role="menu" id="authormenu" popover {{menu}}>
111
+ <a role="menuitem" href="https://gos.si" target="_blank">Homepage</a>
112
+ <a role="menuitem" href="https://github.com" target="_blank">Github</a>
113
+ </div>
114
+ </div>
115
+ </template>
116
+ ```
117
+
118
+ Here are the options, you can pass to `{{menu}}`
119
+
120
+ ```ts
121
+ interface MenuSignature<T> {
122
+ items?: T[];
123
+ disabled?: boolean;
124
+ }
125
+ ```
126
+
127
+ Here is a full example:
128
+
129
+ ```gts
130
+ import { menu } from 'ember-aria-voyager';
131
+ const items = [
132
+ {
133
+ label: 'Version Info',
134
+ action: () => console.log('1.2.4');
135
+ },
136
+ {
137
+ label 'Github',
138
+ link: 'https://github.com/hokulea/aria-voyager'
139
+ }
140
+ ];
141
+
142
+ <template>
143
+ <div role="menu" {{menu items=items}}>
144
+ {{#each items as |item|}}
145
+ {{#if item.action}}
146
+ <button type="button" role="menuitem" {{on "click" item.action}}>{{item.label}}</button>
147
+ {{else if item.link}}
148
+ <a role="menuitem" href={{item.link}} target="_blank">{{item.label}}</a>
149
+ {{else}}
150
+ euw, what?
151
+ {{/if}}
152
+ {{/each}}
153
+ </div>
154
+ </template>
155
+ ```
package/addon-main.js ADDED
@@ -0,0 +1,5 @@
1
+ 'use strict';
2
+
3
+ const { addonV1Shim } = require('@embroider/addon-shim');
4
+
5
+ module.exports = addonV1Shim(__dirname);
@@ -0,0 +1 @@
1
+ export { default } from "ember-aria-voyager/modifiers/listbox";
@@ -0,0 +1 @@
1
+ export { default } from "ember-aria-voyager/modifiers/menu";
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { default as listbox } from './modifiers/listbox.js';
2
+ export { default as menu } from './modifiers/menu.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
@@ -0,0 +1,94 @@
1
+ import { ReactiveUpdateStrategy, Listbox, IndexEmitStrategy, ItemEmitStrategy } from 'aria-voyager';
2
+ import Modifier from 'ember-modifier';
3
+ import isEqual from 'lodash.isequal';
4
+
5
+ function asArray(val) {
6
+ if (val === undefined) {
7
+ return [];
8
+ }
9
+
10
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
11
+ return Array.isArray(val) ? val : [val];
12
+ }
13
+ function createItemEmitter(listbox, options) {
14
+ return new ItemEmitStrategy(listbox, {
15
+ select: selection => {
16
+ options.select?.(options.multi ? selection : selection[0]);
17
+ },
18
+ activateItem: item => {
19
+ options.activateItem?.(item);
20
+ }
21
+ });
22
+ }
23
+ function createIndexEmitter(listbox, options) {
24
+ const findByIndex = index => {
25
+ return options.items[index] ?? undefined;
26
+ };
27
+ return new IndexEmitStrategy(listbox, {
28
+ select: selection => {
29
+ if (options.multi) {
30
+ const items = selection.map(index => findByIndex(index)).filter(i => i !== undefined);
31
+ options.select?.(items);
32
+ } else {
33
+ const item = findByIndex(selection[0]);
34
+ if (item) {
35
+ options.select?.(item);
36
+ }
37
+ }
38
+ },
39
+ activateItem: index => {
40
+ const item = findByIndex(index);
41
+ if (item) {
42
+ options.activateItem?.(item);
43
+ }
44
+ }
45
+ });
46
+ }
47
+ class ListboxModifier extends Modifier {
48
+ modify(element, _, options) {
49
+ if (!this.listbox) {
50
+ this.updater = new ReactiveUpdateStrategy();
51
+ this.listbox = new Listbox(element, {
52
+ updater: this.updater
53
+ });
54
+ }
55
+ if (options.items && !(this.emitter instanceof IndexEmitStrategy)) {
56
+ this.emitter = createIndexEmitter(this.listbox, options);
57
+ } else if (!options.items && !(this.emitter instanceof ItemEmitStrategy)) {
58
+ this.emitter = createItemEmitter(this.listbox, options);
59
+ }
60
+ if (options.items && !isEqual(this.prevItems, options.items)) {
61
+ this.updater.updateItems();
62
+ this.prevItems = [...options.items];
63
+ }
64
+ if (options.selection && !isEqual(asArray(this.prevSelection), asArray(options.selection))) {
65
+ this.updater.updateSelection();
66
+ this.prevSelection = asArray(options.selection);
67
+ }
68
+ let optionsChanged = false;
69
+ if (this.prevMulti !== options.multi) {
70
+ if (options.multi) {
71
+ element.setAttribute('aria-multiselectable', 'true');
72
+ } else {
73
+ element.removeAttribute('aria-multiselectable');
74
+ }
75
+ optionsChanged = true;
76
+ this.prevMulti = options.multi;
77
+ }
78
+ if (this.prevDisabled !== options.disabled) {
79
+ if (options.disabled) {
80
+ element.setAttribute('aria-disabled', 'true');
81
+ } else {
82
+ element.removeAttribute('aria-disabled');
83
+ }
84
+ optionsChanged = true;
85
+ this.prevDisabled = options.disabled;
86
+ }
87
+ if (optionsChanged) {
88
+ this.updater.updateOptions();
89
+ }
90
+ }
91
+ }
92
+
93
+ export { ListboxModifier as default };
94
+ //# sourceMappingURL=listbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listbox.js","sources":["../../src/modifiers/listbox.ts"],"sourcesContent":["import { IndexEmitStrategy, ItemEmitStrategy, Listbox, ReactiveUpdateStrategy } from 'aria-voyager';\nimport Modifier from 'ember-modifier';\nimport isEqual from 'lodash.isequal';\n\nimport type { EmitStrategy } from 'aria-voyager';\nimport type { NamedArgs, PositionalArgs } from 'ember-modifier';\n\nfunction asArray(val?: unknown) {\n if (val === undefined) {\n return [];\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return Array.isArray(val) ? val : [val];\n}\n\nfunction createItemEmitter<T>(listbox: Listbox, options: NamedArgs<ListboxSignature<T>>) {\n return new ItemEmitStrategy(listbox, {\n select: (selection: HTMLElement[]) => {\n (options.select as ((selection: HTMLElement | HTMLElement[]) => void) | undefined)?.(\n options.multi ? selection : (selection[0] as HTMLElement)\n );\n },\n\n activateItem: (item: HTMLElement) => {\n (options.activateItem as ((item: HTMLElement) => void) | undefined)?.(item);\n }\n });\n}\n\nfunction createIndexEmitter<T>(listbox: Listbox, options: NamedArgs<ListboxSignature<T>>) {\n const findByIndex = (index: number) => {\n return (options as WithItems<T>).items[index] ?? undefined;\n };\n\n return new IndexEmitStrategy(listbox, {\n select: (selection: number[]) => {\n if (options.multi) {\n const items = selection\n .map((index) => findByIndex(index))\n .filter((i) => i !== undefined) as T[];\n\n (options.select as ((selection: T[]) => void) | undefined)?.(items);\n } else {\n const item = findByIndex(selection[0] as number);\n\n if (item) {\n (options.select as ((selection: T) => void) | undefined)?.(item);\n }\n }\n },\n\n activateItem: (index: number) => {\n const item = findByIndex(index);\n\n if (item) {\n (options.activateItem as ((item: T) => void) | undefined)?.(item);\n }\n }\n });\n}\n\ntype WithItems<T> = {\n items: T[];\n selection?: T | T[];\n activateItem?: (item: T) => void;\n} & (\n | {\n multi: true;\n select?: (selection: T[]) => void;\n }\n | {\n multi?: false;\n select?: (selection: T) => void;\n }\n);\n\ntype OptionalItems = {\n items?: HTMLElement[];\n selection?: HTMLElement | HTMLElement[];\n activateItem?: (item: HTMLElement) => void;\n} & (\n | {\n multi: true;\n select?: (selection: HTMLElement[]) => void;\n }\n | {\n multi?: false;\n select?: (selection: HTMLElement) => void;\n }\n);\n\ninterface ListboxSignature<T> {\n Args: {\n Positional: [];\n Named: { disabled?: boolean } & (WithItems<T> | OptionalItems);\n };\n}\n\nexport default class ListboxModifier<T> extends Modifier<ListboxSignature<T>> {\n private listbox?: Listbox;\n private declare updater: ReactiveUpdateStrategy;\n private declare emitter: EmitStrategy;\n\n private prevItems?: T[];\n private prevSelection?: T | T[];\n private prevMulti?: boolean;\n private prevDisabled?: boolean;\n\n modify(\n element: Element,\n _: PositionalArgs<ListboxSignature<T>>,\n options: NamedArgs<ListboxSignature<T>>\n ) {\n if (!this.listbox) {\n this.updater = new ReactiveUpdateStrategy();\n\n this.listbox = new Listbox(element as HTMLElement, {\n updater: this.updater\n });\n }\n\n if (options.items && !(this.emitter instanceof IndexEmitStrategy)) {\n this.emitter = createIndexEmitter<T>(this.listbox, options);\n } else if (!options.items && !(this.emitter instanceof ItemEmitStrategy)) {\n this.emitter = createItemEmitter<T>(this.listbox, options);\n }\n\n if (options.items && !isEqual(this.prevItems, (options as WithItems<T>).items)) {\n this.updater.updateItems();\n this.prevItems = [...(options as WithItems<T>).items];\n }\n\n if (options.selection && !isEqual(asArray(this.prevSelection), asArray(options.selection))) {\n this.updater.updateSelection();\n this.prevSelection = asArray(options.selection);\n }\n\n let optionsChanged = false;\n\n if (this.prevMulti !== options.multi) {\n if (options.multi) {\n element.setAttribute('aria-multiselectable', 'true');\n } else {\n element.removeAttribute('aria-multiselectable');\n }\n\n optionsChanged = true;\n\n this.prevMulti = options.multi;\n }\n\n if (this.prevDisabled !== options.disabled) {\n if (options.disabled) {\n element.setAttribute('aria-disabled', 'true');\n } else {\n element.removeAttribute('aria-disabled');\n }\n\n optionsChanged = true;\n\n this.prevDisabled = options.disabled;\n }\n\n if (optionsChanged) {\n this.updater.updateOptions();\n }\n }\n}\n"],"names":["asArray","val","undefined","Array","isArray","createItemEmitter","listbox","options","ItemEmitStrategy","select","selection","multi","activateItem","item","createIndexEmitter","findByIndex","index","items","IndexEmitStrategy","map","filter","i","ListboxModifier","Modifier","modify","element","_","updater","ReactiveUpdateStrategy","Listbox","emitter","isEqual","prevItems","updateItems","prevSelection","updateSelection","optionsChanged","prevMulti","setAttribute","removeAttribute","prevDisabled","disabled","updateOptions"],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import { ReactiveUpdateStrategy, Menu } from 'aria-voyager';
2
+ import Modifier from 'ember-modifier';
3
+ import isEqual from 'lodash.isequal';
4
+
5
+ class MenuModifier extends Modifier {
6
+ modify(element, _, options) {
7
+ if (!this.menu) {
8
+ this.updater = new ReactiveUpdateStrategy();
9
+ this.menu = new Menu(element, {
10
+ updater: this.updater
11
+ });
12
+ }
13
+ if (options.items && !isEqual(this.prevItems, options.items)) {
14
+ this.updater.updateItems();
15
+ this.prevItems = [...options.items];
16
+ }
17
+ let optionsChanged = false;
18
+ if (this.prevDisabled !== options.disabled) {
19
+ if (options.disabled) {
20
+ element.setAttribute('aria-disabled', 'true');
21
+ } else {
22
+ element.removeAttribute('aria-disabled');
23
+ }
24
+ optionsChanged = true;
25
+ this.prevDisabled = options.disabled;
26
+ }
27
+ if (optionsChanged) {
28
+ this.updater.updateOptions();
29
+ }
30
+ }
31
+ }
32
+
33
+ export { MenuModifier as default };
34
+ //# sourceMappingURL=menu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"menu.js","sources":["../../src/modifiers/menu.ts"],"sourcesContent":["import { Menu, ReactiveUpdateStrategy } from 'aria-voyager';\nimport Modifier from 'ember-modifier';\nimport isEqual from 'lodash.isequal';\n\nimport type { EmitStrategy } from 'aria-voyager';\nimport type { NamedArgs, PositionalArgs } from 'ember-modifier';\n\nexport interface MenuSignature<T> {\n Element: HTMLElement;\n Args: {\n Positional: [];\n Named: {\n items?: T[];\n disabled?: boolean;\n };\n };\n}\nexport default class MenuModifier<T> extends Modifier<MenuSignature<T>> {\n private menu?: Menu;\n private declare updater: ReactiveUpdateStrategy;\n private declare emitter: EmitStrategy;\n\n private prevItems?: T[];\n private prevDisabled?: boolean;\n\n modify(\n element: Element,\n _: PositionalArgs<MenuSignature<T>>,\n options: NamedArgs<MenuSignature<T>>\n ) {\n if (!this.menu) {\n this.updater = new ReactiveUpdateStrategy();\n\n this.menu = new Menu(element as HTMLElement, {\n updater: this.updater\n });\n }\n\n if (options.items && !isEqual(this.prevItems, options.items)) {\n this.updater.updateItems();\n this.prevItems = [...options.items];\n }\n\n let optionsChanged = false;\n\n if (this.prevDisabled !== options.disabled) {\n if (options.disabled) {\n element.setAttribute('aria-disabled', 'true');\n } else {\n element.removeAttribute('aria-disabled');\n }\n\n optionsChanged = true;\n\n this.prevDisabled = options.disabled;\n }\n\n if (optionsChanged) {\n this.updater.updateOptions();\n }\n }\n}\n"],"names":["MenuModifier","Modifier","modify","element","_","options","menu","updater","ReactiveUpdateStrategy","Menu","items","isEqual","prevItems","updateItems","optionsChanged","prevDisabled","disabled","setAttribute","removeAttribute","updateOptions"],"mappings":";;;;AAiBe,MAAMA,YAAY,SAAYC,QAAQ,CAAmB;AAQtEC,EAAAA,MAAMA,CACJC,OAAgB,EAChBC,CAAmC,EACnCC,OAAoC,EACpC;AACA,IAAA,IAAI,CAAC,IAAI,CAACC,IAAI,EAAE;AACd,MAAA,IAAI,CAACC,OAAO,GAAG,IAAIC,sBAAsB,EAAE,CAAA;AAE3C,MAAA,IAAI,CAACF,IAAI,GAAG,IAAIG,IAAI,CAACN,OAAO,EAAiB;QAC3CI,OAAO,EAAE,IAAI,CAACA,OAAAA;AAChB,OAAC,CAAC,CAAA;AACJ,KAAA;AAEA,IAAA,IAAIF,OAAO,CAACK,KAAK,IAAI,CAACC,OAAO,CAAC,IAAI,CAACC,SAAS,EAAEP,OAAO,CAACK,KAAK,CAAC,EAAE;AAC5D,MAAA,IAAI,CAACH,OAAO,CAACM,WAAW,EAAE,CAAA;MAC1B,IAAI,CAACD,SAAS,GAAG,CAAC,GAAGP,OAAO,CAACK,KAAK,CAAC,CAAA;AACrC,KAAA;IAEA,IAAII,cAAc,GAAG,KAAK,CAAA;AAE1B,IAAA,IAAI,IAAI,CAACC,YAAY,KAAKV,OAAO,CAACW,QAAQ,EAAE;MAC1C,IAAIX,OAAO,CAACW,QAAQ,EAAE;AACpBb,QAAAA,OAAO,CAACc,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,CAAA;AAC/C,OAAC,MAAM;AACLd,QAAAA,OAAO,CAACe,eAAe,CAAC,eAAe,CAAC,CAAA;AAC1C,OAAA;AAEAJ,MAAAA,cAAc,GAAG,IAAI,CAAA;AAErB,MAAA,IAAI,CAACC,YAAY,GAAGV,OAAO,CAACW,QAAQ,CAAA;AACtC,KAAA;AAEA,IAAA,IAAIF,cAAc,EAAE;AAClB,MAAA,IAAI,CAACP,OAAO,CAACY,aAAa,EAAE,CAAA;AAC9B,KAAA;AACF,GAAA;AACF;;;;"}
@@ -0,0 +1,2 @@
1
+
2
+ //# sourceMappingURL=template-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-registry.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,638 @@
1
+ import { getRootElement, triggerEvent, triggerKeyEvent, focus, click } from '@ember/test-helpers';
2
+ import { isDescriptor, lookupDescriptorData, resolveDOMElement } from 'dom-element-descriptors';
3
+ import sinon from 'sinon';
4
+
5
+ /**
6
+ Used internally by the DOM interaction helpers to get a description of a
7
+ target for debug/error messaging.
8
+
9
+ @private
10
+ @param {Target} target the target
11
+ @returns {string} a description of the target
12
+ */
13
+ function getDescription(target) {
14
+ let data = isDescriptor(target) ? lookupDescriptorData(target) : null;
15
+ if (data) {
16
+ return data.description || '<unknown descriptor>';
17
+ } else {
18
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
19
+ return target.toString();
20
+ }
21
+ }
22
+
23
+ // eslint-disable-next-line require-jsdoc
24
+ function isElement(target) {
25
+ return target !== null && typeof target === 'object' && Reflect.get(target, 'nodeType') === Node.ELEMENT_NODE;
26
+ }
27
+
28
+ // eslint-disable-next-line require-jsdoc
29
+ function isDocument(target) {
30
+ return target !== null && typeof target === 'object' && Reflect.get(target, 'nodeType') === Node.DOCUMENT_NODE;
31
+ }
32
+
33
+ /**
34
+ Used internally by the DOM interaction helpers to find one element.
35
+
36
+ @private
37
+ @param {string|Element} target the element or selector to retrieve
38
+ @returns {Element} the target or selector
39
+ */
40
+ function getElement(target) {
41
+ if (typeof target === 'string') {
42
+ let rootElement = getRootElement();
43
+ return rootElement.querySelector(target);
44
+ } else if (isElement(target) || isDocument(target)) {
45
+ return target;
46
+ } else if (target instanceof Window) {
47
+ return target.document;
48
+ } else {
49
+ let descriptorData = lookupDescriptorData(target);
50
+ if (descriptorData) {
51
+ return resolveDOMElement(descriptorData);
52
+ } else {
53
+ throw new Error('Must use an element, selector string, or DOM element descriptor');
54
+ }
55
+ }
56
+ }
57
+
58
+ function errorMessage(message, target, name) {
59
+ let description = getDescription(target);
60
+ return `${message} when calling \`${name}('${description}')\`.`;
61
+ }
62
+ function getOptions(parent, selector) {
63
+ return [...parent.querySelectorAll(selector)];
64
+ }
65
+ function findOption(target, text, {
66
+ selectors
67
+ }) {
68
+ if (!target) {
69
+ throw new Error(`Must pass an element, selector, or descriptor to \`findOption\`.`);
70
+ }
71
+
72
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
73
+ if (typeof text === 'undefined' || text === null) {
74
+ throw new Error(`Must provide an \`text\` to select when calling \`findOption\`.`);
75
+ }
76
+ const element = getElement(target);
77
+ if (!element) {
78
+ throw new Error(errorMessage('Element not found', target, 'findOption'));
79
+ }
80
+ return getOptions(element, selectors.option).find(e => e.textContent?.trim().includes(text));
81
+ }
82
+ function findOptions(target, texts, {
83
+ selectors
84
+ }) {
85
+ if (!target) {
86
+ throw new Error(`Must pass an element, selector, or descriptor to \`findOption\`.`);
87
+ }
88
+
89
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
90
+ if (typeof texts === 'undefined' || texts === null) {
91
+ throw new Error(`Must provide an \`texts\` to select when calling \`findOption\`.`);
92
+ }
93
+ const element = getElement(target);
94
+ if (!element) {
95
+ throw new Error(errorMessage('Element not found', target, 'findOption'));
96
+ }
97
+ return getOptions(element, selectors.option).filter(e => texts.includes(e.textContent?.trim()));
98
+ }
99
+ async function select(target, options, {
100
+ keepPreviouslySelected = false,
101
+ labels: {
102
+ name,
103
+ element: elementName
104
+ },
105
+ selectors
106
+ }) {
107
+ if (!target) {
108
+ throw new Error(`Must pass an element, selector, or descriptor to \`${name}\`.`);
109
+ }
110
+
111
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
112
+ if (typeof options === 'undefined' || options === null) {
113
+ throw new Error(`Must provide an \`option\` or \`options\` to select when calling \`${name}\`.`);
114
+ }
115
+ const element = getElement(target);
116
+ if (!element) {
117
+ throw new Error(errorMessage('Element not found', target, name));
118
+ }
119
+
120
+ // if (!isSelectElement(element)) {
121
+ // throw new Error(errorMessage('Element is not a HTMLSelectElement', target));
122
+ // }
123
+
124
+ // if (list.disabled) {
125
+ // throw new Error(errorMessage('Element is disabled', selectors.list, name));
126
+ // }
127
+
128
+ const multi = element.getAttribute('aria-multiselectable') === 'true';
129
+ if (!multi && Array.isArray(options)) {
130
+ throw new Error(errorMessage(`${elementName} \`multiple\` attribute is set to \`false\` but multiple options were passed`, target, name));
131
+ }
132
+ const optionElements = (Array.isArray(options) ? findOptions(element, options, {
133
+ selectors
134
+ }) : [findOption(element, options, {
135
+ selectors
136
+ })]
137
+
138
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
139
+ ).filter(e => e !== null);
140
+ const items = element.querySelectorAll(selectors.option);
141
+ for (const item of items) {
142
+ if (optionElements.includes(item)) {
143
+ item.setAttribute('aria-selected', 'true');
144
+ } else if (!keepPreviouslySelected) {
145
+ item.removeAttribute('aria-selected');
146
+ }
147
+ }
148
+ await triggerEvent(element, 'change');
149
+ }
150
+
151
+ //
152
+ // KEYBOARD
153
+ //
154
+
155
+ async function testListboxKeyboardNavigation(assert, elements, selectors) {
156
+ const {
157
+ target,
158
+ list
159
+ } = elements;
160
+ const options = getOptions(list, selectors.option);
161
+ const [first, second, last] = options;
162
+ assert.dom(first).hasAria('current', 'true', 'First option is activated');
163
+ await triggerKeyEvent(target, 'keydown', 'ArrowDown');
164
+ assert.dom(second).hasAria('current', 'true', 'ArrowDown activates second option');
165
+ assert.dom(first).doesNotHaveAria('current', '... and deactivates first option');
166
+ await triggerKeyEvent(target, 'keydown', 'ArrowDown');
167
+ assert.dom(last).hasAria('current', 'true', 'ArrowDown activates last option');
168
+ await triggerKeyEvent(target, 'keydown', 'Home');
169
+ assert.dom(first).hasAria('current', 'true', 'Home activates first option');
170
+ await triggerKeyEvent(target, 'keydown', 'End');
171
+ assert.dom(last).hasAria('current', 'true', 'End activates last option');
172
+ }
173
+ async function testListboxForKeyboardSingleSelection(assert, elements, selectors) {
174
+ const {
175
+ target,
176
+ list
177
+ } = elements;
178
+ const options = getOptions(list, selectors.option);
179
+ const [first, second, last] = options;
180
+ assert.dom(first).hasAria('current', 'true', 'First option is activated');
181
+ assert.dom(first).hasAria('selected', 'true', '... and selected');
182
+ await triggerKeyEvent(target, 'keydown', 'ArrowDown');
183
+ assert.dom(second).hasAria('selected', 'true', 'ArrowDown selects second option');
184
+ assert.dom(first).doesNotHaveAria('selected', '... and deselects first option');
185
+ await triggerKeyEvent(target, 'keydown', 'ArrowDown');
186
+ assert.dom(last).hasAria('selected', 'true', 'ArrowDown selects last option');
187
+ await triggerKeyEvent(target, 'keydown', 'Home');
188
+ assert.dom(first).hasAria('selected', 'true', 'Home selects first option');
189
+ await triggerKeyEvent(target, 'keydown', 'End');
190
+ assert.dom(last).hasAria('selected', 'true', 'End selects last option');
191
+ }
192
+ async function testListboxForKeyboardMultiSelection(assert, elements, selectors) {
193
+ const {
194
+ target,
195
+ list
196
+ } = elements;
197
+ const options = getOptions(list, selectors.option);
198
+ const [first, second, last] = options;
199
+ assert.dom(first).hasAria('current', 'true', 'First option is activated');
200
+ assert.dom(first).doesNotHaveAria('selected', '... and not selected');
201
+ await triggerKeyEvent(target, 'keydown', ' ');
202
+ assert.dom(first).hasAria('selected', 'true', 'SPACE selects first option');
203
+ await triggerKeyEvent(target, 'keydown', ' ');
204
+ assert.dom(first).doesNotHaveAria('selected', 'SPACE deselects first option');
205
+ await triggerKeyEvent(target, 'keydown', ' ');
206
+ assert.dom(first).hasAria('selected', 'true', 'SPACE selects first option');
207
+ await triggerKeyEvent(target, 'keydown', 'ArrowDown');
208
+ await triggerKeyEvent(target, 'keydown', ' ');
209
+ assert.dom(second).hasAria('selected', 'true', 'ArrowDown + SPACE selects second option');
210
+ assert.dom(first).hasAria('selected', 'true', '... and first option still selected');
211
+ await triggerKeyEvent(target, 'keydown', 'End');
212
+ await triggerKeyEvent(target, 'keydown', ' ');
213
+ assert.dom(last).hasAria('selected', 'true', 'End + SPACE selects last option');
214
+ assert.dom(first).hasAria('selected', 'true', '... and first option still selected');
215
+ assert.dom(second).hasAria('selected', 'true', '... and second option still selected');
216
+ await triggerKeyEvent(target, 'keydown', 'Home');
217
+ await triggerKeyEvent(target, 'keydown', ' ');
218
+ assert.dom(first).doesNotHaveAria('selected', 'Home + SPACE deselects first option');
219
+ assert.dom(second).hasAria('selected', 'true', '... and second option still selected');
220
+ assert.dom(last).hasAria('selected', 'true', '... and last option still selected');
221
+ await triggerKeyEvent(target, 'keydown', 'ArrowDown');
222
+ await triggerKeyEvent(target, 'keydown', ' ');
223
+ assert.dom(second).doesNotHaveAria('selected', 'ArrowDown + SPACE deselects second option');
224
+ await triggerKeyEvent(target, 'keydown', 'ArrowDown');
225
+ await triggerKeyEvent(target, 'keydown', ' ');
226
+ assert.dom(last).doesNotHaveAria('selected', 'ArrowDown + SPACE deselects last option');
227
+ await triggerKeyEvent(target, 'keydown', 'KeyA', {
228
+ metaKey: true
229
+ });
230
+ assert.dom(first).hasAria('selected', 'true', 'Meta + A selects all');
231
+ assert.dom(second).hasAria('selected', 'true', '... second option selected');
232
+ assert.dom(last).hasAria('selected', 'true', '... last option selected');
233
+ }
234
+
235
+ //
236
+ // MOUSE
237
+ //
238
+
239
+ async function testListboxPointerNavigation(assert, elements, selectors) {
240
+ const {
241
+ list
242
+ } = elements;
243
+ const options = getOptions(list, selectors.option);
244
+ const [first, second, last] = options;
245
+ await triggerEvent(first, 'pointerup');
246
+ assert.dom(first).hasAria('current', 'true', 'Clicking first option activates it');
247
+ await triggerEvent(second, 'pointerup');
248
+ assert.dom(second).hasAria('current', 'true', 'Clicking second option activates it');
249
+ assert.dom(first).doesNotHaveAria('current', '... and deactivates first option');
250
+ await triggerEvent(last, 'pointerup');
251
+ assert.dom(last).hasAria('current', 'true', 'Clicking last option activates it');
252
+ assert.dom(second).doesNotHaveAria('current', '... and deactivates second option');
253
+ }
254
+ async function testListboxForPointerSingleSelection(assert, elements, selectors) {
255
+ const {
256
+ list
257
+ } = elements;
258
+ const options = getOptions(list, selectors.option);
259
+ const [first, second, last] = options;
260
+ await triggerEvent(first, 'pointerup', {
261
+ bubbles: true
262
+ });
263
+ assert.dom(first).hasAria('selected', 'true', 'Clicking first option selects it');
264
+ await triggerEvent(second, 'pointerup');
265
+ assert.dom(second).hasAria('selected', 'true', 'Clicking second option selects it');
266
+ assert.dom(first).doesNotHaveAria('selected', '... and deselects first option');
267
+ await triggerEvent(last, 'pointerup');
268
+ assert.dom(last).hasAria('selected', 'true', 'Clicking last option selects it');
269
+ assert.dom(second).doesNotHaveAria('selected', '... and deselects second option');
270
+ }
271
+ async function testListboxForPointerMultiSelection(assert, elements, selectors) {
272
+ const {
273
+ list
274
+ } = elements;
275
+ const options = getOptions(list, selectors.option);
276
+ const [first, second, last] = options;
277
+ await triggerEvent(first, 'pointerup');
278
+ assert.dom(first).hasAria('selected', 'true', 'Clicking first option selects it');
279
+ await triggerEvent(first, 'pointerup', {
280
+ metaKey: true
281
+ });
282
+ assert.dom(first).doesNotHaveAria('selected', 'Clicking first option deselects it');
283
+ await triggerEvent(first, 'pointerup');
284
+ assert.dom(first).hasAria('selected', 'true', 'Clicking first option selects it');
285
+ await triggerEvent(second, 'pointerup', {
286
+ metaKey: true
287
+ });
288
+ assert.dom(second).hasAria('selected', 'true', 'Clicking second option (with meta) selects it');
289
+ assert.dom(first).hasAria('selected', 'true', '... and first option still selected');
290
+ await triggerEvent(last, 'pointerup', {
291
+ metaKey: true
292
+ });
293
+ assert.dom(last).hasAria('selected', 'true', 'Clicking last option (with meta) selects it');
294
+ assert.dom(first).hasAria('selected', 'true', '... and first option still selected');
295
+ assert.dom(second).hasAria('selected', 'true', '... and second option still selected');
296
+ await triggerEvent(first, 'pointerup', {
297
+ metaKey: true
298
+ });
299
+ assert.dom(first).doesNotHaveAria('selected', 'Clicking first option (with meta) deselects it');
300
+ assert.dom(second).hasAria('selected', 'true', '... and second option still selected');
301
+ assert.dom(last).hasAria('selected', 'true', '... and last option still selected');
302
+ await triggerEvent(second, 'pointerup', {
303
+ metaKey: true
304
+ });
305
+ assert.dom(second).doesNotHaveAria('selected', 'Clicking second option (with meta) deselects it');
306
+ await triggerEvent(last, 'pointerup', {
307
+ metaKey: true
308
+ });
309
+ assert.dom(last).doesNotHaveAria('selected', 'Clicking last option (with meta) deselects it');
310
+ await triggerEvent(first, 'pointerup');
311
+ assert.dom(first).hasAria('selected', 'true', 'Clicking first option selects it');
312
+ await triggerEvent(last, 'pointerup', {
313
+ shiftKey: true
314
+ });
315
+ assert.dom(last).hasAria('selected', 'true', 'Clicking last option (with shift) selects it');
316
+ assert.dom(second).hasAria('selected', 'true', '... and second option, too');
317
+ }
318
+
319
+ const DEFAULT_SELECTORS$1 = {
320
+ trigger: '[role="listbox"]',
321
+ list: '[role="listbox"]',
322
+ option: '[role="option"]'
323
+ };
324
+ function setupListTest(assert, selectors) {
325
+ const fullSelectors = {
326
+ ...DEFAULT_SELECTORS$1,
327
+ ...selectors
328
+ };
329
+ const list = getRootElement().querySelector(selectors.list);
330
+ assert.dom(list).exists('list exists');
331
+ return {
332
+ elements: {
333
+ trigger: list,
334
+ list: list
335
+ },
336
+ selectors: fullSelectors
337
+ };
338
+ }
339
+
340
+ //
341
+ // KEYBOARD
342
+ //
343
+
344
+ async function testListKeyboardNavigation(assert, selectors = DEFAULT_SELECTORS$1) {
345
+ const {
346
+ elements,
347
+ selectors: allSelectors
348
+ } = setupListTest(assert, selectors);
349
+ const {
350
+ trigger,
351
+ list
352
+ } = elements;
353
+ await focus(list);
354
+ await testListboxKeyboardNavigation(assert, {
355
+ target: trigger,
356
+ list
357
+ }, {
358
+ option: allSelectors.option
359
+ });
360
+ }
361
+ async function testListForKeyboardSingleSelection(assert, elements, selectors) {
362
+ const {
363
+ trigger,
364
+ list
365
+ } = elements;
366
+ await focus(list);
367
+ await testListboxForKeyboardSingleSelection(assert, {
368
+ target: trigger,
369
+ list
370
+ }, {
371
+ option: selectors.option
372
+ });
373
+ }
374
+ async function testListForKeyboardMultiSelection(assert, elements, selectors) {
375
+ const {
376
+ trigger,
377
+ list
378
+ } = elements;
379
+ await focus(list);
380
+ await testListboxForKeyboardMultiSelection(assert, {
381
+ target: trigger,
382
+ list
383
+ }, {
384
+ option: selectors.option
385
+ });
386
+ }
387
+ async function testListKeyboardSelection(assert, selectors = DEFAULT_SELECTORS$1) {
388
+ const {
389
+ elements,
390
+ selectors: allSelectors
391
+ } = setupListTest(assert, selectors);
392
+ const multi = elements.list.getAttribute('aria-multiselectable');
393
+ await (multi ? testListForKeyboardMultiSelection(assert, elements, allSelectors) : testListForKeyboardSingleSelection(assert, elements, allSelectors));
394
+ }
395
+
396
+ //
397
+ // MOUSE
398
+ //
399
+
400
+ async function testListPointerNavigation(assert, selectors = DEFAULT_SELECTORS$1) {
401
+ const {
402
+ elements,
403
+ selectors: allSelectors
404
+ } = setupListTest(assert, selectors);
405
+ const {
406
+ list
407
+ } = elements;
408
+ await testListboxPointerNavigation(assert, {
409
+ list
410
+ }, {
411
+ option: allSelectors.option
412
+ });
413
+ }
414
+ async function testListForPointerSingleSelection(assert, elements, selectors) {
415
+ const {
416
+ trigger,
417
+ list
418
+ } = elements;
419
+ await testListboxForPointerSingleSelection(assert, {
420
+ target: trigger,
421
+ list
422
+ }, {
423
+ option: selectors.option
424
+ });
425
+ }
426
+ async function testListForPointerMultiSelection(assert, elements, selectors) {
427
+ const {
428
+ trigger,
429
+ list
430
+ } = elements;
431
+ await testListboxForPointerMultiSelection(assert, {
432
+ target: trigger,
433
+ list
434
+ }, {
435
+ option: selectors.option
436
+ });
437
+ }
438
+ async function testListPointerSelection(assert, selectors = DEFAULT_SELECTORS$1) {
439
+ const {
440
+ elements,
441
+ selectors: allSelectors
442
+ } = setupListTest(assert, selectors);
443
+ const multi = elements.list.getAttribute('aria-multiselectable');
444
+ await (multi ? testListForPointerMultiSelection(assert, elements, allSelectors) : testListForPointerSingleSelection(assert, elements, allSelectors));
445
+ }
446
+
447
+ //
448
+ // BEHAVIOR
449
+ //
450
+
451
+ async function selectListbox(target, options, keepPreviouslySelected = false) {
452
+ await select(target, options, {
453
+ keepPreviouslySelected,
454
+ labels: {
455
+ name: 'selectListbox',
456
+ element: 'Listbox'
457
+ },
458
+ selectors: {
459
+ option: DEFAULT_SELECTORS$1.option
460
+ }
461
+ });
462
+ }
463
+
464
+ //
465
+ // utility functions
466
+ //
467
+
468
+ // export function findListboxOption(target: Target, text: string) {
469
+ // return findOption(target, text, {
470
+ // selectors: { option: DEFAULT_SELECTORS.option },
471
+ // labels: { name: 'findListboxOption' }
472
+ // });
473
+ // }
474
+
475
+ // export function findListboxOptions(target: Target, texts: string[]) {
476
+ // return findOptions(target, texts, {
477
+ // selectors: { option: DEFAULT_SELECTORS.option },
478
+ // labels: { name: 'findListboxOptions' }
479
+ // });
480
+ // }
481
+
482
+ function getItems(parent, selector) {
483
+ return [...parent.querySelectorAll(selector)];
484
+ }
485
+
486
+ const DEFAULT_SELECTORS = {
487
+ trigger: 'button',
488
+ menu: '[role="menu"]',
489
+ item: '& > [role="menuitem"]'
490
+ };
491
+ function setupMenuTest(assert, selectors) {
492
+ const fullSelectors = {
493
+ ...DEFAULT_SELECTORS,
494
+ ...selectors
495
+ };
496
+ const menu = getRootElement().querySelector(selectors.menu);
497
+ const trigger = getRootElement().querySelector(selectors.trigger);
498
+ assert.dom(menu).exists('Menu exists');
499
+ return {
500
+ elements: {
501
+ trigger: trigger ?? menu,
502
+ menu: menu
503
+ },
504
+ selectors: fullSelectors
505
+ };
506
+ }
507
+
508
+ //
509
+ // KEYBOARD
510
+ //
511
+
512
+ async function testMenuKeyboardNavigation(assert, selectors = DEFAULT_SELECTORS) {
513
+ const {
514
+ elements,
515
+ selectors: allSelectors
516
+ } = setupMenuTest(assert, selectors);
517
+ const {
518
+ trigger,
519
+ menu
520
+ } = elements;
521
+ const shareMenu = getRootElement().querySelectorAll('[role="menu"]').item(1);
522
+ const socialMenu = getRootElement().querySelectorAll('[role="menu"]').item(2);
523
+ await click(trigger);
524
+ assert.true(menu.matches(':popover-open'), 'Main menu opened');
525
+ const items = getItems(menu, allSelectors.item);
526
+ const [first, second,, fourth] = items;
527
+ const last = items[items.length - 1];
528
+ assert.dom(first).hasAttribute('tabindex', '0', 'First item is activated');
529
+ await triggerKeyEvent(menu, 'keydown', 'ArrowDown');
530
+ assert.dom(second).hasAttribute('tabindex', '0', '`ArrowDown` activates second item');
531
+ assert.dom(first).hasAttribute('tabindex', '-1', '... and deactivates first item');
532
+ await triggerKeyEvent(menu, 'keydown', 'ArrowDown');
533
+ await triggerKeyEvent(menu, 'keydown', 'ArrowDown');
534
+ assert.dom(fourth).hasAttribute('tabindex', '0', '`ArrowDown` 2x activates fourth item');
535
+
536
+ // open and close menu with ArrowRight / ArrowLeft
537
+
538
+ assert.false(shareMenu.matches(':popover-open'), 'Share menu is closed');
539
+ await triggerKeyEvent(menu, 'keydown', 'ArrowRight');
540
+ assert.true(shareMenu.matches(':popover-open'), '`ArrowRight` opens share menu');
541
+ await triggerKeyEvent(shareMenu, 'keydown', 'ArrowLeft');
542
+ assert.false(shareMenu.matches(':popover-open'), '`ArrowLeft` closes share menu');
543
+
544
+ // open sub-submenu and closing all of it
545
+ const shareItems = getItems(shareMenu, allSelectors.item);
546
+ await triggerKeyEvent(menu, 'keydown', 'ArrowRight');
547
+ assert.true(shareMenu.matches(':popover-open'), '`ArrowRight` opens share menu again');
548
+ await triggerKeyEvent(shareMenu, 'keydown', 'ArrowDown');
549
+ assert.dom(shareItems[1]).hasAttribute('tabindex', '0', '`ArrowDown` moves to the next item in the submenu');
550
+ await triggerKeyEvent(shareMenu, 'keydown', 'ArrowRight');
551
+ assert.true(socialMenu.matches(':popover-open'), '`ArrowRight` opens social menu');
552
+ const socialItems = getItems(socialMenu, allSelectors.item);
553
+ const spy = sinon.spy();
554
+ socialItems[0]?.addEventListener('click', spy, {
555
+ once: true
556
+ });
557
+
558
+ // await click(socialItems[0] as HTMLElement);
559
+ await triggerKeyEvent(socialMenu, 'keydown', 'Enter');
560
+ assert.true(spy.calledOnce, '`Enter` invokes menu item');
561
+ assert.false(socialMenu.matches(':popover-open'), 'Social menu is closed');
562
+ assert.false(shareMenu.matches(':popover-open'), 'Share menu closed');
563
+ assert.false(menu.matches(':popover-open'), 'Main menu closed');
564
+
565
+ // Home + End
566
+ await click(trigger);
567
+ await triggerKeyEvent(menu, 'keydown', 'End');
568
+ assert.dom(last).hasAttribute('tabindex', '0', '`End` activates last item');
569
+ await triggerKeyEvent(menu, 'keydown', 'Home');
570
+ assert.dom(first).hasAttribute('tabindex', '0', '`Home` activates first item');
571
+ }
572
+
573
+ //
574
+ // POINTER
575
+ //
576
+
577
+ async function testMenuPointerNavigation(assert, selectors = DEFAULT_SELECTORS) {
578
+ const {
579
+ elements,
580
+ selectors: allSelectors
581
+ } = setupMenuTest(assert, selectors);
582
+ const {
583
+ trigger,
584
+ menu
585
+ } = elements;
586
+ const shareMenu = getRootElement().querySelectorAll('[role="menu"]').item(1);
587
+ const socialMenu = getRootElement().querySelectorAll('[role="menu"]').item(2);
588
+ await click(trigger);
589
+ assert.true(menu.matches(':popover-open'), 'Main menu opened');
590
+ const items = getItems(menu, allSelectors.item);
591
+ const [first, second,, fourth, fifth] = items;
592
+ assert.dom(first).hasAttribute('tabindex', '0', 'First item is activated');
593
+ await triggerEvent(second, 'pointerover');
594
+ assert.dom(second).hasAttribute('tabindex', '0', '`pointerover` activates second item');
595
+ assert.dom(first).hasAttribute('tabindex', '-1', '... and deactivates first item');
596
+
597
+ // assert.dom(fourth).hasAttribute('tabindex', '0', '`ArrowDown` 2x activates fourth item');
598
+
599
+ // open and close menu with Pointerover
600
+
601
+ assert.false(shareMenu.matches(':popover-open'), 'Share menu is closed');
602
+ await triggerEvent(fourth, 'pointerover');
603
+ assert.dom(fourth).hasAttribute('tabindex', '0', '`pointerover` activates fourth item');
604
+ assert.true(shareMenu.matches(':popover-open'), '`pointerover` fourth element opens share menu');
605
+ await triggerEvent(fifth, 'pointerover');
606
+ assert.dom(fifth).hasAttribute('tabindex', '0', '`pointerover` activates fifth item');
607
+ assert.false(shareMenu.matches(':popover-open'), '`pointerover` fifth element closes share menu');
608
+
609
+ // open sub-submenu and closing all of it
610
+ const shareItems = getItems(shareMenu, allSelectors.item);
611
+ await triggerEvent(fourth, 'pointerover');
612
+ assert.true(shareMenu.matches(':popover-open'), '`pointerover` fourth element opens share menu again');
613
+ assert.dom(shareItems[0]).hasAttribute('tabindex', '0', 'first item is active');
614
+
615
+ // huh? Why does the second line work, but not the first one?
616
+ // await triggerEvent(shareItems[1] as HTMLElement, 'pointover');
617
+ shareItems[1].dispatchEvent(new Event('pointerover', {
618
+ bubbles: true
619
+ }));
620
+ assert.dom(shareItems[1]).hasAttribute('tabindex', '0', '`pointerover` activates second item');
621
+ assert.true(socialMenu.matches(':popover-open'), '... and opens social menu');
622
+ const socialItems = getItems(socialMenu, allSelectors.item);
623
+ const spy = sinon.spy();
624
+ socialItems[0]?.addEventListener('click', spy, {
625
+ once: true
626
+ });
627
+
628
+ // see: https://github.com/emberjs/ember-test-helpers/issues/267
629
+ await triggerEvent(socialItems[0], 'pointerup');
630
+ socialItems[0].click();
631
+ assert.true(spy.calledOnce, '`Enter` invokes menu item');
632
+ assert.false(socialMenu.matches(':popover-open'), 'Social menu is closed');
633
+ assert.false(shareMenu.matches(':popover-open'), 'Share menu closed');
634
+ assert.false(menu.matches(':popover-open'), 'Main menu closed');
635
+ }
636
+
637
+ export { selectListbox, testListKeyboardNavigation, testListKeyboardSelection, testListPointerNavigation, testListPointerSelection, testMenuKeyboardNavigation, testMenuPointerNavigation };
638
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../src/test-support/-private/-get-description.ts","../../src/test-support/-private/-target.ts","../../src/test-support/-private/-get-element.ts","../../src/test-support/-private/selection.ts","../../src/test-support/-private/list.ts","../../src/test-support/listbox.ts","../../src/test-support/-private/composite.ts","../../src/test-support/menu.ts"],"sourcesContent":["import { isDescriptor, lookupDescriptorData } from 'dom-element-descriptors';\n\nimport type { Target } from '@ember/test-helpers';\n\n/**\n Used internally by the DOM interaction helpers to get a description of a\n target for debug/error messaging.\n\n @private\n @param {Target} target the target\n @returns {string} a description of the target\n*/\nexport default function getDescription(target: Target): string {\n let data = isDescriptor(target) ? lookupDescriptorData(target) : null;\n\n if (data) {\n return data.description || '<unknown descriptor>';\n } else {\n // eslint-disable-next-line @typescript-eslint/no-base-to-string\n return target.toString();\n }\n}\n","import type { Target } from '@ember/test-helpers';\n\nexport interface HTMLElementContentEditable extends HTMLElement {\n isContentEditable: true;\n}\n\n// eslint-disable-next-line require-jsdoc\nexport function isElement(target: unknown): target is Element {\n return (\n target !== null &&\n typeof target === 'object' &&\n Reflect.get(target, 'nodeType') === Node.ELEMENT_NODE\n );\n}\n\n// eslint-disable-next-line require-jsdoc\nexport function isWindow(target: Target): target is Window {\n return target instanceof Window;\n}\n\n// eslint-disable-next-line require-jsdoc\nexport function isDocument(target: unknown): target is Document {\n return (\n target !== null &&\n typeof target === 'object' &&\n Reflect.get(target, 'nodeType') === Node.DOCUMENT_NODE\n );\n}\n\n// eslint-disable-next-line require-jsdoc\nexport function isContentEditable(element: Element): element is HTMLElementContentEditable {\n return 'isContentEditable' in element && (element as HTMLElement).isContentEditable;\n}\n","import { getRootElement } from '@ember/test-helpers';\n\nimport {\n type IDOMElementDescriptor,\n lookupDescriptorData,\n resolveDOMElement\n} from 'dom-element-descriptors';\n\nimport { isDocument, isElement } from './-target';\n\nimport type { Target } from '@ember/test-helpers';\n\nfunction getElement<K extends keyof (HTMLElementTagNameMap | SVGElementTagNameMap)>(\n target: K\n): (HTMLElementTagNameMap[K] | SVGElementTagNameMap[K]) | null;\nfunction getElement<K extends keyof HTMLElementTagNameMap>(\n target: K\n): HTMLElementTagNameMap[K] | null;\nfunction getElement<K extends keyof SVGElementTagNameMap>(\n target: K\n): SVGElementTagNameMap[K] | null;\nfunction getElement(target: string | IDOMElementDescriptor): Element | null;\nfunction getElement(target: Element): Element;\nfunction getElement(target: Document | Window): Document;\nfunction getElement(target: Target): Element | Document | null;\n/**\n Used internally by the DOM interaction helpers to find one element.\n\n @private\n @param {string|Element} target the element or selector to retrieve\n @returns {Element} the target or selector\n*/\nfunction getElement(target: Target): Element | Document | null {\n if (typeof target === 'string') {\n let rootElement = getRootElement();\n\n return rootElement.querySelector(target);\n } else if (isElement(target) || isDocument(target)) {\n return target;\n } else if (target instanceof Window) {\n return target.document;\n } else {\n let descriptorData = lookupDescriptorData(target);\n\n if (descriptorData) {\n return resolveDOMElement(descriptorData);\n } else {\n throw new Error('Must use an element, selector string, or DOM element descriptor');\n }\n }\n}\n\nexport default getElement;\n","import { triggerEvent } from '@ember/test-helpers';\n\nimport getDescription from './-get-description';\nimport getElement from './-get-element';\n\nimport type { Target } from '@ember/test-helpers';\n\nfunction errorMessage(message: string, target: Target, name: string) {\n let description = getDescription(target);\n\n return `${message} when calling \\`${name}('${description}')\\`.`;\n}\n\nexport function getOptions(parent: HTMLElement, selector: string): HTMLElement[] {\n return [...parent.querySelectorAll(selector)] as HTMLElement[];\n}\n\nfunction findOption(\n target: Target,\n text: string,\n {\n selectors\n }: {\n selectors: { option: string };\n }\n): HTMLElement | undefined {\n if (!target) {\n throw new Error(`Must pass an element, selector, or descriptor to \\`findOption\\`.`);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (typeof text === 'undefined' || text === null) {\n throw new Error(`Must provide an \\`text\\` to select when calling \\`findOption\\`.`);\n }\n\n const element = getElement(target);\n\n if (!element) {\n throw new Error(errorMessage('Element not found', target, 'findOption'));\n }\n\n return getOptions(element as HTMLElement, selectors.option).find((e) =>\n e.textContent?.trim().includes(text)\n );\n}\n\nexport function findOptions(\n target: Target,\n texts: string[],\n {\n selectors\n }: {\n selectors: { option: string };\n }\n): HTMLElement[] {\n if (!target) {\n throw new Error(`Must pass an element, selector, or descriptor to \\`findOption\\`.`);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (typeof texts === 'undefined' || texts === null) {\n throw new Error(`Must provide an \\`texts\\` to select when calling \\`findOption\\`.`);\n }\n\n const element = getElement(target);\n\n if (!element) {\n throw new Error(errorMessage('Element not found', target, 'findOption'));\n }\n\n return getOptions(element as HTMLElement, selectors.option).filter((e) =>\n texts.includes(e.textContent?.trim() as string)\n );\n}\n\nexport async function select(\n target: Target,\n options: string | string[],\n {\n keepPreviouslySelected = false,\n labels: { name, element: elementName },\n selectors\n }: {\n keepPreviouslySelected?: boolean;\n labels: { name: string; element: string };\n selectors: { option: string };\n }\n): Promise<void> {\n if (!target) {\n throw new Error(`Must pass an element, selector, or descriptor to \\`${name}\\`.`);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (typeof options === 'undefined' || options === null) {\n throw new Error(\n `Must provide an \\`option\\` or \\`options\\` to select when calling \\`${name}\\`.`\n );\n }\n\n const element = getElement(target);\n\n if (!element) {\n throw new Error(errorMessage('Element not found', target, name));\n }\n\n // if (!isSelectElement(element)) {\n // throw new Error(errorMessage('Element is not a HTMLSelectElement', target));\n // }\n\n // if (list.disabled) {\n // throw new Error(errorMessage('Element is disabled', selectors.list, name));\n // }\n\n const multi = (element as HTMLElement).getAttribute('aria-multiselectable') === 'true';\n\n if (!multi && Array.isArray(options)) {\n throw new Error(\n errorMessage(\n `${elementName} \\`multiple\\` attribute is set to \\`false\\` but multiple options were passed`,\n target,\n name\n )\n );\n }\n\n const optionElements = (\n Array.isArray(options)\n ? findOptions(element, options, { selectors })\n : [findOption(element, options, { selectors })]\n )\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n .filter((e) => e !== null) as HTMLElement[];\n\n const items = element.querySelectorAll(selectors.option);\n\n for (const item of items) {\n if (optionElements.includes(item as HTMLElement)) {\n item.setAttribute('aria-selected', 'true');\n } else if (!keepPreviouslySelected) {\n item.removeAttribute('aria-selected');\n }\n }\n\n await triggerEvent(element, 'change');\n}\n","import { triggerEvent, triggerKeyEvent } from '@ember/test-helpers';\n\nimport { getOptions } from './selection';\n\n//\n// KEYBOARD\n//\n\nexport async function testListboxKeyboardNavigation(\n assert: Assert,\n elements: {\n target: HTMLElement;\n list: HTMLElement;\n },\n selectors: {\n option: string;\n }\n): Promise<void> {\n const { target, list } = elements;\n const options = getOptions(list, selectors.option);\n const [first, second, last] = options;\n\n assert.dom(first).hasAria('current', 'true', 'First option is activated');\n\n await triggerKeyEvent(target, 'keydown', 'ArrowDown');\n\n assert.dom(second).hasAria('current', 'true', 'ArrowDown activates second option');\n assert.dom(first).doesNotHaveAria('current', '... and deactivates first option');\n\n await triggerKeyEvent(target, 'keydown', 'ArrowDown');\n\n assert.dom(last).hasAria('current', 'true', 'ArrowDown activates last option');\n\n await triggerKeyEvent(target, 'keydown', 'Home');\n assert.dom(first).hasAria('current', 'true', 'Home activates first option');\n\n await triggerKeyEvent(target, 'keydown', 'End');\n assert.dom(last).hasAria('current', 'true', 'End activates last option');\n}\n\nexport async function testListboxForKeyboardSingleSelection(\n assert: Assert,\n elements: {\n target: HTMLElement;\n list: HTMLElement;\n },\n selectors: {\n option: string;\n }\n): Promise<void> {\n const { target, list } = elements;\n const options = getOptions(list, selectors.option);\n const [first, second, last] = options;\n\n assert.dom(first).hasAria('current', 'true', 'First option is activated');\n assert.dom(first).hasAria('selected', 'true', '... and selected');\n\n await triggerKeyEvent(target, 'keydown', 'ArrowDown');\n assert.dom(second).hasAria('selected', 'true', 'ArrowDown selects second option');\n assert.dom(first).doesNotHaveAria('selected', '... and deselects first option');\n\n await triggerKeyEvent(target, 'keydown', 'ArrowDown');\n assert.dom(last).hasAria('selected', 'true', 'ArrowDown selects last option');\n\n await triggerKeyEvent(target, 'keydown', 'Home');\n assert.dom(first).hasAria('selected', 'true', 'Home selects first option');\n\n await triggerKeyEvent(target, 'keydown', 'End');\n assert.dom(last).hasAria('selected', 'true', 'End selects last option');\n}\n\nexport async function testListboxForKeyboardMultiSelection(\n assert: Assert,\n elements: {\n target: HTMLElement;\n list: HTMLElement;\n },\n selectors: {\n option: string;\n }\n): Promise<void> {\n const { target, list } = elements;\n const options = getOptions(list, selectors.option);\n const [first, second, last] = options;\n\n assert.dom(first).hasAria('current', 'true', 'First option is activated');\n assert.dom(first).doesNotHaveAria('selected', '... and not selected');\n\n await triggerKeyEvent(target, 'keydown', ' ');\n assert.dom(first).hasAria('selected', 'true', 'SPACE selects first option');\n\n await triggerKeyEvent(target, 'keydown', ' ');\n assert.dom(first).doesNotHaveAria('selected', 'SPACE deselects first option');\n\n await triggerKeyEvent(target, 'keydown', ' ');\n assert.dom(first).hasAria('selected', 'true', 'SPACE selects first option');\n\n await triggerKeyEvent(target, 'keydown', 'ArrowDown');\n await triggerKeyEvent(target, 'keydown', ' ');\n assert.dom(second).hasAria('selected', 'true', 'ArrowDown + SPACE selects second option');\n assert.dom(first).hasAria('selected', 'true', '... and first option still selected');\n\n await triggerKeyEvent(target, 'keydown', 'End');\n await triggerKeyEvent(target, 'keydown', ' ');\n assert.dom(last).hasAria('selected', 'true', 'End + SPACE selects last option');\n assert.dom(first).hasAria('selected', 'true', '... and first option still selected');\n assert.dom(second).hasAria('selected', 'true', '... and second option still selected');\n\n await triggerKeyEvent(target, 'keydown', 'Home');\n await triggerKeyEvent(target, 'keydown', ' ');\n\n assert.dom(first).doesNotHaveAria('selected', 'Home + SPACE deselects first option');\n assert.dom(second).hasAria('selected', 'true', '... and second option still selected');\n assert.dom(last).hasAria('selected', 'true', '... and last option still selected');\n\n await triggerKeyEvent(target, 'keydown', 'ArrowDown');\n await triggerKeyEvent(target, 'keydown', ' ');\n assert.dom(second).doesNotHaveAria('selected', 'ArrowDown + SPACE deselects second option');\n\n await triggerKeyEvent(target, 'keydown', 'ArrowDown');\n await triggerKeyEvent(target, 'keydown', ' ');\n assert.dom(last).doesNotHaveAria('selected', 'ArrowDown + SPACE deselects last option');\n\n await triggerKeyEvent(target, 'keydown', 'KeyA', { metaKey: true });\n assert.dom(first).hasAria('selected', 'true', 'Meta + A selects all');\n assert.dom(second).hasAria('selected', 'true', '... second option selected');\n assert.dom(last).hasAria('selected', 'true', '... last option selected');\n}\n\n//\n// MOUSE\n//\n\nexport async function testListboxPointerNavigation(\n assert: Assert,\n elements: {\n list: HTMLElement;\n },\n selectors: {\n option: string;\n }\n): Promise<void> {\n const { list } = elements;\n const options = getOptions(list, selectors.option);\n const [first, second, last] = options as [HTMLElement, HTMLElement, HTMLElement];\n\n await triggerEvent(first, 'pointerup');\n assert.dom(first).hasAria('current', 'true', 'Clicking first option activates it');\n\n await triggerEvent(second, 'pointerup');\n assert.dom(second).hasAria('current', 'true', 'Clicking second option activates it');\n assert.dom(first).doesNotHaveAria('current', '... and deactivates first option');\n\n await triggerEvent(last, 'pointerup');\n assert.dom(last).hasAria('current', 'true', 'Clicking last option activates it');\n assert.dom(second).doesNotHaveAria('current', '... and deactivates second option');\n}\n\nexport async function testListboxForPointerSingleSelection(\n assert: Assert,\n elements: {\n target: HTMLElement;\n list: HTMLElement;\n },\n selectors: {\n option: string;\n }\n): Promise<void> {\n const { list } = elements;\n const options = getOptions(list, selectors.option);\n const [first, second, last] = options as [HTMLElement, HTMLElement, HTMLElement];\n\n await triggerEvent(first, 'pointerup', { bubbles: true });\n assert.dom(first).hasAria('selected', 'true', 'Clicking first option selects it');\n\n await triggerEvent(second, 'pointerup');\n assert.dom(second).hasAria('selected', 'true', 'Clicking second option selects it');\n assert.dom(first).doesNotHaveAria('selected', '... and deselects first option');\n\n await triggerEvent(last, 'pointerup');\n assert.dom(last).hasAria('selected', 'true', 'Clicking last option selects it');\n assert.dom(second).doesNotHaveAria('selected', '... and deselects second option');\n}\n\nexport async function testListboxForPointerMultiSelection(\n assert: Assert,\n elements: {\n target: HTMLElement;\n list: HTMLElement;\n },\n selectors: {\n option: string;\n }\n): Promise<void> {\n const { list } = elements;\n const options = getOptions(list, selectors.option);\n const [first, second, last] = options as [HTMLElement, HTMLElement, HTMLElement];\n\n await triggerEvent(first, 'pointerup');\n assert.dom(first).hasAria('selected', 'true', 'Clicking first option selects it');\n\n await triggerEvent(first, 'pointerup', { metaKey: true });\n assert.dom(first).doesNotHaveAria('selected', 'Clicking first option deselects it');\n\n await triggerEvent(first, 'pointerup');\n assert.dom(first).hasAria('selected', 'true', 'Clicking first option selects it');\n\n await triggerEvent(second, 'pointerup', { metaKey: true });\n assert.dom(second).hasAria('selected', 'true', 'Clicking second option (with meta) selects it');\n assert.dom(first).hasAria('selected', 'true', '... and first option still selected');\n\n await triggerEvent(last, 'pointerup', { metaKey: true });\n\n assert.dom(last).hasAria('selected', 'true', 'Clicking last option (with meta) selects it');\n assert.dom(first).hasAria('selected', 'true', '... and first option still selected');\n assert.dom(second).hasAria('selected', 'true', '... and second option still selected');\n\n await triggerEvent(first, 'pointerup', { metaKey: true });\n\n assert.dom(first).doesNotHaveAria('selected', 'Clicking first option (with meta) deselects it');\n assert.dom(second).hasAria('selected', 'true', '... and second option still selected');\n assert.dom(last).hasAria('selected', 'true', '... and last option still selected');\n\n await triggerEvent(second, 'pointerup', { metaKey: true });\n assert.dom(second).doesNotHaveAria('selected', 'Clicking second option (with meta) deselects it');\n\n await triggerEvent(last, 'pointerup', { metaKey: true });\n assert.dom(last).doesNotHaveAria('selected', 'Clicking last option (with meta) deselects it');\n\n await triggerEvent(first, 'pointerup');\n assert.dom(first).hasAria('selected', 'true', 'Clicking first option selects it');\n\n await triggerEvent(last, 'pointerup', { shiftKey: true });\n assert.dom(last).hasAria('selected', 'true', 'Clicking last option (with shift) selects it');\n assert.dom(second).hasAria('selected', 'true', '... and second option, too');\n}\n","import { focus, getRootElement } from '@ember/test-helpers';\n\nimport {\n testListboxForKeyboardMultiSelection,\n testListboxForKeyboardSingleSelection,\n testListboxForPointerMultiSelection,\n testListboxForPointerSingleSelection,\n testListboxKeyboardNavigation,\n testListboxPointerNavigation\n} from './-private/list';\nimport { select } from './-private/selection';\n\nimport type { Target } from '@ember/test-helpers';\n\ntype Selectors = {\n trigger: string;\n list: string;\n option: string;\n};\n\ntype Elements = {\n trigger: HTMLElement;\n list: HTMLElement;\n};\n\nconst DEFAULT_SELECTORS = {\n trigger: '[role=\"listbox\"]',\n list: '[role=\"listbox\"]',\n option: '[role=\"option\"]'\n};\n\nfunction setupListTest(\n assert: Assert,\n selectors: Partial<Selectors>\n): { elements: Elements; selectors: Selectors } {\n const fullSelectors = { ...DEFAULT_SELECTORS, ...selectors };\n const list = getRootElement().querySelector(selectors.list as string);\n\n assert.dom(list).exists('list exists');\n\n return {\n elements: {\n trigger: list as HTMLElement,\n list: list as HTMLElement\n },\n selectors: fullSelectors\n };\n}\n\n//\n// KEYBOARD\n//\n\nexport async function testListKeyboardNavigation(\n assert: Assert,\n selectors: Partial<Selectors> = DEFAULT_SELECTORS\n): Promise<void> {\n const { elements, selectors: allSelectors } = setupListTest(assert, selectors);\n\n const { trigger, list } = elements;\n\n await focus(list);\n\n await testListboxKeyboardNavigation(\n assert,\n {\n target: trigger,\n list\n },\n {\n option: allSelectors.option\n }\n );\n}\n\nasync function testListForKeyboardSingleSelection(\n assert: Assert,\n elements: Elements,\n selectors: Selectors\n) {\n const { trigger, list } = elements;\n\n await focus(list);\n await testListboxForKeyboardSingleSelection(\n assert,\n {\n target: trigger,\n list\n },\n {\n option: selectors.option\n }\n );\n}\n\nasync function testListForKeyboardMultiSelection(\n assert: Assert,\n elements: Elements,\n selectors: Selectors\n) {\n const { trigger, list } = elements;\n\n await focus(list);\n await testListboxForKeyboardMultiSelection(\n assert,\n {\n target: trigger,\n list\n },\n {\n option: selectors.option\n }\n );\n}\n\nexport async function testListKeyboardSelection(\n assert: Assert,\n selectors: Partial<Selectors> = DEFAULT_SELECTORS\n): Promise<void> {\n const { elements, selectors: allSelectors } = setupListTest(assert, selectors);\n const multi = elements.list.getAttribute('aria-multiselectable');\n\n await (multi\n ? testListForKeyboardMultiSelection(assert, elements, allSelectors)\n : testListForKeyboardSingleSelection(assert, elements, allSelectors));\n}\n\n//\n// MOUSE\n//\n\nexport async function testListPointerNavigation(\n assert: Assert,\n selectors: Partial<Selectors> = DEFAULT_SELECTORS\n): Promise<void> {\n const { elements, selectors: allSelectors } = setupListTest(assert, selectors);\n\n const { list } = elements;\n\n await testListboxPointerNavigation(\n assert,\n {\n list\n },\n {\n option: allSelectors.option\n }\n );\n}\n\nasync function testListForPointerSingleSelection(\n assert: Assert,\n elements: Elements,\n selectors: Selectors\n) {\n const { trigger, list } = elements;\n\n await testListboxForPointerSingleSelection(\n assert,\n {\n target: trigger,\n list\n },\n {\n option: selectors.option\n }\n );\n}\n\nasync function testListForPointerMultiSelection(\n assert: Assert,\n elements: Elements,\n selectors: Selectors\n) {\n const { trigger, list } = elements;\n\n await testListboxForPointerMultiSelection(\n assert,\n {\n target: trigger,\n list\n },\n {\n option: selectors.option\n }\n );\n}\n\nexport async function testListPointerSelection(\n assert: Assert,\n selectors: Partial<Selectors> = DEFAULT_SELECTORS\n): Promise<void> {\n const { elements, selectors: allSelectors } = setupListTest(assert, selectors);\n const multi = elements.list.getAttribute('aria-multiselectable');\n\n await (multi\n ? testListForPointerMultiSelection(assert, elements, allSelectors)\n : testListForPointerSingleSelection(assert, elements, allSelectors));\n}\n\n//\n// BEHAVIOR\n//\n\nexport async function selectListbox(\n target: Target,\n options: string | string[],\n keepPreviouslySelected = false\n) {\n await select(target, options, {\n keepPreviouslySelected,\n labels: { name: 'selectListbox', element: 'Listbox' },\n selectors: {\n option: DEFAULT_SELECTORS.option\n }\n });\n}\n\n//\n// utility functions\n//\n\n// export function findListboxOption(target: Target, text: string) {\n// return findOption(target, text, {\n// selectors: { option: DEFAULT_SELECTORS.option },\n// labels: { name: 'findListboxOption' }\n// });\n// }\n\n// export function findListboxOptions(target: Target, texts: string[]) {\n// return findOptions(target, texts, {\n// selectors: { option: DEFAULT_SELECTORS.option },\n// labels: { name: 'findListboxOptions' }\n// });\n// }\n","export function getItems(parent: HTMLElement, selector: string): HTMLElement[] {\n return [...parent.querySelectorAll(selector)] as HTMLElement[];\n}\n","import { click, getRootElement, triggerEvent, triggerKeyEvent } from '@ember/test-helpers';\n\nimport sinon from 'sinon';\n\nimport { getItems } from './-private/composite';\n\ntype Selectors = {\n trigger: string;\n menu: string;\n item: string;\n};\n\ntype Elements = {\n trigger: HTMLElement;\n menu: HTMLElement;\n};\n\nconst DEFAULT_SELECTORS = {\n trigger: 'button',\n menu: '[role=\"menu\"]',\n item: '& > [role=\"menuitem\"]'\n};\n\nfunction setupMenuTest(\n assert: Assert,\n selectors: Partial<Selectors>\n): { elements: Elements; selectors: Selectors } {\n const fullSelectors = { ...DEFAULT_SELECTORS, ...selectors };\n const menu = getRootElement().querySelector(selectors.menu as string);\n const trigger = getRootElement().querySelector(selectors.trigger as string);\n\n assert.dom(menu).exists('Menu exists');\n\n return {\n elements: {\n trigger: (trigger as HTMLElement | null) ?? (menu as HTMLElement),\n menu: menu as HTMLElement\n },\n selectors: fullSelectors\n };\n}\n\n//\n// KEYBOARD\n//\n\nexport async function testMenuKeyboardNavigation(\n assert: Assert,\n selectors: Partial<Selectors> = DEFAULT_SELECTORS\n): Promise<void> {\n const { elements, selectors: allSelectors } = setupMenuTest(assert, selectors);\n const { trigger, menu } = elements;\n\n const shareMenu = getRootElement().querySelectorAll('[role=\"menu\"]').item(1) as HTMLElement;\n const socialMenu = getRootElement().querySelectorAll('[role=\"menu\"]').item(2) as HTMLElement;\n\n await click(trigger);\n\n assert.true(menu.matches(':popover-open'), 'Main menu opened');\n\n const items = getItems(menu, allSelectors.item);\n const [first, second, , fourth] = items;\n const last = items[items.length - 1];\n\n assert.dom(first).hasAttribute('tabindex', '0', 'First item is activated');\n\n await triggerKeyEvent(menu, 'keydown', 'ArrowDown');\n\n assert.dom(second).hasAttribute('tabindex', '0', '`ArrowDown` activates second item');\n assert.dom(first).hasAttribute('tabindex', '-1', '... and deactivates first item');\n\n await triggerKeyEvent(menu, 'keydown', 'ArrowDown');\n await triggerKeyEvent(menu, 'keydown', 'ArrowDown');\n\n assert.dom(fourth).hasAttribute('tabindex', '0', '`ArrowDown` 2x activates fourth item');\n\n // open and close menu with ArrowRight / ArrowLeft\n\n assert.false(shareMenu.matches(':popover-open'), 'Share menu is closed');\n\n await triggerKeyEvent(menu, 'keydown', 'ArrowRight');\n assert.true(shareMenu.matches(':popover-open'), '`ArrowRight` opens share menu');\n\n await triggerKeyEvent(shareMenu, 'keydown', 'ArrowLeft');\n assert.false(shareMenu.matches(':popover-open'), '`ArrowLeft` closes share menu');\n\n // open sub-submenu and closing all of it\n const shareItems = getItems(shareMenu, allSelectors.item);\n\n await triggerKeyEvent(menu, 'keydown', 'ArrowRight');\n assert.true(shareMenu.matches(':popover-open'), '`ArrowRight` opens share menu again');\n\n await triggerKeyEvent(shareMenu, 'keydown', 'ArrowDown');\n\n assert\n .dom(shareItems[1])\n .hasAttribute('tabindex', '0', '`ArrowDown` moves to the next item in the submenu');\n\n await triggerKeyEvent(shareMenu, 'keydown', 'ArrowRight');\n assert.true(socialMenu.matches(':popover-open'), '`ArrowRight` opens social menu');\n\n const socialItems = getItems(socialMenu, allSelectors.item);\n const spy = sinon.spy();\n\n socialItems[0]?.addEventListener('click', spy, { once: true });\n\n // await click(socialItems[0] as HTMLElement);\n await triggerKeyEvent(socialMenu, 'keydown', 'Enter');\n\n assert.true(spy.calledOnce, '`Enter` invokes menu item');\n\n assert.false(socialMenu.matches(':popover-open'), 'Social menu is closed');\n assert.false(shareMenu.matches(':popover-open'), 'Share menu closed');\n assert.false(menu.matches(':popover-open'), 'Main menu closed');\n\n // Home + End\n await click(trigger);\n\n await triggerKeyEvent(menu, 'keydown', 'End');\n assert.dom(last).hasAttribute('tabindex', '0', '`End` activates last item');\n\n await triggerKeyEvent(menu, 'keydown', 'Home');\n assert.dom(first).hasAttribute('tabindex', '0', '`Home` activates first item');\n}\n\n//\n// POINTER\n//\n\nexport async function testMenuPointerNavigation(\n assert: Assert,\n selectors: Partial<Selectors> = DEFAULT_SELECTORS\n): Promise<void> {\n const { elements, selectors: allSelectors } = setupMenuTest(assert, selectors);\n const { trigger, menu } = elements;\n\n const shareMenu = getRootElement().querySelectorAll('[role=\"menu\"]').item(1) as HTMLElement;\n const socialMenu = getRootElement().querySelectorAll('[role=\"menu\"]').item(2) as HTMLElement;\n\n await click(trigger);\n\n assert.true(menu.matches(':popover-open'), 'Main menu opened');\n\n const items = getItems(menu, allSelectors.item);\n const [first, second, , fourth, fifth] = items;\n\n assert.dom(first).hasAttribute('tabindex', '0', 'First item is activated');\n\n await triggerEvent(second as HTMLElement, 'pointerover');\n\n assert.dom(second).hasAttribute('tabindex', '0', '`pointerover` activates second item');\n assert.dom(first).hasAttribute('tabindex', '-1', '... and deactivates first item');\n\n // assert.dom(fourth).hasAttribute('tabindex', '0', '`ArrowDown` 2x activates fourth item');\n\n // open and close menu with Pointerover\n\n assert.false(shareMenu.matches(':popover-open'), 'Share menu is closed');\n\n await triggerEvent(fourth as HTMLElement, 'pointerover');\n assert.dom(fourth).hasAttribute('tabindex', '0', '`pointerover` activates fourth item');\n assert.true(shareMenu.matches(':popover-open'), '`pointerover` fourth element opens share menu');\n\n await triggerEvent(fifth as HTMLElement, 'pointerover');\n assert.dom(fifth).hasAttribute('tabindex', '0', '`pointerover` activates fifth item');\n assert.false(shareMenu.matches(':popover-open'), '`pointerover` fifth element closes share menu');\n\n // open sub-submenu and closing all of it\n const shareItems = getItems(shareMenu, allSelectors.item);\n\n await triggerEvent(fourth as HTMLElement, 'pointerover');\n assert.true(\n shareMenu.matches(':popover-open'),\n '`pointerover` fourth element opens share menu again'\n );\n\n assert.dom(shareItems[0] as HTMLElement).hasAttribute('tabindex', '0', 'first item is active');\n\n // huh? Why does the second line work, but not the first one?\n // await triggerEvent(shareItems[1] as HTMLElement, 'pointover');\n (shareItems[1] as HTMLElement).dispatchEvent(new Event('pointerover', { bubbles: true }));\n\n assert\n .dom(shareItems[1] as HTMLElement)\n .hasAttribute('tabindex', '0', '`pointerover` activates second item');\n\n assert.true(socialMenu.matches(':popover-open'), '... and opens social menu');\n\n const socialItems = getItems(socialMenu, allSelectors.item);\n const spy = sinon.spy();\n\n socialItems[0]?.addEventListener('click', spy, { once: true });\n\n // see: https://github.com/emberjs/ember-test-helpers/issues/267\n await triggerEvent(socialItems[0] as HTMLElement, 'pointerup');\n (socialItems[0] as HTMLElement).click();\n\n assert.true(spy.calledOnce, '`Enter` invokes menu item');\n\n assert.false(socialMenu.matches(':popover-open'), 'Social menu is closed');\n assert.false(shareMenu.matches(':popover-open'), 'Share menu closed');\n assert.false(menu.matches(':popover-open'), 'Main menu closed');\n}\n"],"names":["getDescription","target","data","isDescriptor","lookupDescriptorData","description","toString","isElement","Reflect","get","Node","ELEMENT_NODE","isDocument","DOCUMENT_NODE","getElement","rootElement","getRootElement","querySelector","Window","document","descriptorData","resolveDOMElement","Error","errorMessage","message","name","getOptions","parent","selector","querySelectorAll","findOption","text","selectors","element","option","find","e","textContent","trim","includes","findOptions","texts","filter","select","options","keepPreviouslySelected","labels","elementName","multi","getAttribute","Array","isArray","optionElements","items","item","setAttribute","removeAttribute","triggerEvent","testListboxKeyboardNavigation","assert","elements","list","first","second","last","dom","hasAria","triggerKeyEvent","doesNotHaveAria","testListboxForKeyboardSingleSelection","testListboxForKeyboardMultiSelection","metaKey","testListboxPointerNavigation","testListboxForPointerSingleSelection","bubbles","testListboxForPointerMultiSelection","shiftKey","DEFAULT_SELECTORS","trigger","setupListTest","fullSelectors","exists","testListKeyboardNavigation","allSelectors","focus","testListForKeyboardSingleSelection","testListForKeyboardMultiSelection","testListKeyboardSelection","testListPointerNavigation","testListForPointerSingleSelection","testListForPointerMultiSelection","testListPointerSelection","selectListbox","getItems","menu","setupMenuTest","testMenuKeyboardNavigation","shareMenu","socialMenu","click","true","matches","fourth","length","hasAttribute","false","shareItems","socialItems","spy","sinon","addEventListener","once","calledOnce","testMenuPointerNavigation","fifth","dispatchEvent","Event"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,111 @@
1
+ {
2
+ "name": "ember-aria-voyager",
3
+ "version": "0.0.1",
4
+ "description": "Navigation patterns for various aria roles and features in ember.js",
5
+ "keywords": [
6
+ "ember-addon"
7
+ ],
8
+ "author": "gossi",
9
+ "files": [
10
+ "addon-main.js",
11
+ "dist"
12
+ ],
13
+ "dependencies": {
14
+ "@embroider/addon-shim": "^1.8.7",
15
+ "lodash.isequal": "^4.5.0",
16
+ "dom-element-descriptors": "^0.5.0",
17
+ "ember-modifier": "^4.2.0",
18
+ "sinon": "^18.0.0",
19
+ "aria-voyager": "0.0.1"
20
+ },
21
+ "peerDependencies": {
22
+ "@ember/test-helpers": "^3.3.0"
23
+ },
24
+ "peerDependenciesMeta": {
25
+ "@ember/test-helpers": {
26
+ "optional": true
27
+ }
28
+ },
29
+ "devDependencies": {
30
+ "@babel/core": "^7.24.7",
31
+ "@babel/eslint-parser": "^7.24.7",
32
+ "@babel/plugin-transform-typescript": "^7.24.7",
33
+ "@babel/preset-typescript": "^7.24.7",
34
+ "@babel/runtime": "^7.24.7",
35
+ "@ember/test-helpers": "^3.3.0",
36
+ "@embroider/addon-dev": "^4.2.0",
37
+ "@glint/template": "^1.4.0",
38
+ "@gossi/config-eslint": "^0.10.0",
39
+ "@gossi/config-prettier": "^0.9.0",
40
+ "@gossi/config-targets": "^0.9.0",
41
+ "@gossi/config-template-lint": "^0.8.0",
42
+ "@rollup/plugin-babel": "^6.0.4",
43
+ "@rollup/plugin-node-resolve": "^15.2.3",
44
+ "@tsconfig/ember": "^3.0.6",
45
+ "@types/lodash.isequal": "^4.5.8",
46
+ "@types/qunit": "^2.19.10",
47
+ "@types/sinon": "^17.0.3",
48
+ "concurrently": "^8.2.2",
49
+ "ember-cli-code-coverage": "^3.0.0",
50
+ "ember-cli-htmlbars": "^6.3.0",
51
+ "eslint-plugin-ember": "^12.1.1",
52
+ "ember-source": "~5.9.0",
53
+ "ember-template-lint": "^6.0.0",
54
+ "eslint": "^8.57.0",
55
+ "postcss": "^8.4.35",
56
+ "prettier": "^3.2.5",
57
+ "qunit-dom": "^3.0.0",
58
+ "rollup": "^4.13.0",
59
+ "rollup-plugin-postcss": "^4.0.2",
60
+ "typescript": "^5.5.2",
61
+ "webpack": "^5.92.0"
62
+ },
63
+ "ember": {
64
+ "edition": "octane"
65
+ },
66
+ "ember-addon": {
67
+ "version": 2,
68
+ "type": "addon",
69
+ "main": "addon-main.js",
70
+ "app-js": {
71
+ "./modifiers/listbox.js": "./dist/_app_/modifiers/listbox.js",
72
+ "./modifiers/menu.js": "./dist/_app_/modifiers/menu.js"
73
+ }
74
+ },
75
+ "exports": {
76
+ ".": {
77
+ "types": "./declarations/index.d.ts",
78
+ "default": "./dist/index.js"
79
+ },
80
+ "./test-support": {
81
+ "types": "./declarations/test-support/index.d.ts",
82
+ "default": "./dist/test-support/index.js"
83
+ },
84
+ "./addon-main.js": "./addon-main.js",
85
+ "./*": {
86
+ "types": "./declarations/*.d.ts",
87
+ "default": "./dist/*"
88
+ }
89
+ },
90
+ "engines": {
91
+ "node": ">= 18.*"
92
+ },
93
+ "volta": {
94
+ "extends": "../../../package.json"
95
+ },
96
+ "scripts": {
97
+ "build": "concurrently 'npm:build:*'",
98
+ "build:js": "rollup --config",
99
+ "build:types": "tsc --emitDeclarationOnly",
100
+ "lint": "concurrently -g 'npm:lint:*(!fix)'",
101
+ "lint:fix": "concurrently -g 'npm:lint:*:fix'",
102
+ "lint:hbs": "ember-template-lint . --no-error-on-unmatched-pattern",
103
+ "lint:hbs:fix": "ember-template-lint . --fix --no-error-on-unmatched-pattern",
104
+ "lint:js": "eslint . --cache",
105
+ "lint:js:fix": "eslint . --fix",
106
+ "lint:types": "tsc --noEmit",
107
+ "start": "concurrently 'npm:start:*'",
108
+ "start:js": "rollup --config --watch --no-watch.clearScreen",
109
+ "start:types": "tsc --emitDeclarationOnly --watch"
110
+ }
111
+ }