@crowdstrike/glide-core 0.5.2 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/README.md +11 -1
  2. package/dist/accordion.styles.js +1 -0
  3. package/dist/button-group.button.js +1 -1
  4. package/dist/button-group.button.styles.js +2 -1
  5. package/dist/button.d.ts +3 -2
  6. package/dist/button.js +1 -1
  7. package/dist/button.styles.js +1 -1
  8. package/dist/button.test.basics.js +6 -0
  9. package/dist/checkbox.js +1 -1
  10. package/dist/checkbox.styles.js +4 -1
  11. package/dist/drawer.js +1 -1
  12. package/dist/drawer.styles.js +1 -5
  13. package/dist/drawer.test.floating-components.d.ts +1 -0
  14. package/dist/drawer.test.floating-components.js +51 -0
  15. package/dist/dropdown.js +1 -1
  16. package/dist/dropdown.option.test.interactions.multiple.js +1 -6
  17. package/dist/dropdown.styles.js +1 -0
  18. package/dist/dropdown.test.focus.js +11 -1
  19. package/dist/dropdown.test.interactions.filterable.js +64 -0
  20. package/dist/icon-button.d.ts +3 -2
  21. package/dist/icon-button.js +1 -1
  22. package/dist/icon-button.styles.js +9 -9
  23. package/dist/icon-button.test.basics.js +13 -6
  24. package/dist/input.js +1 -1
  25. package/dist/input.styles.js +1 -0
  26. package/dist/label.js +1 -1
  27. package/dist/label.styles.js +11 -13
  28. package/dist/library/localize.d.ts +17 -0
  29. package/dist/library/localize.js +1 -0
  30. package/dist/library/set-containing-block.d.ts +15 -0
  31. package/dist/library/set-containing-block.js +1 -0
  32. package/dist/menu.d.ts +5 -4
  33. package/dist/menu.js +1 -1
  34. package/dist/menu.options.d.ts +22 -0
  35. package/dist/menu.options.js +1 -0
  36. package/dist/menu.options.styles.d.ts +2 -0
  37. package/dist/menu.options.styles.js +33 -0
  38. package/dist/menu.options.test.basics.d.ts +2 -0
  39. package/dist/menu.options.test.basics.js +43 -0
  40. package/dist/menu.stories.d.ts +1 -0
  41. package/dist/menu.styles.js +3 -27
  42. package/dist/menu.test.basics.d.ts +1 -0
  43. package/dist/menu.test.basics.js +67 -45
  44. package/dist/menu.test.focus.js +34 -16
  45. package/dist/menu.test.interactions.d.ts +1 -0
  46. package/dist/menu.test.interactions.js +315 -173
  47. package/dist/modal.js +1 -1
  48. package/dist/modal.styles.js +1 -4
  49. package/dist/modal.tertiary-icon.d.ts +1 -0
  50. package/dist/modal.tertiary-icon.js +1 -1
  51. package/dist/modal.test.floating-components.d.ts +1 -0
  52. package/dist/modal.test.floating-components.js +62 -0
  53. package/dist/radio-group.js +1 -1
  54. package/dist/radio-group.styles.js +18 -22
  55. package/dist/radio.styles.js +11 -28
  56. package/dist/split-button.d.ts +3 -0
  57. package/dist/split-button.js +1 -1
  58. package/dist/split-button.styles.js +0 -1
  59. package/dist/split-button.test.basics.js +16 -1
  60. package/dist/split-container.d.ts +1 -0
  61. package/dist/split-container.js +1 -1
  62. package/dist/split-container.styles.js +2 -0
  63. package/dist/split-container.test.basics.js +11 -16
  64. package/dist/styles/focus-outline.js +1 -1
  65. package/dist/styles/variables.css +1 -1
  66. package/dist/tab.js +1 -1
  67. package/dist/tab.styles.js +79 -54
  68. package/dist/tag.js +1 -1
  69. package/dist/tag.styles.js +1 -0
  70. package/dist/tag.test.basics.js +1 -1
  71. package/dist/tag.test.translations.d.ts +1 -0
  72. package/dist/tag.test.translations.js +25 -0
  73. package/dist/textarea.styles.js +2 -1
  74. package/dist/toasts.js +1 -1
  75. package/dist/toasts.toast.js +1 -1
  76. package/dist/toggle.js +1 -1
  77. package/dist/toggle.test.basics.js +4 -0
  78. package/dist/toggle.test.states.js +8 -0
  79. package/dist/tooltip.d.ts +2 -0
  80. package/dist/tooltip.js +1 -1
  81. package/dist/tooltip.styles.js +2 -0
  82. package/dist/translations/en.d.ts +3 -0
  83. package/dist/translations/en.js +1 -0
  84. package/dist/translations/fr.d.ts +3 -0
  85. package/dist/translations/fr.js +1 -0
  86. package/dist/translations/ja.d.ts +3 -0
  87. package/dist/translations/ja.js +1 -0
  88. package/dist/tree.d.ts +1 -0
  89. package/dist/tree.item.d.ts +3 -1
  90. package/dist/tree.item.js +1 -1
  91. package/dist/tree.item.menu.d.ts +2 -0
  92. package/dist/tree.item.menu.js +1 -1
  93. package/dist/tree.item.menu.test.basics.js +6 -7
  94. package/dist/tree.item.styles.js +22 -7
  95. package/dist/tree.js +1 -1
  96. package/dist/tree.stories.d.ts +1 -0
  97. package/package.json +18 -13
