@crowdstrike/glide-core 0.9.0 → 0.9.2

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 (148) hide show
  1. package/dist/accordion.d.ts +7 -3
  2. package/dist/accordion.styles.js +2 -4
  3. package/dist/button-group.button.d.ts +1 -4
  4. package/dist/button-group.button.styles.js +4 -8
  5. package/dist/button-group.d.ts +3 -0
  6. package/dist/button-group.styles.js +2 -2
  7. package/dist/button.d.ts +4 -0
  8. package/dist/button.js +1 -1
  9. package/dist/button.styles.js +2 -4
  10. package/dist/button.test.events.js +86 -10
  11. package/dist/checkbox-group.d.ts +6 -2
  12. package/dist/checkbox-group.stories.d.ts +1 -1
  13. package/dist/checkbox.d.ts +5 -4
  14. package/dist/checkbox.js +1 -1
  15. package/dist/checkbox.stories.d.ts +1 -1
  16. package/dist/checkbox.styles.js +43 -6
  17. package/dist/checkbox.test.basics.js +15 -6
  18. package/dist/checkbox.test.events.js +12 -4
  19. package/dist/checkbox.test.focus.js +1 -1
  20. package/dist/checkbox.test.form.js +17 -0
  21. package/dist/checkbox.test.interactions.js +52 -7
  22. package/dist/drawer.d.ts +5 -5
  23. package/dist/drawer.js +1 -1
  24. package/dist/drawer.stories.d.ts +0 -1
  25. package/dist/dropdown.d.ts +7 -4
  26. package/dist/dropdown.js +1 -1
  27. package/dist/dropdown.option.js +1 -1
  28. package/dist/dropdown.option.styles.js +1 -0
  29. package/dist/dropdown.styles.js +47 -26
  30. package/dist/dropdown.test.focus.filterable.js +20 -0
  31. package/dist/dropdown.test.focus.js +1 -0
  32. package/dist/dropdown.test.form.js +23 -112
  33. package/dist/dropdown.test.interactions.filterable.js +121 -17
  34. package/dist/dropdown.test.interactions.multiple.js +15 -22
  35. package/dist/dropdown.test.interactions.single.js +44 -22
  36. package/dist/icon-button.d.ts +2 -0
  37. package/dist/icon-button.styles.js +2 -4
  38. package/dist/icons/checked.d.ts +5 -0
  39. package/dist/icons/checked.js +1 -1
  40. package/dist/input.d.ts +5 -4
  41. package/dist/input.js +1 -1
  42. package/dist/input.stories.d.ts +0 -4
  43. package/dist/input.styles.d.ts +1 -1
  44. package/dist/input.styles.js +93 -93
  45. package/dist/input.test.basics.js +45 -45
  46. package/dist/input.test.form.js +17 -0
  47. package/dist/label.styles.js +11 -13
  48. package/dist/library/localize.d.ts +1 -0
  49. package/dist/library/localize.test.js +45 -0
  50. package/dist/menu.button.styles.js +1 -0
  51. package/dist/menu.js +1 -1
  52. package/dist/menu.link.styles.js +1 -0
  53. package/dist/menu.styles.js +3 -1
  54. package/dist/menu.test.events.js +101 -7
  55. package/dist/menu.test.focus.js +26 -3
  56. package/dist/menu.test.interactions.js +5 -2
  57. package/dist/modal.d.ts +0 -7
  58. package/dist/modal.icon-button.test.basics.js +9 -9
  59. package/dist/modal.stories.d.ts +1 -0
  60. package/dist/modal.styles.js +2 -4
  61. package/dist/modal.tertiary-icon.test.basics.js +15 -15
  62. package/dist/modal.test.accessibility.js +16 -27
  63. package/dist/modal.test.basics.js +64 -68
  64. package/dist/modal.test.close.js +12 -16
  65. package/dist/modal.test.events.js +32 -44
  66. package/dist/modal.test.lock-scroll.js +15 -25
  67. package/dist/modal.test.methods.js +8 -12
  68. package/dist/modal.test.scrollbars.js +2 -4
  69. package/dist/radio-group.d.ts +4 -3
  70. package/dist/radio-group.js +1 -1
  71. package/dist/radio-group.stories.d.ts +1 -1
  72. package/dist/radio-group.test.basics.js +3 -3
  73. package/dist/radio-group.test.events.js +6 -6
  74. package/dist/radio-group.test.form.js +19 -0
  75. package/dist/radio.d.ts +1 -2
  76. package/dist/radio.js +1 -1
  77. package/dist/radio.styles.js +2 -6
  78. package/dist/split-button.styles.js +2 -4
  79. package/dist/split-container.d.ts +1 -1
  80. package/dist/split-container.styles.js +2 -4
  81. package/dist/status-indicator.d.ts +1 -1
  82. package/dist/styles/focus-outline.d.ts +1 -1
  83. package/dist/styles/focus-outline.js +7 -1
  84. package/dist/styles/menu-opening-animation.d.ts +2 -0
  85. package/dist/styles/menu-opening-animation.js +26 -0
  86. package/dist/styles/variables.css +1 -1
  87. package/dist/styles/visually-hidden.d.ts +1 -1
  88. package/dist/styles/visually-hidden.js +14 -1
  89. package/dist/tab.group.d.ts +6 -6
  90. package/dist/tab.group.js +1 -1
  91. package/dist/tab.group.styles.js +46 -5
  92. package/dist/tab.group.test.basics.js +9 -2
  93. package/dist/tab.group.test.interactions.js +70 -93
  94. package/dist/tab.js +1 -1
  95. package/dist/tab.panel.styles.js +3 -9
  96. package/dist/tab.styles.js +6 -13
  97. package/dist/tab.test.basics.js +15 -17
  98. package/dist/tabs.stories.d.ts +1 -0
  99. package/dist/tag.d.ts +3 -6
  100. package/dist/tag.js +1 -1
  101. package/dist/tag.styles.js +2 -4
  102. package/dist/tag.test.basics.js +28 -27
  103. package/dist/tag.test.events.js +3 -3
  104. package/dist/tag.test.focus.js +4 -4
  105. package/dist/textarea.d.ts +5 -4
  106. package/dist/textarea.stories.d.ts +0 -4
  107. package/dist/textarea.styles.d.ts +1 -1
  108. package/dist/textarea.styles.js +63 -67
  109. package/dist/textarea.test.basics.js +52 -52
  110. package/dist/toasts.d.ts +5 -0
  111. package/dist/toasts.styles.js +1 -1
  112. package/dist/toggle.d.ts +3 -3
  113. package/dist/toggle.js +1 -1
  114. package/dist/toggle.stories.d.ts +1 -1
  115. package/dist/toggle.styles.js +2 -1
  116. package/dist/toggle.test.interactions.js +37 -0
  117. package/dist/tooltip.d.ts +2 -2
  118. package/dist/tooltip.js +1 -1
  119. package/dist/tooltip.styles.js +22 -18
  120. package/dist/tooltip.test.interactions.js +6 -6
  121. package/dist/translations/en.js +1 -1
  122. package/dist/translations/fr.d.ts +3 -1
  123. package/dist/translations/fr.js +1 -1
  124. package/dist/translations/ja.d.ts +3 -1
  125. package/dist/translations/ja.js +1 -1
  126. package/dist/tree.d.ts +1 -1
  127. package/dist/tree.item.d.ts +0 -3
  128. package/dist/tree.item.icon-button.d.ts +1 -0
  129. package/dist/tree.item.icon-button.js +1 -1
  130. package/dist/tree.item.icon-button.test.basics.js +9 -0
  131. package/dist/tree.item.js +1 -1
  132. package/dist/tree.item.menu.d.ts +2 -0
  133. package/dist/tree.item.menu.js +1 -1
  134. package/dist/tree.item.menu.test.basics.js +15 -0
  135. package/dist/tree.item.styles.js +13 -3
  136. package/dist/tree.item.test.basics.d.ts +2 -1
  137. package/dist/tree.item.test.basics.js +16 -4
  138. package/dist/tree.js +1 -1
  139. package/dist/tree.test.focus.js +91 -4
  140. package/package.json +2 -1
  141. package/dist/button.test.form.d.ts +0 -1
  142. package/dist/button.test.form.js +0 -50
  143. package/dist/input.test.translations.js +0 -38
  144. package/dist/tag.test.translations.d.ts +0 -1
  145. package/dist/tag.test.translations.js +0 -25
  146. package/dist/textarea.test.translations.d.ts +0 -1
  147. package/dist/textarea.test.translations.js +0 -34
  148. /package/dist/{input.test.translations.d.ts → library/localize.test.d.ts} +0 -0
