@crowdstrike/glide-core 0.5.0 → 0.5.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 (208) hide show
  1. package/dist/accordion.js +1 -1
  2. package/dist/accordion.styles.js +4 -4
  3. package/dist/accordion.test.basics.js +109 -0
  4. package/dist/accordion.test.events.js +39 -0
  5. package/dist/button-group.button.js +1 -1
  6. package/dist/button-group.button.styles.js +4 -4
  7. package/dist/button-group.button.test.basics.js +169 -0
  8. package/dist/button-group.button.test.events.js +73 -0
  9. package/dist/button-group.js +1 -1
  10. package/dist/button-group.styles.js +3 -3
  11. package/dist/button-group.test.basics.js +268 -0
  12. package/dist/button-group.test.events.js +291 -0
  13. package/dist/button.js +1 -1
  14. package/dist/button.styles.js +4 -4
  15. package/dist/button.test.basics.js +196 -0
  16. package/dist/button.test.events.js +25 -0
  17. package/dist/button.test.form.js +49 -0
  18. package/dist/checkbox-group.js +1 -1
  19. package/dist/checkbox-group.styles.js +2 -2
  20. package/dist/checkbox-group.test.basics.js +119 -0
  21. package/dist/checkbox-group.test.events.js +110 -0
  22. package/dist/checkbox-group.test.focus.js +45 -0
  23. package/dist/checkbox-group.test.form.js +130 -0
  24. package/dist/checkbox-group.test.validity.js +75 -0
  25. package/dist/checkbox.js +1 -1
  26. package/dist/checkbox.styles.js +3 -3
  27. package/dist/checkbox.test.basics.js +89 -0
  28. package/dist/checkbox.test.events.js +87 -0
  29. package/dist/checkbox.test.focus.js +38 -0
  30. package/dist/checkbox.test.form.js +115 -0
  31. package/dist/checkbox.test.states.js +62 -0
  32. package/dist/checkbox.test.validity.js +51 -0
  33. package/dist/drawer.d.ts +2 -2
  34. package/dist/drawer.js +1 -15
  35. package/dist/drawer.styles.js +18 -3
  36. package/dist/drawer.test.accessibility.js +22 -0
  37. package/dist/drawer.test.basics.js +43 -0
  38. package/dist/drawer.test.closing.js +37 -0
  39. package/dist/drawer.test.events.js +52 -0
  40. package/dist/drawer.test.methods.js +34 -0
  41. package/dist/dropdown.d.ts +4 -2
  42. package/dist/dropdown.js +1 -1
  43. package/dist/dropdown.option.d.ts +1 -3
  44. package/dist/dropdown.option.js +1 -1
  45. package/dist/dropdown.option.styles.js +2 -2
  46. package/dist/dropdown.option.test.basics.js +59 -0
  47. package/dist/dropdown.option.test.basics.multiple.js +26 -0
  48. package/dist/dropdown.option.test.basics.single.js +20 -0
  49. package/dist/dropdown.option.test.events.js +27 -0
  50. package/dist/dropdown.option.test.focus.js +11 -0
  51. package/dist/dropdown.option.test.interactions.multiple.js +87 -0
  52. package/dist/dropdown.option.test.interactions.single.js +22 -0
  53. package/dist/dropdown.styles.js +28 -9
  54. package/dist/dropdown.test.basics.filterable.js +84 -0
  55. package/dist/dropdown.test.basics.js +233 -0
  56. package/dist/dropdown.test.basics.multiple.js +270 -0
  57. package/dist/dropdown.test.basics.single.js +79 -0
  58. package/dist/dropdown.test.events.js +268 -0
  59. package/dist/dropdown.test.events.multiple.js +130 -0
  60. package/dist/dropdown.test.focus.d.ts +1 -0
  61. package/dist/dropdown.test.focus.filterable.js +154 -0
  62. package/dist/dropdown.test.focus.js +18 -0
  63. package/dist/dropdown.test.focus.multiple.js +181 -0
  64. package/dist/dropdown.test.focus.single.js +53 -0
  65. package/dist/dropdown.test.form.js +140 -0
  66. package/dist/dropdown.test.form.multiple.js +149 -0
  67. package/dist/dropdown.test.form.single.js +128 -0
  68. package/dist/dropdown.test.interactions.filterable.js +385 -0
  69. package/dist/dropdown.test.interactions.js +446 -0
  70. package/dist/dropdown.test.interactions.multiple.js +908 -0
  71. package/dist/dropdown.test.interactions.single.js +466 -0
  72. package/dist/dropdown.test.validity.js +46 -0
  73. package/dist/icon-button.js +1 -1
  74. package/dist/icon-button.styles.js +3 -3
  75. package/dist/icon-button.test.basics.js +103 -0
  76. package/dist/icons/checked.js +1 -1
  77. package/dist/icons/magnifying-glass.js +1 -1
  78. package/dist/input.js +1 -1
  79. package/dist/input.styles.js +3 -3
  80. package/dist/input.test.basics.js +169 -0
  81. package/dist/input.test.events.js +97 -0
  82. package/dist/input.test.focus.js +54 -0
  83. package/dist/input.test.form.js +56 -0
  84. package/dist/input.test.validity.js +50 -0
  85. package/dist/label.js +1 -1
  86. package/dist/label.styles.js +3 -3
  87. package/dist/label.test.basics.js +129 -0
  88. package/dist/library/expect-argument-error.js +1 -1
  89. package/dist/library/ow.js +1 -1
  90. package/dist/library/ow.test.js +55 -0
  91. package/dist/menu.button.d.ts +1 -2
  92. package/dist/menu.button.js +1 -1
  93. package/dist/menu.button.styles.js +3 -3
  94. package/dist/menu.button.test.basics.js +42 -0
  95. package/dist/menu.d.ts +4 -0
  96. package/dist/menu.js +1 -1
  97. package/dist/menu.link.d.ts +1 -2
  98. package/dist/menu.link.js +1 -1
  99. package/dist/menu.link.styles.js +3 -3
  100. package/dist/menu.link.test.basics.js +46 -0
  101. package/dist/menu.styles.js +13 -6
  102. package/dist/menu.test.basics.js +161 -0
  103. package/dist/menu.test.focus.d.ts +0 -1
  104. package/dist/menu.test.focus.js +66 -0
  105. package/dist/menu.test.interactions.d.ts +0 -1
  106. package/dist/menu.test.interactions.js +522 -0
  107. package/dist/modal.icon-button.js +1 -1
  108. package/dist/modal.icon-button.styles.js +2 -2
  109. package/dist/modal.icon-button.test.basics.js +45 -0
  110. package/dist/modal.js +1 -15
  111. package/dist/modal.styles.js +4 -4
  112. package/dist/modal.tertiary-icon.js +1 -1
  113. package/dist/modal.tertiary-icon.test.basics.js +59 -0
  114. package/dist/modal.test.accessibility.js +48 -0
  115. package/dist/modal.test.basics.js +203 -0
  116. package/dist/modal.test.close.js +38 -0
  117. package/dist/modal.test.events.js +110 -0
  118. package/dist/modal.test.lock-scroll.js +76 -0
  119. package/dist/modal.test.methods.js +23 -0
  120. package/dist/modal.test.scrollbars.js +19 -0
  121. package/dist/radio-group.js +1 -1
  122. package/dist/radio-group.styles.js +2 -2
  123. package/dist/radio-group.test.basics.js +323 -0
  124. package/dist/radio-group.test.events.js +277 -0
  125. package/dist/radio-group.test.focus.js +75 -0
  126. package/dist/radio-group.test.form.js +104 -0
  127. package/dist/radio-group.test.validity.js +228 -0
  128. package/dist/radio.js +1 -1
  129. package/dist/radio.styles.js +4 -4
  130. package/dist/split-button.d.ts +24 -0
  131. package/dist/split-button.js +1 -0
  132. package/dist/split-button.stories.d.ts +17 -0
  133. package/dist/split-button.styles.d.ts +2 -0
  134. package/dist/split-button.styles.js +103 -0
  135. package/dist/split-button.test.basics.d.ts +1 -0
  136. package/dist/split-button.test.basics.js +84 -0
  137. package/dist/split-container.d.ts +30 -0
  138. package/dist/split-container.js +1 -0
  139. package/dist/split-container.styles.d.ts +2 -0
  140. package/dist/split-container.styles.js +132 -0
  141. package/dist/split-container.test.basics.d.ts +3 -0
  142. package/dist/split-container.test.basics.js +445 -0
  143. package/dist/split-container.test.interactions.d.ts +1 -0
  144. package/dist/split-container.test.interactions.js +20 -0
  145. package/dist/split-link.d.ts +25 -0
  146. package/dist/split-link.js +1 -0
  147. package/dist/split-link.test.basics.d.ts +1 -0
  148. package/dist/split-link.test.basics.js +92 -0
  149. package/dist/split-link.test.interactions.d.ts +1 -0
  150. package/dist/split-link.test.interactions.js +19 -0
  151. package/dist/status-indicator.js +1 -1
  152. package/dist/status-indicator.styles.js +2 -2
  153. package/dist/status-indicator.test.basics.js +102 -0
  154. package/dist/styles/focus-outline.js +1 -4
  155. package/dist/styles/visually-hidden.js +1 -11
  156. package/dist/tab.group.js +1 -1
  157. package/dist/tab.group.styles.js +2 -2
  158. package/dist/tab.group.test.basics.js +185 -0
  159. package/dist/tab.js +1 -1
  160. package/dist/tab.panel.js +1 -1
  161. package/dist/tab.panel.styles.js +3 -3
  162. package/dist/tab.styles.js +2 -2
  163. package/dist/tab.test.basics.js +71 -0
  164. package/dist/tag.js +1 -1
  165. package/dist/tag.styles.js +3 -3
  166. package/dist/tag.test.basics.js +118 -0
  167. package/dist/tag.test.events.js +16 -0
  168. package/dist/tag.test.focus.js +11 -0
  169. package/dist/textarea.js +2 -2
  170. package/dist/textarea.styles.js +3 -3
  171. package/dist/textarea.test.basics.js +140 -0
  172. package/dist/textarea.test.events.js +204 -0
  173. package/dist/textarea.test.form.js +70 -0
  174. package/dist/textarea.test.validity.js +83 -0
  175. package/dist/toasts.js +1 -1
  176. package/dist/toasts.styles.js +2 -2
  177. package/dist/toasts.test.basics.js +94 -0
  178. package/dist/toasts.toast.js +1 -1
  179. package/dist/toasts.toast.styles.js +5 -2
  180. package/dist/toasts.toast.test.basics.js +139 -0
  181. package/dist/toggle.js +1 -1
  182. package/dist/toggle.styles.js +3 -3
  183. package/dist/toggle.test.basics.js +64 -0
  184. package/dist/toggle.test.events.js +29 -0
  185. package/dist/toggle.test.focus.js +9 -0
  186. package/dist/toggle.test.states.js +35 -0
  187. package/dist/tooltip.js +1 -1
  188. package/dist/tooltip.styles.js +3 -3
  189. package/dist/tooltip.test.basics.js +64 -0
  190. package/dist/tooltip.test.interactions.js +78 -0
  191. package/dist/tree.item.icon-button.js +1 -1
  192. package/dist/tree.item.icon-button.styles.js +2 -2
  193. package/dist/tree.item.icon-button.test.basics.js +13 -0
  194. package/dist/tree.item.js +1 -1
  195. package/dist/tree.item.menu.js +1 -1
  196. package/dist/tree.item.menu.styles.js +2 -2
  197. package/dist/tree.item.menu.test.basics.js +34 -0
  198. package/dist/tree.item.styles.js +2 -2
  199. package/dist/tree.item.test.basics.js +102 -0
  200. package/dist/tree.js +1 -1
  201. package/dist/tree.styles.js +2 -2
  202. package/dist/tree.test.aria.js +86 -0
  203. package/dist/tree.test.basics.js +123 -0
  204. package/dist/tree.test.events.js +19 -0
  205. package/dist/tree.test.focus.js +261 -0
  206. package/package.json +20 -18
  207. /package/dist/{dropdown.option.test.focus.multiple.d.ts → dropdown.option.test.focus.d.ts} +0 -0
  208. /package/dist/{dropdown.option.test.focus.single.d.ts → dropdown.test.events.multiple.d.ts} +0 -0