@@ -1,9 +1,9 @@
1
1
  import './menu.button.js';
2
+ import './menu.link.js';
2
3
  import { ArgumentError } from 'ow';
3
4
  import { expect, fixture, html } from '@open-wc/testing';
4
- import { repeat } from 'lit/directives/repeat.js';
5
5
  import GlideCoreMenu from './menu.js';
6
- import GlideCoreMenuLink from './menu.link.js';
6
+ import GlideCoreMenuOptions from './menu.options.js';
7
7
  import expectArgumentError from './library/expect-argument-error.js';
8
8
  import sinon from 'sinon';
9
9
  GlideCoreMenu.shadowRootOptions.mode = 'open';
@@ -16,43 +16,64 @@ it('has defaults', async () => {
16
16
  // eventually typechecked, which means supplying all required attributes and slots.
17
17
  const component = await fixture(html `<glide-core-menu>
18
18
  <button slot="target">Target</button>
19
- <glide-core-menu-link label="Link"></glide-core-menu-link>
19
+
20
+ <glide-core-menu-options>
21
+ <glide-core-menu-link label="Link"></glide-core-menu-link>
22
+ </glide-core-menu-options>
20
23
  </glide-core-menu>`);
24
+ const options = component.querySelector('glide-core-menu-options');
21
25
  expect(component.getAttribute('size')).to.equal('large');
22
26
  expect(component.size).to.equal('large');
27
+ expect(options?.privateSize).to.equal('large');
23
28
  });
24
29
  it('is accessible', async () => {
25
30
  const component = await fixture(html `<glide-core-menu>
26
31
  <button slot="target">Target</button>
27
- <glide-core-menu-link label="Link"></glide-core-menu-link>
32
+
33
+ <glide-core-menu-options>
34
+ <glide-core-menu-link label="Link"></glide-core-menu-link>
35
+ </glide-core-menu-options>
28
36
  </glide-core-menu>`);
37
+ const target = component.querySelector('button');
38
+ const options = component.querySelector('glide-core-menu-options');
39
+ expect(target?.getAttribute('aria-controls')).to.equal(options?.id);
40
+ expect(options?.ariaLabelledby).to.equal(target?.id);
29
41
  await expect(component).to.be.accessible();
30
42
  });
31
43
  it('can be opened', async () => {
32
44
  const component = await fixture(html `<glide-core-menu open>
33
45
  <button slot="target">Target</button>
34
- <glide-core-menu-link label="Link"></glide-core-menu-link>
46
+
47
+ <glide-core-menu-options>
48
+ <glide-core-menu-link label="Link"></glide-core-menu-link>
49
+ </glide-core-menu-options>
35
50
  </glide-core-menu>`);
36
- const menu = component.shadowRoot?.querySelector('[data-test="menu"]');
51
+ const defaultSlot = component?.shadowRoot?.querySelector('slot:not([name])');
37
52
  const target = component.querySelector('button');
38
53
  expect(component.open).to.be.true;
39
- expect(menu?.checkVisibility({ checkVisibilityCSS: true })).to.be.true;
54
+ expect(defaultSlot?.checkVisibility({ checkVisibilityCSS: true })).to.be.true;
40
55
  expect(target?.ariaExpanded).to.equal('true');
41
56
  });