@@ -6,10 +6,6 @@ export default meta;
6
6
  export declare const Default: StoryObj;
7
7
  export declare const Password: StoryObj;
8
8
  export declare const WithError: StoryObj;
9
- export declare const Description: StoryObj;
10
- export declare const Readonly: StoryObj;
11
- export declare const Disabled: StoryObj;
12
- export declare const Placeholder: StoryObj;
13
9
  export declare const Clearable: StoryObj;
14
10
  export declare const SuffixIcon: StoryObj;
15
11
  export declare const PrefixIcon: StoryObj;
@@ -1,2 +1,2 @@
1
- declare const _default: import("lit").CSSResult;
1
+ declare const _default: import("lit").CSSResult[];
2
2
  export default _default;
@@ -1,115 +1,115 @@
1
- import{css}from"lit";import visuallyHidden from"./styles/visually-hidden.js";export default css`
2
- .meta {
3
- column-gap: var(--glide-core-spacing-xs);
4
- display: flex;
5
- font-size: 0.75rem;
6
- grid-column: 2;
7
- justify-content: space-between;
8
- }
9
-
10
- .description {
11
- display: block;
12
- }
1
+ import{css}from"lit";import visuallyHidden from"./styles/visually-hidden.js";export default[css`
2
+ ${visuallyHidden(".character-count .hidden")}
3
+ `,css`
4
+ .meta {
5
+ column-gap: var(--glide-core-spacing-xs);
6
+ display: flex;
7
+ font-size: 0.75rem;
8
+ grid-column: 2;
9
+ justify-content: space-between;
10
+ }
13
11
 