@@ -0,0 +1,132 @@
1
+ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export default[css`
2
+ .component {
3
+ display: inline-flex;
4
+ gap: 0;
5
+
6
+ & .divider {
7
+ inline-size: 1px;
8
+
9
+ &.primary {
10
+ background-color: var(--glide-core-border-base-light);
11
+ }
12
+
13
+ &.secondary {
14
+ background-color: var(--glide-core-border-primary);
15
+ }
16
+ }
17
+
18
+ &:not(.disabled):hover {
19
+ & .divider {
20
+ background-color: transparent;
21
+ }
22
+ }
23
+
24
+ &.disabled,
25
+ &.disabled:hover {
26
+ & .divider {
27
+ background-color: var(--glide-core-border-base-light);
28
+ }
29
+ }
30
+
31
+ & .menu-button {
32
+ align-items: center;
33
+ border-color: transparent;
34
+ border-radius: 0 0.75rem 0.75rem 0;
35
+ border-style: solid;
36
+ border-width: 1px 1px 1px 0;
37
+ cursor: pointer;
38
+ display: inline-flex;
39
+ font-family: var(--glide-core-heading-xxs-font-family);
40
+ font-style: var(--glide-core-heading-xxs-font-style);
41
+ font-weight: var(--glide-core-heading-xxs-font-weight);
42
+ gap: 0.625rem;
43
+ justify-content: center;
44
+ padding-block: var(--glide-core-spacing-xs);
45
+ padding-inline: var(--glide-core-spacing-xs);
46
+ text-decoration: none;
47
+ transition-duration: 150ms;
48
+ transition-property: color, background-color, border-color, fill, stroke;
49
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
50
+ user-select: none;
51
+
52
+ &:focus {
53
+ outline: none;
54
+ }
55
+
56
+ &:focus-visible {
57
+ ${focusOutline};
58
+ }
59
+
60
+ &:disabled {
61
+ cursor: default;
62
+ opacity: 1;
63
+ pointer-events: none;
64
+ }
65
+
66
+ &.primary {
67
+ background-color: var(--glide-core-surface-primary);
68
+ border-color: transparent;
69
+ color: var(--glide-core-text-selected);
70
+
71
+ &:disabled {
72
+ background-color: var(--glide-core-surface-disabled);
73
+ border-color: transparent;
74
+ color: var(--glide-core-text-tertiary-disabled);
75
+ }
76
+
77
+ &:not(:disabled):active {
78
+ background-color: var(--glide-core-surface-selected-hover);
79
+ border-color: transparent;
80
+ color: var(--glide-core-text-selected);
81
+ }
82
+
83
+ &:not(:active):hover:not(:disabled) {
84
+ background-color: var(--glide-core-surface-hover);
85
+ border-color: transparent;
86
+ box-shadow: var(--glide-core-glow-sm);
87
+ color: var(--glide-core-text-primary);
88
+ }
89
+ }
90
+
91
+ &.secondary {
92
+ background-color: transparent;
93
+ border-color: var(--glide-core-border-primary);
94
+ color: var(--glide-core-text-primary);
95
+
96
+ &:disabled {
97
+ background-color: var(--glide-core-surface-disabled);
98
+ border-color: transparent;
99
+ color: var(--glide-core-text-tertiary-disabled);
100
+ }
101
+
102
+ &:not(:disabled):active {
103
+ background-color: var(--glide-core-surface-selected-hover);
104
+ border-color: transparent;
105
+ color: var(--glide-core-text-selected);
106
+ }
107
+
108
+ &:not(:active):hover:not(:disabled) {
109
+ background-color: var(--glide-core-surface-hover);
110
+ border-color: transparent;
111
+ box-shadow: var(--glide-core-glow-sm);
112
+ color: var(--glide-core-text-primary);
113
+ }
114
+ }
115
+
116
+ &.small {
117
+ block-size: 1.75rem;
118
+ box-sizing: border-box;
119
+ font-size: var(--glide-core-body-xs-font-size);
120
+ line-height: 1rem;
121
+ min-inline-size: fit-content;
122
+ }
123
+
124
+ &.large {
125
+ block-size: 2.125rem;
126
+ box-sizing: border-box;
127
+ font-size: var(--glide-core-body-xxs-font-size);
128
+ line-height: 1.5rem;
129
+ }
130
+ }
131
+ }
132
+ `];
@@ -0,0 +1,3 @@
1
+ import './split-button.js';
2
+ import './split-container.js';
3
+ import './split-link.js';
@@ -0,0 +1,445 @@
1
+ import './split-button.js';
2
+ import './split-container.js';
3
+ import './split-link.js';
4
+ import { ArgumentError } from 'ow';
5
+ import { assert, elementUpdated, expect, fixture, html, } from '@open-wc/testing';
6
+ import GlideCoreSplitButton from './split-button.js';
7
+ import GlideCoreSplitContainer from './split-container.js';
8
+ import GlideCoreSplitLink from './split-link.js';
9
+ import expectArgumentError from './library/expect-argument-error.js';
10
+ import sinon from 'sinon';
11
+ GlideCoreSplitContainer.shadowRootOptions.mode = 'open';
12
+ it('registers', async () => {
13
+ expect(window.customElements.get('glide-core-split-container')).to.equal(GlideCoreSplitContainer);
14
+ });
15
+ it('is accessible', async () => {
16
+ const component = await fixture(html `
17
+ <glide-core-split-container menu-label="label">
18
+ <glide-core-split-button slot="primary-action"
19
+ >Button</glide-core-split-button
20
+ >
21
+ <glide-core-menu-link label="One" url="/one"></glide-core-menu-link>
22
+ <glide-core-menu-link label="Two" url="/two"></glide-core-menu-link>
23
+ <glide-core-menu-button label="Three"></glide-core-menu-button>
24
+ </glide-core-split-container>
25
+ `);
26
+ await expect(component).to.be.accessible();
27
+ });
28
+ it('should render a split button, a divider, and a menu button', async () => {
29
+ const component = await fixture(html `
30
+ <glide-core-split-container menu-label="label">
31
+ <glide-core-split-button slot="primary-action"
32
+ >Button</glide-core-split-button
33
+ >
34
+ <glide-core-menu-link label="One" url="/one"></glide-core-menu-link>
35
+ </glide-core-split-container>
36
+ `);
37
+ expect(component.shadowRoot?.querySelector('[data-test="split-menu-button"]'))
38
+ .to.be.not.null;
39
+ expect(component.shadowRoot?.querySelector('[data-test="split-divider"]')).to
40
+ .be.not.null;
41
+ const slot = component?.shadowRoot?.querySelector('slot[data-test="primary-action"]');
42
+ expect(slot).to.be.not.null;
43
+ const defaultSlotValue = slot.assignedNodes()?.at(0);
44
+ expect(defaultSlotValue instanceof GlideCoreSplitButton).to.be.true;
45
+ expect(defaultSlotValue?.textContent).to.equal('Button');
46
+ });
47
+ it('should render a split link, a divider, and a menu button', async () => {
48
+ const component = await fixture(html `
49
+ <glide-core-split-container menu-label="label">
50
+ <glide-core-split-link slot="primary-action">Link</glide-core-split-link>
51
+ <glide-core-menu-link label="One" url="/one"></glide-core-menu-link>
52
+ </glide-core-split-container>
53
+ `);
54
+ expect(component.shadowRoot?.querySelector('[data-test="split-menu-button"]'))
55
+ .to.be.not.null;
56
+ expect(component.shadowRoot?.querySelector('[data-test="split-divider"]')).to
57
+ .be.not.null;
58
+ const slot = component?.shadowRoot?.querySelector('slot[data-test="primary-action"]');
59
+ expect(slot).to.be.not.null;
60
+ const defaultSlotValue = slot.assignedNodes()?.at(0);
61
+ expect(defaultSlotValue instanceof GlideCoreSplitLink).to.be.true;
62
+ expect(defaultSlotValue?.textContent).to.equal('Link');
63
+ });
64
+ it('does not set the menu to "open" by default', async () => {
65
+ const component = await fixture(html `
66
+ <glide-core-split-container menu-label="label">
67
+ <glide-core-split-button slot="primary-action"
68
+ >Button</glide-core-split-button
69
+ >
70
+ <glide-core-menu-link label="One" url="/one"></glide-core-menu-link>
71
+ </glide-core-split-container>
72
+ `);
73
+ expect(component.shadowRoot?.querySelector('glide-core-menu')).to.not.have.attribute('open');
74
+ });
75
+ it('sets the menu component to "open" when the "open" attribute is set', async () => {
76
+ const component = await fixture(html `
77
+ <glide-core-split-container menu-label="label" open>
78
+ <glide-core-split-button slot="primary-action"
79
+ >Button</glide-core-split-button
80
+ >
81
+ <glide-core-menu-link label="One" url="/one"></glide-core-menu-link>
82
+ </glide-core-split-container>
83
+ `);
84
+ expect(component.shadowRoot?.querySelector('glide-core-menu')).to.have.attribute('open');
85
+ });
86
+ it('applies appropriate classes and attributes when "size" is set to "small"', async () => {
87
+ const component = await fixture(html `
88
+ <glide-core-split-container menu-label="label" size="small">
89
+ <glide-core-split-button slot="primary-action"
90
+ >Button</glide-core-split-button
91
+ >
92
+ <glide-core-menu-link label="One" url="/one"></glide-core-menu-link>
93
+ </glide-core-split-container>
94
+ `);
95
+ expect(component.shadowRoot
96
+ ?.querySelector('[data-test="primary-action"]')
97
+ ?.assignedNodes()
98
+ ?.at(0)).to.have.attribute('size', 'small');
99
+ expect(component.shadowRoot
100
+ ?.querySelector('[data-test="split-menu-button"]')
101
+ ?.classList.contains('small')).to.be.true;
102
+ expect(component.shadowRoot?.querySelector('glide-core-menu')).to.have.attribute('size', 'small');
103
+ });
104
+ it('applies appropriate classes and attributes when "size" is set to "large"', async () => {
105
+ const component = await fixture(html `
106
+ <glide-core-split-container menu-label="label" size="large">
107
+ <glide-core-split-button slot="primary-action"
108
+ >Button</glide-core-split-button
109
+ >
110
+ <glide-core-menu-link label="One" url="/one"></glide-core-menu-link>
111
+ </glide-core-split-container>
112
+ `);
113
+ expect(component.shadowRoot
114
+ ?.querySelector('[data-test="primary-action"]')
115
+ ?.assignedNodes()
116
+ ?.at(0)).to.have.attribute('size', 'large');
117
+ expect(component.shadowRoot
118
+ ?.querySelector('[data-test="split-menu-button"]')
119
+ ?.classList.contains('large')).to.be.true;
120
+ expect(component.shadowRoot?.querySelector('glide-core-menu')).to.have.attribute('size', 'large');
121
+ });
122
+ it('applies appropriate classes and attributes by default as "large" when "size" is not set', async () => {
123
+ const component = await fixture(html `
124
+ <glide-core-split-container menu-label="label">
125
+ <glide-core-split-button slot="primary-action"
126
+ >Button</glide-core-split-button
127
+ >
128
+ <glide-core-menu-link label="One" url="/one"></glide-core-menu-link>
129
+ </glide-core-split-container>
130
+ `);
131
+ expect(component.shadowRoot
132
+ ?.querySelector('[data-test="primary-action"]')
133
+ ?.assignedNodes()
134
+ ?.at(0)).to.have.attribute('size', 'large');
135
+ expect(component.shadowRoot
136
+ ?.querySelector('[data-test="split-menu-button"]')
137
+ ?.classList.contains('large')).to.be.true;
138
+ expect(component.shadowRoot?.querySelector('glide-core-menu')).to.have.attribute('size', 'large');
139
+ });
140
+ it('applies appropriate classes and attributes when "size" is dynamically changed using the split button', async () => {
141
+ const component = await fixture(html `
142
+ <glide-core-split-container menu-label="label" size="large">
143
+ <glide-core-split-button slot="primary-action"
144
+ >Button</glide-core-split-button
145
+ >
146
+ <glide-core-menu-link label="One" url="/one"></glide-core-menu-link>
147
+ </glide-core-split-container>
148
+ `);
149
+ expect(component.shadowRoot
150
+ ?.querySelector('[data-test="primary-action"]')
151
+ ?.assignedNodes()
152
+ ?.at(0)).to.have.attribute('size', 'large');
153
+ expect(component.shadowRoot
154
+ ?.querySelector('[data-test="split-menu-button"]')
155
+ ?.classList.contains('large')).to.be.true;
156
+ expect(component.shadowRoot?.querySelector('glide-core-menu')).to.have.attribute('size', 'large');
157
+ component.size = 'small';
158
+ await elementUpdated(component);
159
+ expect(component.shadowRoot
160
+ ?.querySelector('[data-test="primary-action"]')
161
+ ?.assignedNodes()
162
+ ?.at(0)).to.have.attribute('size', 'small');
163
+ expect(component.shadowRoot
164
+ ?.querySelector('[data-test="split-menu-button"]')
165
+ ?.classList.contains('small')).to.be.true;
166
+ expect(component.shadowRoot?.querySelector('glide-core-menu')).to.have.attribute('size', 'small');
167
+ });
168
+ it('applies appropriate classes and attributes when "size" is dynamically changed using the link button', async () => {
169
+ const component = await fixture(html `
170
+ <glide-core-split-container menu-label="label" size="large">
171
+ <glide-core-split-link slot="primary-action" url="/"
172
+ >Button</glide-core-split-link
173
+ >
174
+ <glide-core-menu-link label="One" url="/one"></glide-core-menu-link>
175
+ </glide-core-split-container>
176
+ `);
177
+ expect(component.shadowRoot
178
+ ?.querySelector('[data-test="primary-action"]')
179
+ ?.assignedNodes()
180
+ ?.at(0)).to.have.attribute('size', 'large');
181
+ expect(component.shadowRoot
182
+ ?.querySelector('[data-test="split-menu-button"]')
183
+ ?.classList.contains('large')).to.be.true;
184
+ expect(component.shadowRoot?.querySelector('glide-core-menu')).to.have.attribute('size', 'large');
185
+ component.size = 'small';
186
+ await elementUpdated(component);
187
+ expect(component.shadowRoot
188
+ ?.querySelector('[data-test="primary-action"]')
189
+ ?.assignedNodes()
190
+ ?.at(0)).to.have.attribute('size', 'small');
191
+ expect(component.shadowRoot
192
+ ?.querySelector('[data-test="split-menu-button"]')
193
+ ?.classList.contains('small')).to.be.true;
194
+ expect(component.shadowRoot?.querySelector('glide-core-menu')).to.have.attribute('size', 'small');
195
+ });
196
+ it('applies appropriate classes and sets the "variant" to "primary" by default', async () => {
197
+ const component = await fixture(html `
198
+ <glide-core-split-container menu-label="label">
199
+ <glide-core-split-button slot="primary-action"
200
+ >Button</glide-core-split-button
201
+ >
202
+ <glide-core-menu-link label="One" url="/one"></glide-core-menu-link>
203
+ </glide-core-split-container>
204
+ `);
205
+ expect(component.shadowRoot
206
+ ?.querySelector('[data-test="primary-action"]')
207
+ ?.assignedNodes()
208
+ ?.at(0)).to.have.attribute('variant', 'primary');
209
+ expect(component.shadowRoot
210
+ ?.querySelector('[data-test="split-menu-button"]')
211
+ ?.classList.contains('primary')).to.be.true;
212
+ expect(component.shadowRoot
213
+ ?.querySelector('[data-test="split-divider"]')
214
+ ?.classList.contains('primary')).to.be.true;
215
+ });
216
+ it('applies appropriate classes when "variant" is set to "primary"', async () => {
217
+ const component = await fixture(html `
218
+ <glide-core-split-container menu-label="label" variant="primary">
219
+ <glide-core-split-button slot="primary-action"
220
+ >Button</glide-core-split-button
221
+ >
222
+ <glide-core-menu-link label="One" url="/one"></glide-core-menu-link>
223
+ </glide-core-split-container>
224
+ `);
225
+ expect(component.shadowRoot
226
+ ?.querySelector('[data-test="primary-action"]')
227
+ ?.assignedNodes()
228
+ ?.at(0)).to.have.attribute('variant', 'primary');
229
+ expect(component.shadowRoot
230
+ ?.querySelector('[data-test="split-menu-button"]')
231
+ ?.classList.contains('primary')).to.be.true;
232
+ expect(component.shadowRoot
233
+ ?.querySelector('[data-test="split-divider"]')
234
+ ?.classList.contains('primary')).to.be.true;
235
+ });
236
+ it('applies appropriate classes when "variant" is set to "secondary"', async () => {
237
+ const component = await fixture(html `
238
+ <glide-core-split-container menu-label="label" variant="secondary">
239
+ <glide-core-split-button slot="primary-action"
240
+ >Button</glide-core-split-button
241
+ >
242
+ <glide-core-menu-link label="One" url="/one"></glide-core-menu-link>
243
+ </glide-core-split-container>
244
+ `);
245
+ expect(component.shadowRoot
246
+ ?.querySelector('[data-test="primary-action"]')
247
+ ?.assignedNodes()
248
+ ?.at(0)).to.have.attribute('variant', 'secondary');
249
+ expect(component.shadowRoot
250
+ ?.querySelector('[data-test="split-menu-button"]')
251
+ ?.classList.contains('secondary')).to.be.true;
252
+ expect(component.shadowRoot
253
+ ?.querySelector('[data-test="split-divider"]')
254
+ ?.classList.contains('secondary')).to.be.true;
255
+ });
256
+ it('applies appropriate classes and attributes when "variant" is dynamically changed using the split button', async () => {
257
+ const component = await fixture(html `
258
+ <glide-core-split-container menu-label="label" variant="primary">
259
+ <glide-core-split-button slot="primary-action"
260
+ >Button</glide-core-split-button
261
+ >
262
+ <glide-core-menu-link label="One" url="/one"></glide-core-menu-link>
263
+ </glide-core-split-container>
264
+ `);
265
+ expect(component.shadowRoot
266
+ ?.querySelector('[data-test="primary-action"]')
267
+ ?.assignedNodes()
268
+ ?.at(0)).to.have.attribute('variant', 'primary');
269
+ expect(component.shadowRoot
270
+ ?.querySelector('[data-test="split-menu-button"]')
271
+ ?.classList.contains('primary')).to.be.true;
272
+ expect(component.shadowRoot
273
+ ?.querySelector('[data-test="split-divider"]')
274
+ ?.classList.contains('primary')).to.be.true;
275
+ component.variant = 'secondary';
276
+ await elementUpdated(component);
277
+ expect(component.shadowRoot
278
+ ?.querySelector('[data-test="primary-action"]')
279
+ ?.assignedNodes()
280
+ ?.at(0)).to.have.attribute('variant', 'secondary');
281
+ expect(component.shadowRoot
282
+ ?.querySelector('[data-test="split-menu-button"]')
283
+ ?.classList.contains('secondary')).to.be.true;
284
+ expect(component.shadowRoot
285
+ ?.querySelector('[data-test="split-divider"]')
286
+ ?.classList.contains('secondary')).to.be.true;
287
+ });
288
+ it('applies appropriate classes and attributes when "variant" is dynamically changed using the link button', async () => {
289
+ const component = await fixture(html `
290
+ <glide-core-split-container menu-label="label" variant="primary">
291
+ <glide-core-split-link slot="primary-action" url="/"
292
+ >Button</glide-core-split-link
293
+ >
294
+ <glide-core-menu-link label="One" url="/one"></glide-core-menu-link>
295
+ </glide-core-split-container>
296
+ `);
297
+ expect(component.shadowRoot
298
+ ?.querySelector('[data-test="primary-action"]')
299
+ ?.assignedNodes()
300
+ ?.at(0)).to.have.attribute('variant', 'primary');
301
+ expect(component.shadowRoot
302
+ ?.querySelector('[data-test="split-menu-button"]')
303
+ ?.classList.contains('primary')).to.be.true;
304
+ expect(component.shadowRoot
305
+ ?.querySelector('[data-test="split-divider"]')
306
+ ?.classList.contains('primary')).to.be.true;
307
+ component.variant = 'secondary';
308
+ await elementUpdated(component);
309
+ expect(component.shadowRoot
310
+ ?.querySelector('[data-test="primary-action"]')
311
+ ?.assignedNodes()
312
+ ?.at(0)).to.have.attribute('variant', 'secondary');
313
+ expect(component.shadowRoot
314
+ ?.querySelector('[data-test="split-menu-button"]')
315
+ ?.classList.contains('secondary')).to.be.true;
316
+ expect(component.shadowRoot
317
+ ?.querySelector('[data-test="split-divider"]')
318
+ ?.classList.contains('secondary')).to.be.true;
319
+ });
320
+ it('sets the appropriate classes and attributes when the "disabled" attribute is set', async () => {
321
+ const component = await fixture(html `
322
+ <glide-core-split-container menu-label="label" disabled>
323
+ <glide-core-split-button slot="primary-action"
324
+ >Button</glide-core-split-button
325
+ >
326
+ <glide-core-menu-link label="One" url="/one"></glide-core-menu-link>
327
+ </glide-core-split-container>
328
+ `);
329
+ expect(component.shadowRoot
330
+ ?.querySelector('[data-test="primary-action"]')
331
+ ?.assignedNodes()
332
+ ?.at(0)).to.have.attribute('disabled');
333
+ expect(component.shadowRoot?.querySelector('[data-test="split-menu-button"]')).to.have.attribute('disabled');
334
+ expect(component.shadowRoot?.querySelector('[data-test="split-menu-button"]')).to.have.attribute('disabled');
335
+ });
336
+ it('applies appropriate classes and attributes when "disabled" is dynamically changed using the split button', async () => {
337
+ const component = await fixture(html `
338
+ <glide-core-split-container menu-label="label">
339
+ <glide-core-split-button slot="primary-action"
340
+ >Button</glide-core-split-button
341
+ >
342
+ <glide-core-menu-link label="One" url="/one"></glide-core-menu-link>
343
+ </glide-core-split-container>
344
+ `);
345
+ expect(component.shadowRoot
346
+ ?.querySelector('[data-test="primary-action"]')
347
+ ?.assignedNodes()
348
+ ?.at(0)).to.not.have.attribute('disabled');
349
+ expect(component.shadowRoot?.querySelector('[data-test="split-menu-button"]')).to.not.have.attribute('disabled');
350
+ component.disabled = true;
351
+ await elementUpdated(component);
352
+ expect(component.shadowRoot
353
+ ?.querySelector('[data-test="primary-action"]')
354
+ ?.assignedNodes()
355
+ ?.at(0)).to.have.attribute('disabled');
356
+ expect(component.shadowRoot?.querySelector('[data-test="split-menu-button"]')).to.have.attribute('disabled');
357
+ });
358
+ it('applies appropriate classes and attributes when "disabled" is dynamically changed using the link button', async () => {
359
+ const component = await fixture(html `
360
+ <glide-core-split-container menu-label="label">
361
+ <glide-core-split-link slot="primary-action" url="/"
362
+ >Button</glide-core-split-link
363
+ >
364
+ <glide-core-menu-link label="One" url="/one"></glide-core-menu-link>
365
+ </glide-core-split-container>
366
+ `);
367
+ expect(component.shadowRoot
368
+ ?.querySelector('[data-test="primary-action"]')
369
+ ?.assignedNodes()
370
+ ?.at(0)).to.not.have.attribute('disabled');
371
+ expect(component.shadowRoot?.querySelector('[data-test="split-menu-button"]')).to.not.have.attribute('disabled');
372
+ component.disabled = true;
373
+ await elementUpdated(component);
374
+ expect(component.shadowRoot
375
+ ?.querySelector('[data-test="primary-action"]')
376
+ ?.assignedNodes()
377
+ ?.at(0)).to.have.attribute('disabled');
378
+ expect(component.shadowRoot?.querySelector('[data-test="split-menu-button"]')).to.have.attribute('disabled');
379
+ });
380
+ it('sets the default "menu-placement" as "bottom-end"', async () => {
381
+ const component = await fixture(html `
382
+ <glide-core-split-container menu-label="label">
383
+ <glide-core-split-button slot="primary-action"
384
+ >Button</glide-core-split-button
385
+ >
386
+ <glide-core-menu-link label="One" url="/one"></glide-core-menu-link>
387
+ </glide-core-split-container>
388
+ `);
389
+ expect(component.shadowRoot?.querySelector('glide-core-menu')).to.have.attribute('placement', 'bottom-end');
390
+ });
391
+ it('sets the "menu-placement" attribute as specified', async () => {
392
+ const component = await fixture(html `
393
+ <glide-core-split-container menu-label="label" menu-placement="bottom">
394
+ <glide-core-split-button slot="primary-action"
395
+ >Button</glide-core-split-button
396
+ >
397
+ <glide-core-menu-link label="One" url="/one"></glide-core-menu-link>
398
+ </glide-core-split-container>
399
+ `);
400
+ expect(component.shadowRoot?.querySelector('glide-core-menu')).to.have.attribute('placement', 'bottom');
401
+ });
402
+ it('focuses the "primary-action" slotted element when the container component is focused', async () => {
403
+ const component = await fixture(html `
404
+ <glide-core-split-container menu-label="label" menu-placement="bottom">
405
+ <glide-core-split-button slot="primary-action"
406
+ >Button</glide-core-split-button
407
+ >
408
+ <glide-core-menu-link label="One" url="/one"></glide-core-menu-link>
409
+ </glide-core-split-container>
410
+ `);
411
+ component.focus();
412
+ expect(component.shadowRoot
413
+ ?.querySelector('[data-test="primary-action"]')
414
+ ?.assignedNodes()
415
+ ?.at(0)).to.have.focus;
416
+ });
417
+ it('throws an error when the default slot is empty', async () => {
418
+ await expectArgumentError(() => fixture(html `<glide-core-split-container menu-label="label">
419
+ <glide-core-split-button slot="primary-action"
420
+ >Button</glide-core-split-button
421
+ >
422
+ </glide-core-split-container>`));
423
+ });
424
+ it('throws an error when the default slot is an unsupported type', async () => {
425
+ await expectArgumentError(() => fixture(html `<glide-core-split-container menu-label="label">
426
+ <glide-core-split-button slot="primary-action">
427
+ Button
428
+ </glide-core-split-button>
429
+ <div>Option</div>
430
+ </glide-core-split-container>`));
431
+ const menu = document
432
+ .querySelector('glide-core-split-container')
433
+ ?.shadowRoot?.querySelector('[data-test="menu"]');
434
+ assert(menu);
435
+ const spy = sinon.spy();
436
+ try {
437
+ await menu.updateComplete;
438
+ }
439
+ catch (error) {
440
+ if (error instanceof ArgumentError) {
441
+ spy();
442
+ }
443
+ }
444
+ expect(spy.called).to.be.true;
445
+ });
@@ -0,0 +1 @@
1
+ import './split-container.js';
@@ -0,0 +1,20 @@
1
+ import './split-container.js';
2
+ import { elementUpdated, expect, fixture, html } from '@open-wc/testing';
3
+ import GlideCoreSplitContainer from './split-container.js';
4
+ GlideCoreSplitContainer.shadowRootOptions.mode = 'open';
5
+ it('the menu opens when the menu button is clicked', async () => {
6
+ const component = await fixture(html `
7
+ <glide-core-split-container menu-label="label">
8
+ <glide-core-split-button slot="primary-action"
9
+ >Button</glide-core-split-button
10
+ >
11
+ <glide-core-menu-link label="One" url="/one"></glide-core-menu-link>
12
+ </glide-core-split-container>
13
+ `);
14
+ expect(component.shadowRoot?.querySelector('glide-core-menu')).to.not.have.attribute('open');
15
+ component.shadowRoot
16
+ ?.querySelector('[data-test="split-menu-button"]')
17
+ ?.click();
18
+ await elementUpdated(component);
19
+ expect(component.shadowRoot?.querySelector('glide-core-menu')).to.have.attribute('open');
20
+ });
@@ -0,0 +1,25 @@
1
+ import './menu.js';
2
+ import { LitElement } from 'lit';
3
+ declare global {
4
+ interface HTMLElementTagNameMap {
5
+ 'glide-core-split-link': GlideCoreSplitLink;
6
+ }
7
+ }
8
+ /**
9
+ * @description - A link to be used in the `primary-action` slot of `glide-core-split-container`.
10
+ *
11
+ * @slot prefix - An optional icon slot to display before the label.
12
+ * @slot - A label for the contents of the link.
13
+ */
14
+ export default class GlideCoreSplitLink extends LitElement {
15
+ #private;
16
+ static shadowRootOptions: ShadowRootInit;
17
+ static styles: import("lit").CSSResult[];
18
+ url?: string;
19
+ disabled: boolean;
20
+ variant: 'primary' | 'secondary';
21
+ size: 'large' | 'small';
22
+ firstUpdated(): void;
23
+ render(): import("lit").TemplateResult<1>;
24
+ private hasPrefixSlot;
25
+ }
@@ -0,0 +1 @@
1
+ var __decorate=this&&this.__decorate||function(e,t,o,l){var i,s=arguments.length,r=s<3?t:null===l?l=Object.getOwnPropertyDescriptor(t,o):l;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(e,t,o,l);else for(var a=e.length-1;a>=0;a--)(i=e[a])&&(r=(s<3?i(r):s>3?i(t,o,r):i(t,o))||r);return s>3&&r&&Object.defineProperty(t,o,r),r};import"./menu.js";import{LitElement,html}from"lit";import{classMap}from"lit/directives/class-map.js";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property,state}from"lit/decorators.js";import{ifDefined}from"lit/directives/if-defined.js";import{owSlot,owSlotType}from"./library/ow.js";import styles from"./split-button.styles.js";let GlideCoreSplitLink=class GlideCoreSplitLink extends LitElement{constructor(){super(...arguments),this.disabled=!1,this.variant="primary",this.size="large",this.hasPrefixSlot=!1,this.#e=createRef(),this.#t=createRef()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,delegatesFocus:!0,mode:"closed"}}static{this.styles=styles}firstUpdated(){owSlot(this.#e.value),owSlotType(this.#e.value,[Text])}render(){return this.disabled?html`<span class="${classMap({component:!0,disabled:!0,[this.variant]:!0,[this.size]:!0,"has-prefix":this.hasPrefixSlot})}" aria-disabled="true" role="link" @keydown="${this.#o}" data-test="split-link"><slot name="prefix" @slotchange="${this.#l}" ${ref(this.#t)} data-test="prefix-slot"></slot><slot @slotchange="${this.#i}" ${ref(this.#e)} data-test="default-slot"></slot></span>`:html`<a href="${ifDefined(this.url)}" class="${classMap({component:!0,[this.variant]:!0,[this.size]:!0,"has-prefix":this.hasPrefixSlot})}" @keydown="${this.#o}" data-test="split-link"><slot name="prefix" @slotchange="${this.#l}" ${ref(this.#t)} data-test="prefix-slot"></slot><slot @slotchange="${this.#i}" ${ref(this.#e)} data-test="default-slot"></slot></a>`}#e;#t;#i(){owSlot(this.#e.value),owSlotType(this.#e.value,[Text])}#o(e){" "===e.key&&this.url?.length&&window.open(this.url)}#l(){const e=this.#t.value?.assignedNodes();this.hasPrefixSlot=!!(e&&e.length>0)}};__decorate([property({reflect:!0})],GlideCoreSplitLink.prototype,"url",void 0),__decorate([property({type:Boolean,reflect:!0})],GlideCoreSplitLink.prototype,"disabled",void 0),__decorate([property({reflect:!0})],GlideCoreSplitLink.prototype,"variant",void 0),__decorate([property({reflect:!0})],GlideCoreSplitLink.prototype,"size",void 0),__decorate([state()],GlideCoreSplitLink.prototype,"hasPrefixSlot",void 0),GlideCoreSplitLink=__decorate([customElement("glide-core-split-link")],GlideCoreSplitLink);export default GlideCoreSplitLink;
@@ -0,0 +1 @@
1
+ import './split-link.js';