42
57
  it('can have a default slot', async () => {
43
58
  const component = await fixture(html `<glide-core-menu>
44
59
  <button slot="target">Target</button>
45
- <glide-core-menu-link label="Link"></glide-core-menu-link>
60
+
61
+ <glide-core-menu-options>
62
+ <glide-core-menu-link label="Link"></glide-core-menu-link>
63
+ </glide-core-menu-options>
46
64
  </glide-core-menu>`);
47
65
  const assignedElements = component.shadowRoot
48
66
  ?.querySelectorAll('slot')[1]
49
67
  .assignedElements();
50
- expect(assignedElements?.at(0) instanceof GlideCoreMenuLink).to.be.true;
68
+ expect(assignedElements?.at(0) instanceof GlideCoreMenuOptions).to.be.true;
51
69
  });
52
70
  it('can have a target slot', async () => {
53
71
  const component = await fixture(html `<glide-core-menu>
54
72
  <button slot="target">Target</button>
55
- <glide-core-menu-link label="Link"></glide-core-menu-link>
73
+
74
+ <glide-core-menu-options>
75
+ <glide-core-menu-link label="Link"></glide-core-menu-link>
76
+ </glide-core-menu-options>
56
77
  </glide-core-menu>`);
57
78
  const assignedElements = component.shadowRoot
58
79
  ?.querySelector('slot[name="target"]')
@@ -63,38 +84,47 @@ it('activates the first menu link by default', async () => {
63
84
  const component = await fixture(html `
64
85
  <glide-core-menu open>
65
86
  <button slot="target">Target</button>
66
- <glide-core-menu-link label="One"></glide-core-menu-link>
67
- <glide-core-menu-link label="Two"></glide-core-menu-link>
87
+
88
+ <glide-core-menu-options>
89
+ <glide-core-menu-link label="One"></glide-core-menu-link>
90
+ <glide-core-menu-link label="Two"></glide-core-menu-link>
91
+ </glide-core-menu-options>
68
92
  </glide-core-menu>
69
93
  `);
70
- const options = component.querySelectorAll('glide-core-menu-link');
71
- const menu = component?.shadowRoot?.querySelector('[data-test="menu"]');
72
- expect(options[0].privateActive).to.be.true;
73
- expect(options[1].privateActive).to.be.false;
74
- expect(menu?.getAttribute('aria-activedescendant')).to.equal(options[0].id);
94
+ const links = component.querySelectorAll('glide-core-menu-link');
95
+ const options = component.querySelector('glide-core-menu-options');
96
+ expect(links[0].privateActive).to.be.true;
97
+ expect(links[1].privateActive).to.be.false;
98
+ expect(options?.getAttribute('aria-activedescendant')).to.equal(links[0].id);
75
99
  });
76
100
  it('activates the first menu button by default', async () => {
77
101
  const component = await fixture(html `
78
102
  <glide-core-menu open>
79
103
  <button slot="target">Target</button>
80
- <glide-core-menu-button label="One"></glide-core-menu-button>
81
- <glide-core-menu-button label="Two"></glide-core-menu-button>
104
+
105
+ <glide-core-menu-options>
106
+ <glide-core-menu-button label="One"></glide-core-menu-button>
107
+ <glide-core-menu-button label="Two"></glide-core-menu-button>
108
+ </glide-core-menu-options>
82
109
  </glide-core-menu>
83
110
  `);
84
- const options = component.querySelectorAll('glide-core-menu-button');
85
- const menu = component?.shadowRoot?.querySelector('[data-test="menu"]');
86
- expect(options[0].privateActive).to.be.true;
87
- expect(options[1].privateActive).to.be.false;
88
- expect(menu?.getAttribute('aria-activedescendant')).to.equal(options[0].id);
111
+ const buttons = component.querySelectorAll('glide-core-menu-button');
112
+ const options = component.querySelector('glide-core-menu-options');
113
+ expect(buttons[0].privateActive).to.be.true;
114
+ expect(buttons[1].privateActive).to.be.false;
115
+ expect(options?.getAttribute('aria-activedescendant')).to.equal(buttons[0].id);
89
116
  });
90
117
  it('is not opened when initially `open` and its target is `disabled`', async () => {
91
118
  const component = await fixture(html `<glide-core-menu open>
92
119
  <button slot="target" disabled>Target</button>
93
- <glide-core-menu-link label="Link"></glide-core-menu-link>
120
+
121
+ <glide-core-menu-options>
122
+ <glide-core-menu-link label="Link"></glide-core-menu-link>
123
+ </glide-core-menu-options>
94
124
  </glide-core-menu>`);
95
- const menu = component.shadowRoot?.querySelector('[data-test="menu"]');
125
+ const defaultSlot = component?.shadowRoot?.querySelector('slot:not([name])');
96
126
  const target = component.querySelector('button');
97
- expect(menu?.checkVisibility({ checkVisibilityCSS: true })).to.not.be.ok;
127
+ expect(defaultSlot?.checkVisibility({ checkVisibilityCSS: true })).not.be.ok;
98
128
  expect(target?.ariaExpanded).to.equal('false');
99
129
  });
100
130
  it('throws if it does not have a default slot', async () => {
@@ -123,7 +153,9 @@ it('throws if it does not have a "target" slot', async () => {
123
153
  const spy = sinon.spy();
124
154
  try {
125
155
  await fixture(html `<glide-core-menu>
126
- <glide-core-menu-link label="Link"></glide-core-menu-link>
156
+ <glide-core-menu-options>
157
+ <glide-core-menu-link label="Link"></glide-core-menu-link>
158
+ </glide-core-menu-options>
127
159
  </glide-core-menu>`);
128
160
  }
129
161
  catch (error) {
@@ -133,29 +165,19 @@ it('throws if it does not have a "target" slot', async () => {
133
165
  }
134
166
  expect(spy.called).to.be.true;
135
167
  });
136
- it('does not throw if the default slot only contains whitespace', async () => {
137
- const spy = sinon.spy();
138
- try {
139
- await fixture(html `<glide-core-menu>
140
- <button slot="target">Target</button>
141
- ${repeat([], () => html `<glide-core-menu-link label="Link"></glide-core-menu-link>`)}
142
- </glide-core-menu>`);
143
- }
144
- catch (error) {
145
- if (error instanceof ArgumentError) {
146
- spy();
147
- }
148
- }
149
- expect(spy.notCalled).to.be.true;
150
- });
151
- it('sets accessibility attributes on the target', async () => {
168
+ it('sets accessibility attributes', async () => {
152
169
  const component = await fixture(html `<glide-core-menu>
153
170
  <button slot="target">Target</button>
154
- <glide-core-menu-link label="Link"></glide-core-menu-link>
171
+
172
+ <glide-core-menu-options>
173
+ <glide-core-menu-link label="Link"></glide-core-menu-link>
174
+ </glide-core-menu-options>
155
175
  </glide-core-menu>`);
156
176
  const target = component.querySelector('button');
177
+ const options = component.querySelector('glide-core-menu-options');
157
178
  expect(target?.getAttribute('aria-expanded')).to.equal('false');
158
179
  expect(target?.getAttribute('aria-haspopup')).to.equal('true');
159
180
  expect(target?.ariaExpanded).to.equal('false');
160
181
  expect(target?.ariaHasPopup).to.equal('true');
182
+ expect(options?.ariaLabelledby).to.equal(target?.id);
161
183
  });
@@ -2,11 +2,15 @@ import './menu.link.js';
2
2
  import { assert, elementUpdated, expect, fixture, html, } from '@open-wc/testing';
3
3
  import { sendKeys } from '@web/test-runner-commands';
4
4
  import GlideCoreMenu from './menu.js';
5
+ import GlideCoreMenuOptions from './menu.options.js';
5
6
  GlideCoreMenu.shadowRootOptions.mode = 'open';
6
7
  it('focuses the target on `focus()`', async () => {
7
8
  const component = await fixture(html `<glide-core-menu>
8
9
  <button slot="target">Target</button>
9
- <glide-core-menu-link label="Link"></glide-core-menu-link>
10
+
11
+ <glide-core-menu-options>
12
+ <glide-core-menu-link label="Link"></glide-core-menu-link>
13
+ </glide-core-menu-options>
10
14
  </glide-core-menu>`);
11
15
  component.focus();
12
16
  const target = component.querySelector('button');
@@ -16,31 +20,42 @@ it('focuses the target on `focus()`', async () => {
16
20
  it('closes when it loses focus', async () => {
17
21
  const component = await fixture(html `<glide-core-menu open>
18
22
  <button slot="target">Target</button>
19
- <glide-core-menu-link label="Link"></glide-core-menu-link>
23
+
24
+ <glide-core-menu-options>
25
+ <glide-core-menu-link label="Link"></glide-core-menu-link>
26
+ </glide-core-menu-options>
20
27
  </glide-core-menu>`);
21
28
  component.focus();
22
29
  await sendKeys({ press: 'Tab' });
23
- const menu = component?.shadowRoot?.querySelector('[data-test="menu"]');
30
+ const defaultSlot = component?.shadowRoot?.querySelector('slot:not([name])');
31
+ const options = component.querySelector('glide-core-menu-options');
24
32
  expect(component.open).to.be.false;
25
- expect(menu?.checkVisibility({ checkVisibilityCSS: true })).to.be.false;
26
- expect(menu?.getAttribute('aria-activedescendant')).to.equal('');
33
+ expect(defaultSlot?.checkVisibility({ checkVisibilityCSS: true })).be.false;
34
+ expect(options?.getAttribute('aria-activedescendant')).to.equal('');
27
35
  });
28
- it('remains open when the menu focused', async () => {
36
+ it('remains open when the options component is focused', async () => {
29
37
  const component = await fixture(html `<glide-core-menu open>
30
38
  <button slot="target">Target</button>
31
- <glide-core-menu-link label="Link"></glide-core-menu-link>
39
+
40
+ <glide-core-menu-options>
41
+ <glide-core-menu-link label="Link"></glide-core-menu-link>
42
+ </glide-core-menu-options>
32
43
  </glide-core-menu>`);
33
44
  component.focus();
34
- const menu = component.shadowRoot?.querySelector('[data-test="menu"]');
35
- assert(menu instanceof HTMLElement);
36
- menu.focus();
45
+ const options = component.querySelector('glide-core-menu-options');
46
+ assert(options instanceof GlideCoreMenuOptions);
47
+ options.focus();
48
+ const defaultSlot = component?.shadowRoot?.querySelector('slot:not([name])');
37
49
  expect(component.open).to.be.true;
38
- expect(menu?.checkVisibility({ checkVisibilityCSS: true })).to.be.true;
50
+ expect(defaultSlot?.checkVisibility({ checkVisibilityCSS: true })).to.be.true;
39
51
  });
40
52
  it('remains open when an option is focused', async () => {
41
53
  const component = await fixture(html `<glide-core-menu open>
42
54
  <button slot="target">Target</button>
43
- <glide-core-menu-link label="Link"></glide-core-menu-link>
55
+
56
+ <glide-core-menu-options>
57
+ <glide-core-menu-link label="Link"></glide-core-menu-link>
58
+ </glide-core-menu-options>
44
59
  </glide-core-menu>`);
45
60
  component.focus();
46
61
  const option = component.querySelector('glide-core-menu-link');
@@ -51,16 +66,19 @@ it('remains open when an option is focused', async () => {
51
66
  it('sets the focused option as active', async () => {
52
67
  const component = await fixture(html `<glide-core-menu open>
53
68
  <button slot="target">Target</button>
54
- <glide-core-menu-button label="Button"></glide-core-menu-button>
55
- <glide-core-menu-link label="Link"></glide-core-menu-link>
69
+
70
+ <glide-core-menu-options>
71
+ <glide-core-menu-button label="Button"></glide-core-menu-button>
72
+ <glide-core-menu-link label="Link"></glide-core-menu-link>
73
+ </glide-core-menu-options>
56
74
  </glide-core-menu>`);
57
75
  component.focus();
58
76
  const target = component.querySelector('glide-core-menu-button');
59
77
  const link = component.querySelector('glide-core-menu-link');
60
- const menu = component.shadowRoot?.querySelector('[data-test="menu"]');
78
+ const options = component.querySelector('glide-core-menu-options');
61
79
  link?.focus();
62
80
  await elementUpdated(component);
63
81
  expect(target?.privateActive).to.be.false;
64
82
  expect(link?.privateActive).to.be.true;
65
- expect(menu?.getAttribute('aria-activedescendant')).to.equal(link?.id);
83
+ expect(options?.getAttribute('aria-activedescendant')).to.equal(link?.id);
66
84
  });
@@ -1 +1,2 @@
1
1
  import './menu.link.js';
2
+ import './menu.options.js';