14
- .character-count {
15
- &.error {
16
- font-weight: var(--glide-core-font-weight-bold);
12
+ .description {
13
+ display: block;
17
14
  }
18
15
 
19
- .hidden {
20
- ${visuallyHidden};
16
+ .character-count {
17
+ &.error {
18
+ font-weight: var(--glide-core-font-weight-bold);
19
+ }
21
20
  }
22
- }
23
21
 
24
- .search-icon {
25
- align-items: center;
26
- display: flex;
27
- }
22
+ .search-icon {
23
+ align-items: center;
24
+ display: flex;
25
+ }
28
26
 
29
- .input-container {
30
- align-items: center;
31
- background-color: var(--glide-core-surface-base-lighter);
32
- block-size: 2.125rem;
33
- border: 1px solid var(--glide-core-border-base-light);
34
- border-radius: var(--glide-core-spacing-xs);
35
- box-sizing: border-box;
36
- color: var(--glide-core-text-body-1);
37
- display: flex;
38
- gap: var(--glide-core-spacing-xxs);
39
- line-height: var(--glide-core-body-xs-line-height);
40
- padding-inline: var(--glide-core-spacing-sm);
27
+ .input-container {
28
+ align-items: center;
29
+ background-color: var(--glide-core-surface-base-lighter);
30
+ block-size: 2.125rem;
31
+ border: 1px solid var(--glide-core-border-base);
32
+ border-radius: var(--glide-core-spacing-xs);
33
+ box-sizing: border-box;
34
+ color: var(--glide-core-text-body-1);
35
+ display: flex;
36
+ gap: var(--glide-core-spacing-xxs);
37
+ line-height: var(--glide-core-body-xs-line-height);
38
+ padding-inline: var(--glide-core-spacing-sm);
41
39
 
42
- &.error {
43
- border-color: var(--glide-core-status-error);
44
- }
40
+ &.focused,
41
+ &:hover {
42
+ border-color: var(--glide-core-border-focus);
43
+ transition: border-color 200ms ease-in-out;
44
+ }
45
45
 
46
- &.focused:not(.error) {
47
- border-color: var(--glide-core-border-focus);
48
- transition: border-color 200ms ease-in-out;
49
- }
46
+ &.error {
47
+ border-color: var(--glide-core-status-error);
48
+ }
50
49
 
51
- /* We had to resort to a class selector because there may be a bug in Chrome and Safari
50
+ /* We had to resort to a class selector because there may be a bug in Chrome and Safari
52
51
  * with ":read-only"
53
52
  * https://bugs.chromium.org/p/chromium/issues/detail?id=1519649
54
53
  */
55
- &.readonly {
56
- border: 1px solid transparent;
57
- padding-inline-start: 0;
58
- }
54
+ &.readonly {
55
+ border: 1px solid transparent;
56
+ padding-inline-start: 0;
57
+ }
59
58
 
60
- &.disabled {
61
- background-color: var(--glide-core-surface-disabled);
62
- color: var(--glide-core-text-tertiary-disabled);
63
- }
59
+ &.disabled {
60
+ background-color: var(--glide-core-surface-disabled);
61
+ border-color: var(--glide-core-border-base-light);
62
+ color: var(--glide-core-text-tertiary-disabled);
63
+ }
64
64
 
65
- input {
66
- background-color: transparent;
67
- border: none;
68
- color: inherit;
69
- cursor: inherit;
70
- font-family: var(--glide-core-font-sans);
71
- font-size: var(--glide-core-body-sm-font-size);
72
- font-weight: var(--glide-core-body-xs-font-weight);
73
- inline-size: 100%;
74
- min-inline-size: 0;
75
- outline: none;
76
- padding: 0;
65
+ input {
66
+ background-color: transparent;
67
+ border: none;
68
+ color: inherit;
69
+ cursor: inherit;
70
+ font-family: var(--glide-core-font-sans);
71
+ font-size: var(--glide-core-body-sm-font-size);
72
+ font-weight: var(--glide-core-body-xs-font-weight);
73
+ inline-size: 100%;
74
+ min-inline-size: 0;
75
+ outline: none;
76
+ padding: 0;
77
+
78
+ &::-webkit-search-decoration,
79
+ &::-webkit-search-cancel-button,
80
+ &::-webkit-search-results-button,
81
+ &::-webkit-search-results-decoration {
82
+ appearance: none;
83
+ }
84
+ }
77
85
 
78
- &::-webkit-search-decoration,
79
- &::-webkit-search-cancel-button,
80
- &::-webkit-search-results-button,
81
- &::-webkit-search-results-decoration {
82
- appearance: none;
86
+ .suffix {
87
+ align-items: center;
88
+ display: flex;
83
89
  }
84
90
  }
85
91
 
86
- .suffix {
92
+ .clear-icon-button,
93
+ .password-toggle,
94
+ ::slotted([slot='suffix']) {
87
95
  align-items: center;
88
- display: flex;
96
+ background: none;
97
+ border: none;
98
+ color: var(--glide-core-icon-default);
99
+ display: inline-flex;
100
+ justify-content: center;
101
+ padding: 0;
89
102
  }
90
- }
91
-
92
- .clear-icon-button,
93
- .password-toggle,
94
- ::slotted([slot='suffix']) {
95
- align-items: center;
96
- background: none;
97
- border: none;
98
- color: var(--glide-core-icon-default);
99
- display: inline-flex;
100
- justify-content: center;
101
- padding: 0;
102
- }
103
103
 
104
- .clear-icon-button,
105
- .password-toggle,
106
- .search-icon,
107
- ::slotted([slot='prefix']),
108
- ::slotted([slot='suffix']) {
109
- display: flex;
110
- }
104
+ .clear-icon-button,
105
+ .password-toggle,
106
+ .search-icon,
107
+ ::slotted([slot='prefix']),
108
+ ::slotted([slot='suffix']) {
109
+ display: flex;
110
+ }
111
111
 
112
- .empty .clear-icon-button {
113
- visibility: hidden;
114
- }
115
- `;
112
+ .empty .clear-icon-button {
113
+ visibility: hidden;
114
+ }
115
+ `];
@@ -7,43 +7,43 @@ it('registers', async () => {
7
7
  expect(window.customElements.get('glide-core-input')).to.equal(GlideCoreInput);
8
8
  });
9
9
  it('is accessible', async () => {
10
- const element = await fixture(html `
10
+ const component = await fixture(html `
11
11
  <glide-core-input label="Test" value="lorem"></glide-core-input>
12
12
  `);
13
- await expect(element).to.be.accessible();
13
+ await expect(component).to.be.accessible();
14
14
  });
15
15
  it('accepts and contains "value" attribute', async () => {
16
- const element = await fixture(html `
16
+ const component = await fixture(html `
17
17
  <glide-core-input label="Test" value="lorem"></glide-core-input>
18
18
  `);
19
- expect(element.value).to.equal('lorem');
19
+ expect(component.value).to.equal('lorem');
20
20
  });
21
21
  it('accepts disable attribute and disables the underlying input', async () => {
22
- const element = await fixture(html `
22
+ const component = await fixture(html `
23
23
  <glide-core-input label="Test" disabled></glide-core-input>
24
24
  `);
25
- const inputElement = element.shadowRoot?.querySelector('input');
25
+ const inputElement = component.shadowRoot?.querySelector('input');
26
26
  expect(inputElement).to.exist;
27
27
  expect(inputElement?.hasAttribute('disabled')).to.be.true;
28
28
  });
29
29
  it('accepts readonly attribute and applies readonly to the underlying input', async () => {
30
- const element = await fixture(html `
30
+ const component = await fixture(html `
31
31
  <glide-core-input label="Test" readonly></glide-core-input>
32
32
  `);
33
- const inputElement = element.shadowRoot?.querySelector('input');
33
+ const inputElement = component.shadowRoot?.querySelector('input');
34
34
  expect(inputElement).to.exist;
35
35
  expect(inputElement?.hasAttribute('readonly')).to.be.true;
36
36
  });
37
37
  it('accepts a type attribute', async () => {
38
- const element = await fixture(html `
38
+ const component = await fixture(html `
39
39
  <glide-core-input label="Test" type="number"></glide-core-input>
40
40
  `);
41
- const inputElement = element.shadowRoot?.querySelector('input');
41
+ const inputElement = component.shadowRoot?.querySelector('input');
42
42
  expect(inputElement).to.exist;
43
43
  expect(inputElement?.getAttribute('type')).to.equal('number');
44
44
  });
45
45
  it('changes to type text when password is revealed', async () => {
46
- const element = await fixture(html `
46
+ const component = await fixture(html `
47
47
  <glide-core-input
48
48
  label="Test"
49
49
  value="password123"
@@ -51,89 +51,89 @@ it('changes to type text when password is revealed', async () => {
51
51
  password-toggle
52
52
  ></glide-core-input>
53
53
  `);
54
- const inputElement = element.shadowRoot?.querySelector('input');
54
+ const inputElement = component.shadowRoot?.querySelector('input');
55
55
  expect(inputElement).to.exist;
56
56
  expect(inputElement?.getAttribute('type')).to.equal('password');
57
- const passwordToggle = element.shadowRoot?.querySelector('[data-test="password-toggle"]');
57
+ const passwordToggle = component.shadowRoot?.querySelector('[data-test="password-toggle"]');
58
58
  passwordToggle?.click();
59
- await element.updateComplete;
59
+ await component.updateComplete;
60
60
  expect(inputElement?.getAttribute('type')).to.equal('text');
61
61
  });
62
62
  it('shows search icon with type search', async () => {
63
- const element = await fixture(html `
63
+ const component = await fixture(html `
64
64
  <glide-core-input label="Test" type="search"></glide-core-input>
65
65
  `);
66
- const inputElement = element.shadowRoot?.querySelector('input');
66
+ const inputElement = component.shadowRoot?.querySelector('input');
67
67
  expect(inputElement).to.exist;
68
68
  expect(inputElement?.getAttribute('type')).to.equal('search');
69
- const searchIcon = element.shadowRoot?.querySelector('[data-test="search-icon"]');
69
+ const searchIcon = component.shadowRoot?.querySelector('[data-test="search-icon"]');
70
70
  expect(searchIcon).to.exist;
71
71
  });
72
72
  it('when using "focus() on input", the native input is focused', async () => {
73
- const element = await fixture(html `
73
+ const component = await fixture(html `
74
74
  <glide-core-input label="Test"></glide-core-input>
75
75
  `);
76
- const inputElement = element.shadowRoot?.querySelector('input');
77
- element.focus();
78
- expect(document.activeElement).to.equal(element);
79
- expect(element.shadowRoot?.activeElement).to.equal(inputElement);
76
+ const inputElement = component.shadowRoot?.querySelector('input');
77
+ component.focus();
78
+ expect(document.activeElement).to.equal(component);
79
+ expect(component.shadowRoot?.activeElement).to.equal(inputElement);
80
80
  });
81
81
  it('emits input events when text is changed and reports a value through the event target', async () => {
82
- const element = await fixture(html `
82
+ const component = await fixture(html `
83
83
  <glide-core-input label="Test"></glide-core-input>
84
84
  `);
85
85
  let inputEventCaught = false;
86
86
  let value = '';
87
- element.addEventListener('input', (event) => {
87
+ component.addEventListener('input', (event) => {
88
88
  inputEventCaught = true;
89
89
  if (event.target instanceof GlideCoreInput) {
90
90
  value = event.target.value;
91
91
  }
92
92
  });
93
- element.focus();
93
+ component.focus();
94
94
  await sendKeys({ type: 'testing' });
95
- element.blur();
95
+ component.blur();
96
96
  expect(inputEventCaught).to.be.true;
97
97
  expect(value).to.be.equal('testing');
98
98
  });
99
99
  it('clearable attribute allows for a button which can clear input', async () => {
100
- const element = await fixture(html `
100
+ const component = await fixture(html `
101
101
  <glide-core-input label="Test" clearable></glide-core-input>
102
102
  `);
103
- const clearButton = element.shadowRoot?.querySelector('[data-test="clear-button"]');
104
- element.focus();
103
+ const clearButton = component.shadowRoot?.querySelector('[data-test="clear-button"]');
104
+ component.focus();
105
105
  await sendKeys({ type: 'testing' });
106
- expect(element.value).to.be.equal('testing');
106
+ expect(component.value).to.be.equal('testing');
107
107
  clearButton?.click();
108
- expect(element.value).to.be.equal('');
108
+ expect(component.value).to.be.equal('');
109
109
  });
110
110
  it('label correctly displays when provided as an attribute', async () => {
111
- const element = await fixture(html `
111
+ const component = await fixture(html `
112
112
  <glide-core-input label="Test label"></glide-core-input>
113
113
  `);
114
- const labelElement = element?.shadowRoot?.querySelector('label');
114
+ const labelElement = component?.shadowRoot?.querySelector('label');
115
115
  const labelText = labelElement?.textContent?.trim();
116
116
  expect(labelText).to.be.equal('Test label');
117
117
  });
118
118
  it('displays a max character and current character count if maxlength is provided', async () => {
119
- const element = await fixture(html `
119
+ const component = await fixture(html `
120
120
  <glide-core-input label="Test label" maxlength="5"></glide-core-input>
121
121
  `);
122
- const maxCharacterCountText = element.shadowRoot?.querySelector('[data-test="character-count-text"]');
122
+ const maxCharacterCountText = component.shadowRoot?.querySelector('[data-test="character-count-text"]');
123
123
  expect(maxCharacterCountText?.textContent?.trim()).to.equal('0/5');
124
124
  });
125
125
  it('displays visually hidden character count text for screenreaders', async () => {
126
- const element = await fixture(html `
126
+ const component = await fixture(html `
127
127
  <glide-core-input label="Test label" maxlength="5"></glide-core-input>
128
128
  `);
129
- const maxCharacterCountAnnouncement = element.shadowRoot?.querySelector('[data-test="character-count-announcement"]');
129
+ const maxCharacterCountAnnouncement = component.shadowRoot?.querySelector('[data-test="character-count-announcement"]');
130
130
  expect(maxCharacterCountAnnouncement?.textContent?.trim()).to.equal('Character count 0 of 5');
131
131
  });
132
132
  it('does not render a character count when attribute `maxlength` is set less than than zero', async () => {
133
- const element = await fixture(html `
133
+ const component = await fixture(html `
134
134
  <glide-core-input label="Test label" maxlength="0"></glide-core-input>
135
135
  `);
136
- const container = element.shadowRoot?.querySelector('[data-test="character-count-container"]');
136
+ const container = component.shadowRoot?.querySelector('[data-test="character-count-container"]');
137
137
  expect(container).to.be.null;
138
138
  });
139
139
  it('supports a "tooltip" slot', async () => {
@@ -146,25 +146,25 @@ it('supports a "tooltip" slot', async () => {
146
146
  expect(assignedElements?.at(0)?.textContent).to.equal('Tooltip');
147
147
  });
148
148
  it('supports a "description" slot', async () => {
149
- const element = await fixture(html `
149
+ const component = await fixture(html `
150
150
  <glide-core-input label="Test">
151
151
  <div slot="description">Description</div>
152
152
  </glide-core-input>
153
153
  `);
154
- const assignedElements = element.shadowRoot
154
+ const assignedElements = component.shadowRoot
155
155
  ?.querySelector('slot[name="description"]')
156
156
  ?.assignedElements();
157
157
  expect(assignedElements?.at(0)?.textContent).to.equal('Description');
158
158
  });
159
159
  it('supports a "prefix" icon slot', async () => {
160
- const element = await fixture(html `
160
+ const component = await fixture(html `
161
161
  <glide-core-input label="Test">
162
162
  <div slot="prefix">
163
163
  <span data-svg></span>
164
164
  </div>
165
165
  </glide-core-input>
166
166
  `);
167
- const assignedElements = element.shadowRoot
167
+ const assignedElements = component.shadowRoot
168
168
  ?.querySelector('slot[name="prefix"]')
169
169
  ?.assignedElements();
170
170
  const slottedSvg = assignedElements
@@ -173,14 +173,14 @@ it('supports a "prefix" icon slot', async () => {
173
173
  expect(slottedSvg).to.exist;
174
174
  });
175
175
  it('supports a "suffix" icon slot', async () => {
176
- const element = await fixture(html `
176
+ const component = await fixture(html `
177
177
  <glide-core-input label="Test">
178
178
  <div slot="suffix">
179
179
  <span data-svg></span>
180
180
  </div>
181
181
  </glide-core-input>
182
182
  `);
183
- const assignedElements = element.shadowRoot
183
+ const assignedElements = component.shadowRoot
184
184
  ?.querySelector('slot[name="suffix"]')
185
185
  ?.assignedElements();
186
186
  const slottedSvg = assignedElements
@@ -1,6 +1,9 @@
1
1
  /* eslint-disable @typescript-eslint/no-unused-expressions */
2
2
  import './input.js';
3
3
  import { expect, fixture, html } from '@open-wc/testing';
4
+ import { sendKeys } from '@web/test-runner-commands';
5
+ import GlideCoreInput from './input.js';
6
+ import sinon from 'sinon';
4
7
  it('can be reset to initial value', async () => {
5
8
  const form = document.createElement('form');
6
9
  const input = await fixture(html `<glide-core-input value="value"></glide-core-input>`, {
@@ -55,3 +58,17 @@ it('has no `formData` value when it has a value but without a `name`', async ()
55
58
  const formData = new FormData(form);
56
59
  expect(formData.get('name')).to.be.null;
57
60
  });
61
+ it('submits its form on Enter', async () => {
62
+ const form = document.createElement('form');
63
+ const component = await fixture(html `<glide-core-input value="value"></glide-core-input>`, {
64
+ parentNode: form,
65
+ });
66
+ const spy = sinon.spy();
67
+ form.addEventListener('submit', (event) => {
68
+ event.preventDefault();
69
+ spy();
70
+ });
71
+ component.focus();
72
+ await sendKeys({ press: 'Enter' });
73
+ expect(spy.callCount).to.equal(1);
74
+ });
@@ -1,6 +1,11 @@
1
1
  import{css}from"lit";import focusOutline from"./styles/focus-outline.js";import visuallyHidden from"./styles/visually-hidden.js";export default[css`
2
+ ${focusOutline(".optional-tooltip-target:focus-visible ")}
3
+ ${visuallyHidden(".tooltips-and-label.hidden")}
4
+ `,css`
2
5
  .component {
3
6
  &.horizontal {
7
+ --column-gap: var(--glide-core-spacing-sm);
8
+
4
9
  column-gap: var(--glide-core-spacing-sm);
5
10
  display: grid;
6
11
  grid-template-columns: auto minmax(min-content, 1fr);
@@ -16,7 +21,9 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";import
16
21
  }
17
22
 
18
23
  &.middle {
19
- grid-template-columns: 50% 50%;
24
+ grid-template-columns: calc(50% - var(--column-gap) / 2) calc(
25
+ 50% - var(--column-gap) / 2
26
+ );
20
27
  }
21
28
 
22
29
  &.hidden-label {
@@ -30,13 +37,12 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";import
30
37
  column-gap: var(--glide-core-spacing-xs);
31
38
  display: flex;
32
39
 
33
- /*
34
- Prevents it from growing larger than its column percentage when a child of Form Controls
35
- Layout. Also allows for an ellipsis on the label. See the linked comment for why it's "3ch"
40
+ /*
41
+ Allows for an ellipsis on the label. See the linked comment for why it's "3ch"
36
42
  instead of "0".
37
43
 
44
+ - https://github.com/CrowdStrike/glide-core/pull/317#issuecomment-2297025365
38
45
  - https://css-tricks.com/flexbox-truncated-text/#aa-the-solution-is-min-width-0-on-the-flex-child
39
- - https://github.com/CrowdStrike/glide-core/pull/317#issuecomment-2297025365
40
46
  */
41
47
  min-inline-size: 3ch;
42
48
 
@@ -44,10 +50,6 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";import
44
50
  &.left {
45
51
  justify-content: flex-end;
46
52
  }
47
-
48
- &.hidden {
49
- ${visuallyHidden};
50
- }
51
53
  }
52
54
 
53
55
  .optional-tooltip {
@@ -80,10 +82,6 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";import
80
82
 
81
83
  display: flex;
82
84
  padding: 0;
83
-
84
- &:focus-visible {
85
- ${focusOutline};
86
- }
87
85
  }
88
86
 
89
87
  .label {
@@ -18,4 +18,5 @@ export interface Translation extends DefaultTranslation {
18
18
  displayedCharacterCount: (current: number, maximum: number) => string;
19
19
  clearEntry: (label: string) => string;
20
20
  removeTag: (name: string) => string;
21
+ actionsFor: (label: string) => string;
21
22
  }
@@ -0,0 +1,45 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-expressions */
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ import { LitElement } from 'lit';
9
+ import { LocalizeController } from './localize.js';
10
+ import { customElement } from 'lit/decorators.js';
11
+ import { expect, fixture, html } from '@open-wc/testing';
12
+ import en from '../translations/en.js';
13
+ let GlideCoreMockComponent = class GlideCoreMockComponent extends LitElement {
14
+ constructor() {
15
+ super(...arguments);
16
+ this.localize = new LocalizeController(this);
17
+ }
18
+ static { this.shadowRootOptions = {
19
+ ...LitElement.shadowRootOptions,
20
+ mode: 'closed',
21
+ }; }
22
+ };
23
+ GlideCoreMockComponent = __decorate([
24
+ customElement('mock-component')
25
+ ], GlideCoreMockComponent);
26
+ it('can call any term from en translation if locale is Japanese', async () => {
27
+ const component = await fixture(
28
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
29
+ html `<mock-component></mock-component>`);
30
+ component.lang = 'ja';
31
+ expect(component.localize.lang()).to.equal('ja');
32
+ const keys = Object.keys(en);
33
+ for (const key of keys) {
34
+ expect(component.localize.term(key)).to.be.ok;
35
+ }
36
+ });
37
+ it('can call any term from en translation if locale is French', async () => {
38
+ const component = await fixture(html `<mock-component></mock-component>`);
39
+ component.lang = 'fr';
40
+ expect(component.localize.lang()).to.equal('fr');
41
+ const keys = Object.keys(en);
42
+ for (const key of keys) {
43
+ expect(component.localize.term(key)).to.be.ok;
44
+ }
45
+ });
@@ -11,6 +11,7 @@ import{css}from"lit";export default[css`
11
11
  inline-size: 100%;
12
12
  padding-block: var(--padding-block);
13
13
  padding-inline: var(--padding-inline);
14
+ transition: background-color 100ms ease-in-out;
14
15
  user-select: none;
15
16
 
16
17
  &.active {
package/dist/menu.js CHANGED
@@ -1 +1 @@
1
- var __decorate=this&&this.__decorate||function(e,t,i,o){var n,s=arguments.length,l=s<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,i):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)l=Reflect.decorate(e,t,i,o);else for(var a=e.length-1;a>=0;a--)(n=e[a])&&(l=(s<3?n(l):s>3?n(t,i,l):n(t,i))||l);return s>3&&l&&Object.defineProperty(t,i,l),l};import{LitElement,html}from"lit";import{autoUpdate,computePosition,flip,offset}from"@floating-ui/dom";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property}from"lit/decorators.js";import{nanoid}from"nanoid";import GlideCoreMenuButton from"./menu.button.js";import GlideCoreMenuLink from"./menu.link.js";import GlideCoreMenuOptions from"./menu.options.js";import ow,{owSlot,owSlotType}from"./library/ow.js";import styles from"./menu.styles.js";let GlideCoreMenu=class GlideCoreMenu extends LitElement{constructor(){super(...arguments),this.placement="bottom-start",this.#e=createRef(),this.#t=createRef(),this.#i=!1,this.#o=!1,this.#n="large",this.#s=createRef(),this.#l=e=>{e.target&&e.target instanceof Node&&this.contains(e.target)||(this.open=!1,this.#a&&(this.#a.ariaActivedescendant=""))}}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}get open(){return this.#o}set open(e){this.#o=e,e&&!this.isTargetDisabled?this.#r():this.#c()}get size(){return this.#n}set size(e){this.#n=e,this.#a&&(this.#a.privateSize=e)}connectedCallback(){super.connectedCallback(),document.addEventListener("click",this.#l,{capture:!0})}createRenderRoot(){return this.#d=super.createRenderRoot(),this.#d}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("click",this.#l,{capture:!0})}firstUpdated(){ow(this.#a,ow.object.instanceOf(GlideCoreMenuOptions)),owSlot(this.#t.value),owSlot(this.#s.value),owSlotType(this.#t.value,[GlideCoreMenuOptions]),this.#t.value.popover="manual";const e=this.#h?.at(0);this.open&&e&&!this.isTargetDisabled&&(e.privateActive=!0,this.#r())}focus(e){this.#p&&"focus"in this.#p&&this.#p?.focus(e)}get isTargetDisabled(){const e=this.#p&&"disabled"in this.#p&&this.#p.disabled,t=this.#p&&"true"===this.#p.ariaDisabled;return Boolean(e)||Boolean(t)}render(){return html`<div class="component" @focusout="${this.#m}" ${ref(this.#e)}><slot class="target-slot" name="target" @click="${this.#u}" @keydown="${this.#f}" @slotchange="${this.#E}" ${ref(this.#s)}></slot><slot class="default-slot" @click="${this.#v}" @focusin="${this.#g}" @keydown="${this.#f}" @mouseover="${this.#w}" @slotchange="${this.#S}" ${ref(this.#t)}></slot></div>`}#C;#e;#t;#i;#o;#d;#n;#s;get#y(){return this.#h?.find((({privateActive:e})=>e))}#l;#c(){this.#C?.(),this.#a&&(this.#a.ariaActivedescendant=""),this.#p&&(this.#p.ariaExpanded="false"),this.#t.value?.hidePopover()}get#a(){const e=this.#t.value?.assignedElements().at(0);return e instanceof GlideCoreMenuOptions?e:null}#S(){ow(this.#a,ow.object.instanceOf(GlideCoreMenuOptions)),owSlot(this.#t.value),owSlotType(this.#t.value,[GlideCoreMenuOptions]);const e=this.#h?.at(0);e&&(e.privateActive=!0),this.#a.privateSize=this.size}#v(){this.open=!1}#g(e){(e.target instanceof GlideCoreMenuButton||e.target instanceof GlideCoreMenuLink)&&this.#y&&this.#a&&(e.target.privateActive=!0,this.#y.privateActive=!1,this.#a.ariaActivedescendant=e.target.id)}#w(e){if(e.target instanceof GlideCoreMenuLink||e.target instanceof GlideCoreMenuButton){if(this.#h)for(const t of this.#h)t.privateActive=t===e.target;this.#a&&(this.#a.ariaActivedescendant=e.target.id)}}#m(e){const t=e.relatedTarget instanceof HTMLElement&&this.#d?.contains(e.relatedTarget),i=e.relatedTarget instanceof GlideCoreMenuOptions,o=e.relatedTarget instanceof GlideCoreMenuButton||e.relatedTarget instanceof GlideCoreMenuLink;t||i||o||(this.open=!1)}#f(e){if(ow(this.#a,ow.object.instanceOf(GlideCoreMenuOptions)),[" ","Enter","Escape"].includes(e.key)&&this.open)return this.open=!1,this.focus(),void(this.#i=!0);if([" ","ArrowUp","ArrowDown"].includes(e.key)&&!this.open&&this.#y)return e.preventDefault(),this.open=!0,void(this.#a.ariaActivedescendant=this.#y.id);if(this.open){ow(this.#h,ow.array),ow(this.#a,ow.object.instanceOf(GlideCoreMenuOptions)),ow(this.#y,ow.object.is((e=>e instanceof GlideCoreMenuButton||e instanceof GlideCoreMenuLink)));const t=this.#h.indexOf(this.#y);if("ArrowUp"===e.key&&!e.metaKey){e.preventDefault();const i=this.#h.at(t-1);return void(i&&0!==t&&(this.#y.privateActive=!1,this.#a.ariaActivedescendant=i.id,i.privateActive=!0))}if("ArrowDown"===e.key&&!e.metaKey){e.preventDefault();const i=this.#h.at(t+1);return void(i&&(this.#y.privateActive=!1,this.#a.ariaActivedescendant=i.id,i.privateActive=!0))}if("ArrowUp"===e.key&&e.metaKey||"Home"===e.key||"PageUp"===e.key){e.preventDefault();const t=this.#h.at(0);return void(t&&(this.#y.privateActive=!1,this.#a.ariaActivedescendant=t.id,t.privateActive=!0))}if("ArrowDown"===e.key&&e.metaKey||"End"===e.key||"PageDown"===e.key){e.preventDefault();const t=this.#h.at(-1);return void(t&&(this.#y.privateActive=!1,this.#a.ariaActivedescendant=t.id,t.privateActive=!0))}}}#E(){owSlot(this.#s.value),ow(this.#p,ow.object.instanceOf(Element)),ow(this.#a,ow.object.instanceOf(GlideCoreMenuOptions));new MutationObserver((e=>{e.some((e=>"disabled"===e.attributeName||"aria-disabled"===e.attributeName))&&(this.open&&!this.isTargetDisabled?this.#r():this.#c())})).observe(this.#p,{attributes:!0}),this.#p.ariaHasPopup="true",this.#p.id=nanoid(),this.#p.setAttribute("aria-controls",this.#a.id),this.#a.ariaLabelledby=this.#p.id,this.open&&!this.isTargetDisabled?this.#r():this.#c()}#u(){this.isTargetDisabled?this.#c():this.#i?this.#i=!1:(this.#h&&this.#h.length>0&&(this.open=!this.open),!this.open&&this.#a&&this.focus())}get#h(){let e=this.#t.value?.assignedElements()?.at(0)?.children;const t=e?.[0];if(t instanceof HTMLSlotElement&&(e=t.assignedElements()),e)return[...e].filter((e=>e instanceof GlideCoreMenuLink||e instanceof GlideCoreMenuButton))}#r(){this.#C?.(),this.#p&&this.#t.value&&(this.#C=autoUpdate(this.#p,this.#t.value,(()=>{(async()=>{if(this.#p&&this.#t.value){const{x:e,y:t,placement:i}=await computePosition(this.#p,this.#t.value,{placement:this.placement,middleware:[offset({mainAxis:Number.parseFloat(window.getComputedStyle(document.body).getPropertyValue("--glide-core-spacing-xxs"))*Number.parseFloat(window.getComputedStyle(document.documentElement).fontSize)}),flip()]});this.#t.value.dataset.placement=i,Object.assign(this.#t.value.style,{left:`${e}px`,top:`${t}px`})}this.#t.value?.showPopover(),this.#a&&this.#y?.id&&(this.#a.ariaActivedescendant=this.#y.id),this.#p&&(this.#p.ariaExpanded="true")})()})))}get#p(){return this.#s.value?.assignedElements().at(0)}};__decorate([property({reflect:!0,type:Boolean})],GlideCoreMenu.prototype,"open",null),__decorate([property({reflect:!0})],GlideCoreMenu.prototype,"placement",void 0),__decorate([property({reflect:!0})],GlideCoreMenu.prototype,"size",null),GlideCoreMenu=__decorate([customElement("glide-core-menu")],GlideCoreMenu);export default GlideCoreMenu;
1
+ var __decorate=this&&this.__decorate||function(e,t,i,o){var n,s=arguments.length,l=s<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,i):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)l=Reflect.decorate(e,t,i,o);else for(var a=e.length-1;a>=0;a--)(n=e[a])&&(l=(s<3?n(l):s>3?n(t,i,l):n(t,i))||l);return s>3&&l&&Object.defineProperty(t,i,l),l};import{LitElement,html}from"lit";import{autoUpdate,computePosition,flip,offset}from"@floating-ui/dom";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property}from"lit/decorators.js";import{nanoid}from"nanoid";import GlideCoreMenuButton from"./menu.button.js";import GlideCoreMenuLink from"./menu.link.js";import GlideCoreMenuOptions from"./menu.options.js";import ow,{owSlot,owSlotType}from"./library/ow.js";import styles from"./menu.styles.js";let GlideCoreMenu=class GlideCoreMenu extends LitElement{constructor(){super(...arguments),this.placement="bottom-start",this.#e=createRef(),this.#t=createRef(),this.#i=!1,this.#o=!1,this.#n="large",this.#s=createRef(),this.#l=e=>{e.target&&e.target instanceof Node&&this.contains(e.target)||(this.open=!1,this.#a&&(this.#a.ariaActivedescendant=""))}}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}get open(){return this.#o}set open(e){this.#o=e,e&&!this.isTargetDisabled?this.#r():this.#c()}get size(){return this.#n}set size(e){this.#n=e,this.#a&&(this.#a.privateSize=e)}connectedCallback(){super.connectedCallback(),document.addEventListener("click",this.#l,{capture:!0})}createRenderRoot(){return this.#d=super.createRenderRoot(),this.#d}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("click",this.#l,{capture:!0})}firstUpdated(){ow(this.#a,ow.object.instanceOf(GlideCoreMenuOptions)),owSlot(this.#t.value),owSlot(this.#s.value),owSlotType(this.#t.value,[GlideCoreMenuOptions]),this.#t.value.popover="manual";const e=this.#h?.at(0);this.open&&e&&!this.isTargetDisabled&&(e.privateActive=!0,this.#r())}focus(e){this.#p&&"focus"in this.#p&&this.#p?.focus(e)}get isTargetDisabled(){const e=this.#p&&"disabled"in this.#p&&this.#p.disabled,t=this.#p&&"true"===this.#p.ariaDisabled;return Boolean(e)||Boolean(t)}render(){return html`<div class="component" @focusout="${this.#u}" ${ref(this.#e)}><slot class="target-slot" name="target" @click="${this.#m}" @keydown="${this.#f}" @slotchange="${this.#E}" ${ref(this.#s)}></slot><slot class="default-slot" @click="${this.#v}" @focusin="${this.#g}" @keydown="${this.#f}" @mouseover="${this.#w}" @slotchange="${this.#S}" ${ref(this.#t)}></slot></div>`}#C;#e;#t;#i;#o;#d;#n;#s;get#y(){return this.#h?.find((({privateActive:e})=>e))}#l;#c(){this.#C?.(),this.#a&&(this.#a.ariaActivedescendant=""),this.#p&&(this.#p.ariaExpanded="false"),this.#t.value?.hidePopover()}get#a(){const e=this.#t.value?.assignedElements().at(0);return e instanceof GlideCoreMenuOptions?e:null}#S(){ow(this.#a,ow.object.instanceOf(GlideCoreMenuOptions)),owSlot(this.#t.value),owSlotType(this.#t.value,[GlideCoreMenuOptions]);const e=this.#h?.at(0);e&&(e.privateActive=!0),this.#a.privateSize=this.size}#v(){this.open=!1}#g(e){(e.target instanceof GlideCoreMenuButton||e.target instanceof GlideCoreMenuLink)&&this.#y&&this.#a&&(this.#y.privateActive=!1,e.target.privateActive=!0,this.#a.ariaActivedescendant=e.target.id)}#w(e){if(e.target instanceof GlideCoreMenuLink||e.target instanceof GlideCoreMenuButton){if(this.#h)for(const t of this.#h)t.privateActive=t===e.target;this.#a&&(this.#a.ariaActivedescendant=e.target.id)}}#u(e){const t=e.relatedTarget instanceof HTMLElement&&this.#d?.contains(e.relatedTarget),i=e.relatedTarget instanceof GlideCoreMenuOptions,o=e.relatedTarget instanceof GlideCoreMenuButton||e.relatedTarget instanceof GlideCoreMenuLink;t||i||o||(this.open=!1)}#f(e){if(ow(this.#a,ow.object.instanceOf(GlideCoreMenuOptions)),[" ","Enter"].includes(e.key)&&this.open)return this.open=!1,this.focus(),this.#y?.dispatchEvent(new PointerEvent("click",{bubbles:!0})),void(this.#i=!0);if(["Escape"].includes(e.key)&&this.open)return this.open=!1,void this.focus();if(["ArrowUp","ArrowDown"].includes(e.key)&&!this.open&&this.#y)return e.preventDefault(),this.open=!0,void(this.#a.ariaActivedescendant=this.#y.id);if(this.open){ow(this.#h,ow.array),ow(this.#a,ow.object.instanceOf(GlideCoreMenuOptions)),ow(this.#y,ow.object.is((e=>e instanceof GlideCoreMenuButton||e instanceof GlideCoreMenuLink)));const t=this.#h.indexOf(this.#y);if("ArrowUp"===e.key&&!e.metaKey){e.preventDefault();const i=this.#h.at(t-1);return void(i&&0!==t&&(this.#y.privateActive=!1,this.#a.ariaActivedescendant=i.id,i.privateActive=!0))}if("ArrowDown"===e.key&&!e.metaKey){e.preventDefault();const i=this.#h.at(t+1);return void(i&&(this.#y.privateActive=!1,this.#a.ariaActivedescendant=i.id,i.privateActive=!0))}if("ArrowUp"===e.key&&e.metaKey||"Home"===e.key||"PageUp"===e.key){e.preventDefault();const t=this.#h.at(0);return void(t&&(this.#y.privateActive=!1,this.#a.ariaActivedescendant=t.id,t.privateActive=!0))}if("ArrowDown"===e.key&&e.metaKey||"End"===e.key||"PageDown"===e.key){e.preventDefault();const t=this.#h.at(-1);return void(t&&(this.#y.privateActive=!1,this.#a.ariaActivedescendant=t.id,t.privateActive=!0))}}}#E(){owSlot(this.#s.value),ow(this.#p,ow.object.instanceOf(Element)),ow(this.#a,ow.object.instanceOf(GlideCoreMenuOptions));new MutationObserver((e=>{e.some((e=>"disabled"===e.attributeName||"aria-disabled"===e.attributeName))&&(this.open&&!this.isTargetDisabled?this.#r():this.#c())})).observe(this.#p,{attributes:!0}),this.#p.ariaHasPopup="true",this.#p.id=nanoid(),this.#p.setAttribute("aria-controls",this.#a.id),this.#a.ariaLabelledby=this.#p.id,this.open&&!this.isTargetDisabled?this.#r():this.#c()}#m(){this.isTargetDisabled?this.#c():this.#i?this.#i=!1:this.#h&&this.#h.length>0&&(this.open=!this.open)}get#h(){let e=this.#t.value?.assignedElements()?.at(0)?.children;const t=e?.[0];if(t instanceof HTMLSlotElement&&(e=t.assignedElements()),e)return[...e].filter((e=>e instanceof GlideCoreMenuLink||e instanceof GlideCoreMenuButton))}#r(){this.#C?.(),this.#p&&this.#t.value&&(this.#C=autoUpdate(this.#p,this.#t.value,(()=>{(async()=>{if(this.#p&&this.#t.value){const{x:e,y:t,placement:i}=await computePosition(this.#p,this.#t.value,{placement:this.placement,middleware:[offset({mainAxis:Number.parseFloat(window.getComputedStyle(document.body).getPropertyValue("--glide-core-spacing-xxs"))*Number.parseFloat(window.getComputedStyle(document.documentElement).fontSize)}),flip()]});this.#t.value.dataset.placement=i,Object.assign(this.#t.value.style,{left:`${e}px`,top:`${t}px`})}this.#t.value?.showPopover(),this.#a&&this.#y?.id&&(this.#a.ariaActivedescendant=this.#y.id),this.#p&&(this.#p.ariaExpanded="true")})()})))}get#p(){return this.#s.value?.assignedElements().at(0)}};__decorate([property({reflect:!0,type:Boolean})],GlideCoreMenu.prototype,"open",null),__decorate([property({reflect:!0})],GlideCoreMenu.prototype,"placement",void 0),__decorate([property({reflect:!0})],GlideCoreMenu.prototype,"size",null),GlideCoreMenu=__decorate([customElement("glide-core-menu")],GlideCoreMenu);export default GlideCoreMenu;
@@ -13,6 +13,7 @@ import{css}from"lit";export default[css`
13
13
  padding-block: var(--padding-block);
14
14
  padding-inline: var(--padding-inline);
15
15
  text-decoration: none;
16
+ transition: background-color 100ms ease-in-out;
16
17
  user-select: none;
17
18
 
18
19
  &.active {
@@ -1,4 +1,6 @@
1
- import{css}from"lit";export default[css`
1
+ import{css}from"lit";import menuOpeningAnimation from"./styles/menu-opening-animation.js";export default[css`
2
+ ${menuOpeningAnimation(".default-slot:popover-open")}
3
+ `,css`
2
4
  :host {
3
5
  /* Contains elements with "padding", "margin", and "width". Inline by default. */
4
6
  display: inline-block;