@crowdstrike/glide-core 0.5.1 → 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 (242) hide show
  1. package/README.md +11 -1
  2. package/dist/accordion.js +1 -1
  3. package/dist/accordion.styles.js +5 -4
  4. package/dist/accordion.test.basics.js +109 -0
  5. package/dist/accordion.test.events.js +39 -0
  6. package/dist/button-group.button.js +1 -1
  7. package/dist/button-group.button.styles.js +6 -5
  8. package/dist/button-group.button.test.basics.js +169 -0
  9. package/dist/button-group.button.test.events.js +73 -0
  10. package/dist/button-group.js +1 -1
  11. package/dist/button-group.styles.js +3 -3
  12. package/dist/button-group.test.basics.js +268 -0
  13. package/dist/button-group.test.events.js +291 -0
  14. package/dist/button.d.ts +3 -2
  15. package/dist/button.js +1 -1
  16. package/dist/button.styles.js +5 -5
  17. package/dist/button.test.basics.js +202 -0
  18. package/dist/button.test.events.js +25 -0
  19. package/dist/button.test.form.js +49 -0
  20. package/dist/checkbox-group.js +1 -1
  21. package/dist/checkbox-group.styles.js +2 -2
  22. package/dist/checkbox-group.test.basics.js +119 -0
  23. package/dist/checkbox-group.test.events.js +110 -0
  24. package/dist/checkbox-group.test.focus.js +45 -0
  25. package/dist/checkbox-group.test.form.js +130 -0
  26. package/dist/checkbox-group.test.validity.js +75 -0
  27. package/dist/checkbox.js +1 -1
  28. package/dist/checkbox.styles.js +7 -4
  29. package/dist/checkbox.test.basics.js +89 -0
  30. package/dist/checkbox.test.events.js +87 -0
  31. package/dist/checkbox.test.focus.js +38 -0
  32. package/dist/checkbox.test.form.js +115 -0
  33. package/dist/checkbox.test.states.js +62 -0
  34. package/dist/checkbox.test.validity.js +51 -0
  35. package/dist/drawer.d.ts +2 -2
  36. package/dist/drawer.js +1 -15
  37. package/dist/drawer.styles.js +14 -4
  38. package/dist/drawer.test.accessibility.js +22 -0
  39. package/dist/drawer.test.basics.js +43 -0
  40. package/dist/drawer.test.closing.js +37 -0
  41. package/dist/drawer.test.events.js +52 -0
  42. package/dist/drawer.test.floating-components.d.ts +1 -0
  43. package/dist/drawer.test.floating-components.js +51 -0
  44. package/dist/drawer.test.methods.js +34 -0
  45. package/dist/dropdown.d.ts +4 -2
  46. package/dist/dropdown.js +1 -1
  47. package/dist/dropdown.option.d.ts +0 -2
  48. package/dist/dropdown.option.js +1 -1
  49. package/dist/dropdown.option.styles.js +2 -2
  50. package/dist/dropdown.option.test.basics.js +59 -0
  51. package/dist/dropdown.option.test.basics.multiple.js +26 -0
  52. package/dist/dropdown.option.test.basics.single.js +20 -0
  53. package/dist/dropdown.option.test.events.js +27 -0
  54. package/dist/dropdown.option.test.focus.js +11 -0
  55. package/dist/dropdown.option.test.interactions.multiple.js +82 -0
  56. package/dist/dropdown.option.test.interactions.single.js +22 -0
  57. package/dist/dropdown.styles.js +26 -6
  58. package/dist/dropdown.test.basics.filterable.js +84 -0
  59. package/dist/dropdown.test.basics.js +233 -0
  60. package/dist/dropdown.test.basics.multiple.js +270 -0
  61. package/dist/dropdown.test.basics.single.js +79 -0
  62. package/dist/dropdown.test.events.js +268 -0
  63. package/dist/dropdown.test.events.multiple.js +130 -0
  64. package/dist/dropdown.test.focus.d.ts +1 -0
  65. package/dist/dropdown.test.focus.filterable.js +154 -0
  66. package/dist/dropdown.test.focus.js +28 -0
  67. package/dist/dropdown.test.focus.multiple.js +181 -0
  68. package/dist/dropdown.test.focus.single.js +53 -0
  69. package/dist/dropdown.test.form.js +140 -0
  70. package/dist/dropdown.test.form.multiple.js +149 -0
  71. package/dist/dropdown.test.form.single.js +128 -0
  72. package/dist/dropdown.test.interactions.filterable.js +449 -0
  73. package/dist/dropdown.test.interactions.js +446 -0
  74. package/dist/dropdown.test.interactions.multiple.js +908 -0
  75. package/dist/dropdown.test.interactions.single.js +466 -0
  76. package/dist/dropdown.test.validity.js +46 -0
  77. package/dist/icon-button.d.ts +3 -2
  78. package/dist/icon-button.js +1 -1
  79. package/dist/icon-button.styles.js +12 -12
  80. package/dist/icon-button.test.basics.js +110 -0
  81. package/dist/icons/checked.js +1 -1
  82. package/dist/icons/magnifying-glass.js +1 -1
  83. package/dist/input.js +1 -1
  84. package/dist/input.styles.js +4 -3
  85. package/dist/input.test.basics.js +169 -0
  86. package/dist/input.test.events.js +97 -0
  87. package/dist/input.test.focus.js +54 -0
  88. package/dist/input.test.form.js +56 -0
  89. package/dist/input.test.validity.js +50 -0
  90. package/dist/label.js +1 -1
  91. package/dist/label.styles.js +13 -15
  92. package/dist/label.test.basics.js +129 -0
  93. package/dist/library/expect-argument-error.js +1 -1
  94. package/dist/library/localize.d.ts +17 -0
  95. package/dist/library/localize.js +1 -0
  96. package/dist/library/ow.js +1 -1
  97. package/dist/library/ow.test.js +55 -0
  98. package/dist/library/set-containing-block.d.ts +15 -0
  99. package/dist/library/set-containing-block.js +1 -0
  100. package/dist/menu.button.d.ts +1 -2
  101. package/dist/menu.button.js +1 -1
  102. package/dist/menu.button.styles.js +3 -3
  103. package/dist/menu.button.test.basics.js +42 -0
  104. package/dist/menu.d.ts +7 -2
  105. package/dist/menu.js +1 -1
  106. package/dist/menu.link.d.ts +1 -2
  107. package/dist/menu.link.js +1 -1
  108. package/dist/menu.link.styles.js +3 -3
  109. package/dist/menu.link.test.basics.js +46 -0
  110. package/dist/menu.options.d.ts +22 -0
  111. package/dist/menu.options.js +1 -0
  112. package/dist/menu.options.styles.d.ts +2 -0
  113. package/dist/menu.options.styles.js +33 -0
  114. package/dist/menu.options.test.basics.d.ts +2 -0
  115. package/dist/menu.options.test.basics.js +43 -0
  116. package/dist/menu.stories.d.ts +1 -0
  117. package/dist/menu.styles.js +7 -31
  118. package/dist/menu.test.basics.d.ts +1 -0
  119. package/dist/menu.test.basics.js +183 -0
  120. package/dist/menu.test.focus.d.ts +0 -1
  121. package/dist/menu.test.focus.js +84 -0
  122. package/dist/menu.test.interactions.d.ts +1 -1
  123. package/dist/menu.test.interactions.js +664 -0
  124. package/dist/modal.icon-button.js +1 -1
  125. package/dist/modal.icon-button.styles.js +2 -2
  126. package/dist/modal.icon-button.test.basics.js +45 -0
  127. package/dist/modal.js +1 -15
  128. package/dist/modal.styles.js +4 -7
  129. package/dist/modal.tertiary-icon.d.ts +1 -0
  130. package/dist/modal.tertiary-icon.js +1 -1
  131. package/dist/modal.tertiary-icon.test.basics.js +59 -0
  132. package/dist/modal.test.accessibility.js +48 -0
  133. package/dist/modal.test.basics.js +203 -0
  134. package/dist/modal.test.close.js +38 -0
  135. package/dist/modal.test.events.js +110 -0
  136. package/dist/modal.test.floating-components.d.ts +1 -0
  137. package/dist/modal.test.floating-components.js +62 -0
  138. package/dist/modal.test.lock-scroll.js +76 -0
  139. package/dist/modal.test.methods.js +23 -0
  140. package/dist/modal.test.scrollbars.js +19 -0
  141. package/dist/radio-group.js +1 -1
  142. package/dist/radio-group.styles.js +20 -24
  143. package/dist/radio-group.test.basics.js +323 -0
  144. package/dist/radio-group.test.events.js +277 -0
  145. package/dist/radio-group.test.focus.js +75 -0
  146. package/dist/radio-group.test.form.js +104 -0
  147. package/dist/radio-group.test.validity.js +228 -0
  148. package/dist/radio.js +1 -1
  149. package/dist/radio.styles.js +14 -31
  150. package/dist/split-button.d.ts +27 -0
  151. package/dist/split-button.js +1 -0
  152. package/dist/split-button.stories.d.ts +17 -0
  153. package/dist/split-button.styles.d.ts +2 -0
  154. package/dist/split-button.styles.js +102 -0
  155. package/dist/split-button.test.basics.d.ts +1 -0
  156. package/dist/split-button.test.basics.js +99 -0
  157. package/dist/split-container.d.ts +31 -0
  158. package/dist/split-container.js +1 -0
  159. package/dist/split-container.styles.d.ts +2 -0
  160. package/dist/split-container.styles.js +134 -0
  161. package/dist/split-container.test.basics.d.ts +3 -0
  162. package/dist/split-container.test.basics.js +440 -0
  163. package/dist/split-container.test.interactions.d.ts +1 -0
  164. package/dist/split-container.test.interactions.js +20 -0
  165. package/dist/split-link.d.ts +25 -0
  166. package/dist/split-link.js +1 -0
  167. package/dist/split-link.test.basics.d.ts +1 -0
  168. package/dist/split-link.test.basics.js +92 -0
  169. package/dist/split-link.test.interactions.d.ts +1 -0
  170. package/dist/split-link.test.interactions.js +19 -0
  171. package/dist/status-indicator.js +1 -1
  172. package/dist/status-indicator.styles.js +2 -2
  173. package/dist/status-indicator.test.basics.js +102 -0
  174. package/dist/styles/focus-outline.js +1 -4
  175. package/dist/styles/variables.css +1 -1
  176. package/dist/styles/visually-hidden.js +1 -11
  177. package/dist/tab.group.js +1 -1
  178. package/dist/tab.group.styles.js +2 -2
  179. package/dist/tab.group.test.basics.js +185 -0
  180. package/dist/tab.js +1 -1
  181. package/dist/tab.panel.js +1 -1
  182. package/dist/tab.panel.styles.js +3 -3
  183. package/dist/tab.styles.js +80 -55
  184. package/dist/tab.test.basics.js +71 -0
  185. package/dist/tag.js +1 -1
  186. package/dist/tag.styles.js +4 -3
  187. package/dist/tag.test.basics.js +118 -0
  188. package/dist/tag.test.events.js +16 -0
  189. package/dist/tag.test.focus.js +11 -0
  190. package/dist/tag.test.translations.d.ts +1 -0
  191. package/dist/tag.test.translations.js +25 -0
  192. package/dist/textarea.js +2 -2
  193. package/dist/textarea.styles.js +5 -4
  194. package/dist/textarea.test.basics.js +140 -0
  195. package/dist/textarea.test.events.js +204 -0
  196. package/dist/textarea.test.form.js +70 -0
  197. package/dist/textarea.test.validity.js +83 -0
  198. package/dist/toasts.js +1 -1
  199. package/dist/toasts.styles.js +2 -2
  200. package/dist/toasts.test.basics.js +94 -0
  201. package/dist/toasts.toast.js +1 -1
  202. package/dist/toasts.toast.styles.js +5 -2
  203. package/dist/toasts.toast.test.basics.js +139 -0
  204. package/dist/toggle.js +1 -1
  205. package/dist/toggle.styles.js +3 -3
  206. package/dist/toggle.test.basics.js +68 -0
  207. package/dist/toggle.test.events.js +29 -0
  208. package/dist/toggle.test.focus.js +9 -0
  209. package/dist/toggle.test.states.js +43 -0
  210. package/dist/tooltip.d.ts +2 -0
  211. package/dist/tooltip.js +1 -1
  212. package/dist/tooltip.styles.js +5 -3
  213. package/dist/tooltip.test.basics.js +64 -0
  214. package/dist/tooltip.test.interactions.js +78 -0
  215. package/dist/translations/en.d.ts +3 -0
  216. package/dist/translations/en.js +1 -0
  217. package/dist/translations/fr.d.ts +3 -0
  218. package/dist/translations/fr.js +1 -0
  219. package/dist/translations/ja.d.ts +3 -0
  220. package/dist/translations/ja.js +1 -0
  221. package/dist/tree.d.ts +1 -0
  222. package/dist/tree.item.d.ts +3 -1
  223. package/dist/tree.item.icon-button.js +1 -1
  224. package/dist/tree.item.icon-button.styles.js +2 -2
  225. package/dist/tree.item.icon-button.test.basics.js +13 -0
  226. package/dist/tree.item.js +1 -1
  227. package/dist/tree.item.menu.d.ts +2 -0
  228. package/dist/tree.item.menu.js +1 -1
  229. package/dist/tree.item.menu.styles.js +2 -2
  230. package/dist/tree.item.menu.test.basics.js +33 -0
  231. package/dist/tree.item.styles.js +23 -8
  232. package/dist/tree.item.test.basics.js +102 -0
  233. package/dist/tree.js +1 -1
  234. package/dist/tree.stories.d.ts +1 -0
  235. package/dist/tree.styles.js +2 -2
  236. package/dist/tree.test.aria.js +86 -0
  237. package/dist/tree.test.basics.js +123 -0
  238. package/dist/tree.test.events.js +19 -0
  239. package/dist/tree.test.focus.js +261 -0
  240. package/package.json +25 -18
  241. /package/dist/{dropdown.option.test.focus.multiple.d.ts → dropdown.option.test.focus.d.ts} +0 -0
  242. /package/dist/{dropdown.option.test.focus.single.d.ts → dropdown.test.events.multiple.d.ts} +0 -0
@@ -1,8 +1,9 @@
1
- "use strict";import{css as o}from"lit";export default[o`
1
+ import{css}from"lit";export default[css`
2
2
  .component {
3
3
  align-items: center;
4
4
  border-radius: var(--glide-core-spacing-sm);
5
5
  box-shadow: var(--glide-core-shadow-lg);
6
+ color: var(--glide-core-text-body-2);
6
7
  column-gap: var(--glide-core-spacing-xs);
7
8
  display: grid;
8
9
  font-family: var(--glide-core-body-xs-font-family);
@@ -51,10 +52,12 @@
51
52
  }
52
53
 
53
54
  .close-button {
55
+ --icon-color: var(--glide-core-icon-default2);
56
+
54
57
  grid-column: 3;
55
58
  }
56
59
 
57
60
  .description {
58
61
  grid-column: 2;
59
62
  }
60
- `];
63
+ `];
@@ -0,0 +1,139 @@
1
+ import { assert, expect, fixture, html } from '@open-wc/testing';
2
+ import GlideCoreToast from './toasts.toast.js';
3
+ import sinon from 'sinon';
4
+ GlideCoreToast.shadowRootOptions.mode = 'open';
5
+ // NOTE: Due to https://github.com/modernweb-dev/web/issues/2520, we sometimes need
6
+ // to manually dispatch the `transitionend` event in tests.
7
+ it('registers', async () => {
8
+ expect(window.customElements.get('glide-core-toast')).to.equal(GlideCoreToast);
9
+ });
10
+ it('is accessible', async () => {
11
+ const component = await fixture(html `<glide-core-toast
12
+ variant="informational"
13
+ label="Label"
14
+ description="Toast description"
15
+ ></glide-core-toast>`);
16
+ await expect(component).to.be.accessible();
17
+ });
18
+ it('sets correct role', async () => {
19
+ const component = await fixture(html `<glide-core-toast
20
+ variant="informational"
21
+ label="Label"
22
+ description="Toast description"
23
+ ></glide-core-toast>`);
24
+ expect(component.shadowRoot?.firstElementChild?.getAttribute('role')).to.equal('alert');
25
+ });
26
+ it('sets correct aria labelling', async () => {
27
+ const component = await fixture(html `<glide-core-toast
28
+ variant="informational"
29
+ label="Label"
30
+ description="Toast description"
31
+ ></glide-core-toast>`);
32
+ expect(component.shadowRoot?.firstElementChild?.getAttribute('aria-labelledby')).to.equal('label description');
33
+ expect(component.shadowRoot?.firstElementChild?.querySelector('#label')
34
+ ?.textContent).to.equal('Label');
35
+ expect(component.shadowRoot?.firstElementChild?.querySelector('#description')
36
+ ?.textContent).to.equal('Toast description');
37
+ });
38
+ it('sets variant, label, and description', async () => {
39
+ const component = await fixture(html `<glide-core-toast
40
+ variant="informational"
41
+ label="Label"
42
+ description="Toast description"
43
+ ></glide-core-toast>`);
44
+ await expect(component.variant).to.equal('informational');
45
+ await expect(component.label).to.equal('Label');
46
+ await expect(component.description).to.equal('Toast description');
47
+ });
48
+ it('opens and closes by default', async () => {
49
+ const clock = sinon.useFakeTimers();
50
+ const component = await fixture(html `<glide-core-toast
51
+ variant="informational"
52
+ label="Label"
53
+ description="Toast description"
54
+ ></glide-core-toast>`);
55
+ clock.tick(3000);
56
+ const shadowElement = component.shadowRoot.firstElementChild;
57
+ await expect([...shadowElement.classList]).to.deep.equal([
58
+ 'component',
59
+ 'informational',
60
+ 'open',
61
+ ]);
62
+ clock.tick(3000);
63
+ shadowElement?.dispatchEvent(new TransitionEvent('transitionend'));
64
+ await expect([
65
+ ...component.shadowRoot.firstElementChild.classList,
66
+ ]).to.deep.equal(['component', 'informational', 'closed']);
67
+ clock.restore();
68
+ });
69
+ it('responds to duration', async () => {
70
+ const clock = sinon.useFakeTimers();
71
+ const component = await fixture(html `<glide-core-toast
72
+ variant="informational"
73
+ label="Label"
74
+ description="Toast description"
75
+ duration="10000"
76
+ ></glide-core-toast>`);
77
+ clock.tick(9500);
78
+ const shadowElement = component.shadowRoot.firstElementChild;
79
+ await expect([...shadowElement.classList]).to.deep.equal([
80
+ 'component',
81
+ 'informational',
82
+ 'open',
83
+ ]);
84
+ clock.tick(1000);
85
+ shadowElement?.dispatchEvent(new TransitionEvent('transitionend'));
86
+ await expect([
87
+ ...component.shadowRoot.firstElementChild.classList,
88
+ ]).to.deep.equal(['component', 'informational', 'closed']);
89
+ clock.restore();
90
+ });
91
+ it('responds to duration of Infinity', async () => {
92
+ const clock = sinon.useFakeTimers();
93
+ const component = await fixture(html `<glide-core-toast
94
+ variant="informational"
95
+ label="Label"
96
+ description="Toast description"
97
+ duration="Infinity"
98
+ ></glide-core-toast>`);
99
+ clock.tick(9500);
100
+ const shadowElement = component.shadowRoot.firstElementChild;
101
+ await expect([...shadowElement.classList]).to.deep.equal([
102
+ 'component',
103
+ 'informational',
104
+ 'open',
105
+ ]);
106
+ clock.restore();
107
+ });
108
+ it('does not allow less than 5000 duration', async () => {
109
+ const clock = sinon.useFakeTimers();
110
+ const component = await fixture(html `<glide-core-toast
111
+ variant="informational"
112
+ label="Label"
113
+ description="Toast description"
114
+ duration="3000"
115
+ ></glide-core-toast>`);
116
+ clock.tick(4000);
117
+ const shadowElement = component.shadowRoot.firstElementChild;
118
+ await expect([...shadowElement.classList]).to.deep.equal([
119
+ 'component',
120
+ 'informational',
121
+ 'open',
122
+ ]);
123
+ clock.restore();
124
+ });
125
+ it('can be closed by clicking on the x icon', async () => {
126
+ const component = await fixture(html `<glide-core-toast
127
+ variant="informational"
128
+ label="Label"
129
+ description="Toast description"
130
+ ></glide-core-toast>`);
131
+ const shadowElement = component.shadowRoot.firstElementChild;
132
+ const closeButton = shadowElement?.querySelector('glide-core-icon-button[label="Close"]');
133
+ assert(closeButton);
134
+ closeButton.click();
135
+ shadowElement?.dispatchEvent(new TransitionEvent('transitionend'));
136
+ await expect([
137
+ ...component.shadowRoot.firstElementChild.classList,
138
+ ]).to.deep.equal(['component', 'informational', 'closed']);
139
+ });
package/dist/toggle.js CHANGED
@@ -1 +1 @@
1
- "use strict";var y=Object.defineProperty;var E=Object.getOwnPropertyDescriptor;var a=(i,e,t,l)=>{for(var o=l>1?void 0:l?E(e,t):e,p=i.length-1,m;p>=0;p--)(m=i[p])&&(o=(l?m(e,t,o):m(o))||o);return l&&o&&y(e,t,o),o};var u=(i,e,t)=>{if(!e.has(i))throw TypeError("Cannot "+t)};var c=(i,e,t)=>(u(i,e,"read from private field"),t?t.call(i):e.get(i)),h=(i,e,t)=>{if(e.has(i))throw TypeError("Cannot add the same private member more than once");e instanceof WeakSet?e.add(i):e.set(i,t)};var f=(i,e,t)=>(u(i,e,"access private method"),t);var n,d,v;import"./label.js";import{LitElement as b,html as $}from"lit";import{createRef as k,ref as L}from"lit/directives/ref.js";import{customElement as R,property as r}from"lit/decorators.js";import w from"./toggle.styles.js";let s=class extends b{constructor(){super(...arguments);h(this,d);this.checked=!1;this.disabled=!1;this.hideLabel=!1;this.orientation="horizontal";h(this,n,k())}click(){c(this,n).value?.click()}focus(t){c(this,n).value?.focus(t)}render(){return $`<div data-test="component"><glide-core-label orientation="${this.orientation}" ?disabled="${this.disabled}" ?hide="${this.hideLabel}"><slot name="tooltip" slot="tooltip"></slot><label for="input">${this.label}</label><div class="toggle-and-input" slot="control"><input aria-describedby="summary description" data-test="input" id="input" type="checkbox" ?checked="${this.checked}" ?disabled="${this.disabled}" @change="${f(this,d,v)}" ${L(c(this,n))}></div><div slot="summary" id="summary">${this.summary}</div><slot class="description" id="description" name="description" slot="description"></slot></glide-core-label></div>`}};n=new WeakMap,d=new WeakSet,v=function(t){t.target instanceof HTMLInputElement&&(this.checked=t.target.checked),this.dispatchEvent(new Event(t.type,t))},s.shadowRootOptions={...b.shadowRootOptions,mode:"closed"},s.styles=w,a([r({type:Boolean})],s.prototype,"checked",2),a([r({reflect:!0,type:Boolean})],s.prototype,"disabled",2),a([r({attribute:"hide-label",type:Boolean})],s.prototype,"hideLabel",2),a([r({reflect:!0})],s.prototype,"label",2),a([r({reflect:!0})],s.prototype,"orientation",2),a([r({reflect:!0})],s.prototype,"name",2),a([r({reflect:!0})],s.prototype,"summary",2),s=a([R("glide-core-toggle")],s);export{s as default};
1
+ var __decorate=this&&this.__decorate||function(e,t,o,i){var l,r=arguments.length,s=r<3?t:null===i?i=Object.getOwnPropertyDescriptor(t,o):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,o,i);else for(var d=e.length-1;d>=0;d--)(l=e[d])&&(s=(r<3?l(s):r>3?l(t,o,s):l(t,o))||s);return r>3&&s&&Object.defineProperty(t,o,s),s};import"./label.js";import{LitElement,html}from"lit";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property}from"lit/decorators.js";import styles from"./toggle.styles.js";let GlideCoreToggle=class GlideCoreToggle extends LitElement{constructor(){super(...arguments),this.checked=!1,this.disabled=!1,this.hideLabel=!1,this.orientation="horizontal",this.#e=createRef()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}click(){this.#e.value?.click()}focus(e){this.#e.value?.focus(e)}render(){return html`<div data-test="component"><glide-core-label orientation="${this.orientation}" ?disabled="${this.disabled}" ?hide="${this.hideLabel}"><slot name="tooltip" slot="tooltip"></slot><label for="input">${this.label}</label><div class="toggle-and-input" slot="control"><input aria-checked="${this.checked}" aria-describedby="summary description" data-test="input" id="input" role="switch" type="checkbox" ?checked="${this.checked}" ?disabled="${this.disabled}" @change="${this.#t}" ${ref(this.#e)}></div><div slot="summary" id="summary">${this.summary}</div><slot class="description" id="description" name="description" slot="description"></slot></glide-core-label></div>`}#e;#t(e){e.target instanceof HTMLInputElement&&(this.checked=e.target.checked),this.dispatchEvent(new Event(e.type,e))}};__decorate([property({type:Boolean})],GlideCoreToggle.prototype,"checked",void 0),__decorate([property({reflect:!0,type:Boolean})],GlideCoreToggle.prototype,"disabled",void 0),__decorate([property({attribute:"hide-label",type:Boolean})],GlideCoreToggle.prototype,"hideLabel",void 0),__decorate([property({reflect:!0})],GlideCoreToggle.prototype,"label",void 0),__decorate([property({reflect:!0})],GlideCoreToggle.prototype,"orientation",void 0),__decorate([property({reflect:!0})],GlideCoreToggle.prototype,"name",void 0),__decorate([property({reflect:!0})],GlideCoreToggle.prototype,"summary",void 0),GlideCoreToggle=__decorate([customElement("glide-core-toggle")],GlideCoreToggle);export default GlideCoreToggle;
@@ -1,4 +1,4 @@
1
- "use strict";import{css as e}from"lit";import s from"./styles/focus-outline.js";export default[e`
1
+ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export default[css`
2
2
  /*
3
3
  Most states are handled on the host. But ":checked" is handled on the input
4
4
  because browsers don't support that class on the host. And using attribute
@@ -30,7 +30,7 @@ Use the ":checked" pseudo class on the host and throughout when browsers support
30
30
  position: relative;
31
31
 
32
32
  &:has(input:focus-visible) {
33
- ${s};
33
+ ${focusOutline};
34
34
  outline-offset: 4px;
35
35
  }
36
36
 
@@ -78,4 +78,4 @@ Use the ":checked" pseudo class on the host and throughout when browsers support
78
78
  opacity: 0;
79
79
  position: absolute;
80
80
  }
81
- `];
81
+ `];
@@ -0,0 +1,68 @@
1
+ import { expect, fixture, html } from '@open-wc/testing';
2
+ import GlideCoreToggle from './toggle.js';
3
+ GlideCoreToggle.shadowRootOptions.mode = 'open';
4
+ it('registers', async () => {
5
+ expect(window.customElements.get('glide-core-toggle')).to.equal(GlideCoreToggle);
6
+ });
7
+ it('has defaults', async () => {
8
+ const component = await fixture(html `<glide-core-toggle label="Label"></glide-core-toggle>`);
9
+ expect(component.hasAttribute('checked')).to.be.false;
10
+ expect(component.checked).to.be.false;
11
+ const input = component.shadowRoot?.querySelector('[data-test="input"]');
12
+ expect(input?.getAttribute('aria-checked')).to.equal('false');
13
+ expect(component.hasAttribute('disabled')).to.be.false;
14
+ expect(component.disabled).to.be.false;
15
+ expect(component.hasAttribute('hide-label')).to.be.false;
16
+ expect(component.hideLabel).to.be.false;
17
+ expect(component.getAttribute('orientation')).to.equal('horizontal');
18
+ expect(component.orientation).to.equal('horizontal');
19
+ expect(component.getAttribute('summary')).to.be.null;
20
+ expect(component.summary).to.equal(undefined);
21
+ });
22
+ it('is accessible', async () => {
23
+ const component = await fixture(html `<glide-core-toggle label="Label">
24
+ <div slot="tooltip">Tooltip</div>
25
+ <div slot="description">Description</div>
26
+ </glide-core-toggle>`);
27
+ await expect(component).to.be.accessible();
28
+ });
29
+ it('can have a label', async () => {
30
+ const component = await fixture(html `<glide-core-toggle label="Label"></glide-core-toggle> `);
31
+ expect(component.getAttribute('label')).to.equal('Label');
32
+ expect(component.label).to.equal('Label');
33
+ });
34
+ it('can have a description', async () => {
35
+ const component = await fixture(html `<glide-core-toggle label="Label">
36
+ <div slot="description">Description</div>
37
+ </glide-core-toggle>`);
38
+ const assignedElements = component.shadowRoot
39
+ ?.querySelector('slot[name="description"]')
40
+ ?.assignedElements();
41
+ expect(assignedElements?.at(0)?.textContent).to.equal('Description');
42
+ });
43
+ it('can have a summary', async () => {
44
+ const component = await fixture(html `<glide-core-toggle summary="Summary"></glide-core-toggle> `);
45
+ expect(component.getAttribute('summary')).to.equal('Summary');
46
+ expect(component.summary).to.equal('Summary');
47
+ });
48
+ it('can have a tooltip', async () => {
49
+ const component = await fixture(html `<glide-core-toggle label="Label">
50
+ <div slot="tooltip">Tooltip</div>
51
+ </glide-core-toggle>`);
52
+ const assignedElements = component.shadowRoot
53
+ ?.querySelector('slot[name="tooltip"]')
54
+ ?.assignedElements();
55
+ expect(assignedElements?.at(0)?.textContent).to.equal('Tooltip');
56
+ });
57
+ it('can be checked', async () => {
58
+ const component = await fixture(html `<glide-core-toggle checked></glide-core-toggle> `);
59
+ expect(component.hasAttribute('checked')).to.be.true;
60
+ expect(component.checked).to.equal(true);
61
+ const input = component.shadowRoot?.querySelector('[data-test="input"]');
62
+ expect(input?.getAttribute('aria-checked')).to.equal('true');
63
+ });
64
+ it('can be disabled', async () => {
65
+ const component = await fixture(html `<glide-core-toggle disabled></glide-core-toggle> `);
66
+ expect(component.hasAttribute('disabled')).to.be.true;
67
+ expect(component.disabled).to.equal(true);
68
+ });
@@ -0,0 +1,29 @@
1
+ import { expect, fixture, html, oneEvent } from '@open-wc/testing';
2
+ import GlideCoreToggle from './toggle.js';
3
+ GlideCoreToggle.shadowRootOptions.mode = 'open';
4
+ // `await aTimeout(0)` is used throughout. Using `oneEvent` instead and
5
+ // expecting it to throw would work. But it wouldn't throw until its
6
+ // timeout, which would make for a slow test. Its timeout can likely be
7
+ // configured. But waiting a turn of the event loop, after which the event
8
+ // will have been dispatched, gets the job done as well.
9
+ it('dispatches a "click" event when clicked', async () => {
10
+ const component = await fixture(html `<glide-core-toggle label="Label"></glide-core-toggle>`);
11
+ setTimeout(() => component.click());
12
+ const event = await oneEvent(component, 'click');
13
+ expect(event instanceof PointerEvent).to.be.true;
14
+ expect(event.bubbles).to.be.true;
15
+ });
16
+ it('dispatches a "change" event when clicked', async () => {
17
+ const component = await fixture(html `<glide-core-toggle label="Label"></glide-core-toggle>`);
18
+ setTimeout(() => component.click());
19
+ const event = await oneEvent(component, 'change');
20
+ expect(event instanceof Event).to.be.true;
21
+ expect(event.bubbles).to.be.true;
22
+ });
23
+ it('dispatches an "input" event when clicked', async () => {
24
+ const component = await fixture(html `<glide-core-toggle label="Label"></glide-core-toggle>`);
25
+ setTimeout(() => component.click());
26
+ const event = await oneEvent(component, 'input');
27
+ expect(event instanceof Event).to.be.true;
28
+ expect(event.bubbles).to.be.true;
29
+ });
@@ -0,0 +1,9 @@
1
+ import { expect, fixture, html } from '@open-wc/testing';
2
+ import GlideCoreToggle from './toggle.js';
3
+ GlideCoreToggle.shadowRootOptions.mode = 'open';
4
+ it('focuses the input when `focus` is called', async () => {
5
+ const component = await fixture(html `<glide-core-toggle label="Label"></glide-core-toggle>`);
6
+ component.focus();
7
+ const input = component.shadowRoot?.querySelector('[data-test="input"]');
8
+ expect(component.shadowRoot?.activeElement).to.equal(input);
9
+ });
@@ -0,0 +1,43 @@
1
+ import { elementUpdated, expect, fixture, html } from '@open-wc/testing';
2
+ import GlideCoreToggle from './toggle.js';
3
+ GlideCoreToggle.shadowRootOptions.mode = 'open';
4
+ it('is checked after being clicked', async () => {
5
+ const component = await fixture(html `<glide-core-toggle label="Label"></glide-core-toggle>`);
6
+ component.click();
7
+ await elementUpdated(component);
8
+ expect(component.checked).to.equal(true);
9
+ expect(component.hasAttribute('checked')).to.be.false;
10
+ const input = component.shadowRoot?.querySelector('[data-test="input"]');
11
+ expect(input?.getAttribute('aria-checked')).to.equal('true');
12
+ });
13
+ it('is unchecked after being clicked', async () => {
14
+ const component = await fixture(html `<glide-core-toggle label="Label" checked></glide-core-toggle>`);
15
+ component.click();
16
+ await elementUpdated(component);
17
+ expect(component.checked).to.equal(false);
18
+ expect(component.hasAttribute('checked')).to.be.true;
19
+ const input = component.shadowRoot?.querySelector('[data-test="input"]');
20
+ expect(input?.getAttribute('aria-checked')).to.equal('false');
21
+ });
22
+ it('is still checked after being clicked when checked but disabled', async () => {
23
+ const component = await fixture(html `<glide-core-toggle
24
+ label="Label"
25
+ checked
26
+ disabled
27
+ ></glide-core-toggle>`);
28
+ component.click();
29
+ await elementUpdated(component);
30
+ expect(component.checked).to.equal(true);
31
+ expect(component.hasAttribute('checked')).to.be.true;
32
+ const input = component.shadowRoot?.querySelector('[data-test="input"]');
33
+ expect(input?.getAttribute('aria-checked')).to.equal('true');
34
+ });
35
+ it('is still unchecked after being clicked when unchecked and disabled', async () => {
36
+ const component = await fixture(html `<glide-core-toggle label="Label" disabled></glide-core-toggle>`);
37
+ component.click();
38
+ await elementUpdated(component);
39
+ expect(component.hasAttribute('checked')).to.be.false;
40
+ expect(component.checked).to.equal(false);
41
+ const input = component.shadowRoot?.querySelector('[data-test="input"]');
42
+ expect(input?.getAttribute('aria-checked')).to.equal('false');
43
+ });
package/dist/tooltip.d.ts CHANGED
@@ -13,9 +13,11 @@ export default class GlideCoreTooltip extends LitElement {
13
13
  static shadowRootOptions: ShadowRootInit;
14
14
  static styles: import("lit").CSSResult[];
15
15
  placement?: 'bottom' | 'left' | 'right' | 'top';
16
+ containingBlock?: Element;
16
17
  firstUpdated(): void;
17
18
  private get isVisible();
18
19
  private set isVisible(value);
19
20
  render(): import("lit").TemplateResult<1>;
21
+ setContainingBlock(containingBlock: Element): void;
20
22
  private effectivePlacement?;
21
23
  }
package/dist/tooltip.js CHANGED
@@ -1 +1 @@
1
- "use strict";var Z=Object.defineProperty;var _=Object.getOwnPropertyDescriptor;var v=(i,s,t,l)=>{for(var n=l>1?void 0:l?_(s,t):s,f=i.length-1,u;f>=0;f--)(u=i[f])&&(n=(l?u(s,t,n):u(n))||n);return l&&n&&Z(s,t,n),n};var P=(i,s,t)=>{if(!s.has(i))throw TypeError("Cannot "+t)};var e=(i,s,t)=>(P(i,s,"read from private field"),t?t.call(i):s.get(i)),o=(i,s,t)=>{if(s.has(i))throw TypeError("Cannot add the same private member more than once");s instanceof WeakSet?s.add(i):s.set(i,t)},S=(i,s,t,l)=>(P(i,s,"write to private field"),l?l.call(i,t):s.set(i,t),t);var a=(i,s,t)=>(P(i,s,"access private method"),t);var b,y,w,c,$,m,p,h,x,N,M,X,V,Y,T,q,L,z,U,A,H,B,F,J,O,Q,E,k;import{LitElement as I,html as C}from"lit";import{arrow as G,autoUpdate as tt,computePosition as et,flip as st,offset as it,shift as ot}from"@floating-ui/dom";import{classMap as lt}from"lit/directives/class-map.js";import{createRef as d,ref as g}from"lit/directives/ref.js";import{customElement as at,property as rt,state as K}from"lit/decorators.js";import{owSlot as R}from"./library/ow.js";import nt from"./tooltip.styles.js";let r=class extends I{constructor(){super(...arguments);o(this,x);o(this,M);o(this,V);o(this,T);o(this,L);o(this,U);o(this,H);o(this,F);o(this,O);o(this,E);o(this,b,d());o(this,y,void 0);o(this,w,void 0);o(this,c,d());o(this,$,!1);o(this,m,d());o(this,p,d());o(this,h,d())}firstUpdated(){R(e(this,c).value),R(e(this,p).value),a(this,E,k).call(this)}get isVisible(){return e(this,$)}set isVisible(t){var l;S(this,$,t),this.isVisible?a(this,E,k).call(this):(l=e(this,y))==null||l.call(this)}render(){return C`<div class="component" @mouseover="${a(this,H,B)}" @mouseout="${a(this,U,A)}"><div aria-labelledby="tooltip" class="target" slot="target" @focusin="${a(this,V,Y)}" @focusout="${a(this,T,q)}" @keydown="${a(this,L,z)}" ${g(e(this,m))}><slot @slotchange="${a(this,F,J)}" ${g(e(this,p))} name="target"></slot></div><div class="${lt({tooltip:!0,visible:this.isVisible})}" id="tooltip" role="tooltip" ${g(e(this,h))}><span aria-label="Tooltip: "></span><slot @slotchange="${a(this,M,X)}" ${g(e(this,c))}></slot><div class="arrow" ${g(e(this,b))}></div></div></div>`}};b=new WeakMap,y=new WeakMap,w=new WeakMap,c=new WeakMap,$=new WeakMap,m=new WeakMap,p=new WeakMap,h=new WeakMap,x=new WeakSet,N=function(){clearTimeout(e(this,w))},M=new WeakSet,X=function(){R(e(this,c).value)},V=new WeakSet,Y=function(){this.isVisible=!0},T=new WeakSet,q=function(){this.isVisible=!1},L=new WeakSet,z=function(t){t.key==="Escape"&&(this.isVisible=!1)},U=new WeakSet,A=function(){a(this,O,Q).call(this)},H=new WeakSet,B=function(){a(this,x,N).call(this),this.isVisible=!0},F=new WeakSet,J=function(){R(e(this,p).value)},O=new WeakSet,Q=function(){S(this,w,setTimeout(()=>{this.isVisible=!1},200))},E=new WeakSet,k=function(){e(this,m).value&&e(this,h).value&&S(this,y,tt(e(this,m).value,e(this,h).value,()=>{(async()=>{if(e(this,m).value&&e(this,h).value){const t=e(this,b).value,{placement:l,x:n,y:f,middlewareData:u}=await et(e(this,m).value,e(this,h).value,{placement:this.placement,strategy:"fixed",middleware:[it(10),st({fallbackStrategy:"initialPlacement"}),ot(),G({element:t})]});Object.assign(e(this,h).value.style,{left:`${n}px`,top:`${f}px`});const D=u.arrow?.x??null,j=u.arrow?.y??null,W={top:"bottom",right:"left",bottom:"top",left:"right"}[l.split("-")[0]];Object.assign(t.style,{left:D===null?"":`${D}px`,top:j===null?"":`${j}px`,right:"",bottom:"",[W]:"-3px"}),this.effectivePlacement=l}})()}))},r.shadowRootOptions={...I.shadowRootOptions,delegatesFocus:!0,mode:"closed"},r.styles=nt,v([rt()],r.prototype,"placement",2),v([K()],r.prototype,"isVisible",1),v([K()],r.prototype,"effectivePlacement",2),r=v([at("glide-core-tooltip")],r);export{r as default};
1
+ var __decorate=this&&this.__decorate||function(t,e,o,i){var l,s=arguments.length,a=s<3?e:null===i?i=Object.getOwnPropertyDescriptor(e,o):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(t,e,o,i);else for(var r=t.length-1;r>=0;r--)(l=t[r])&&(a=(s<3?l(a):s>3?l(e,o,a):l(e,o))||a);return s>3&&a&&Object.defineProperty(e,o,a),a};import{LitElement,html}from"lit";import{arrow,autoUpdate,computePosition,flip,offset,platform,shift}from"@floating-ui/dom";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{offsetParent}from"composed-offset-position";import{owSlot}from"./library/ow.js";import styles from"./tooltip.styles.js";let GlideCoreTooltip=class GlideCoreTooltip extends LitElement{static{this.shadowRootOptions={...LitElement.shadowRootOptions,delegatesFocus:!0,mode:"closed"}}static{this.styles=styles}firstUpdated(){owSlot(this.#t.value),owSlot(this.#e.value),this.#o()}get isVisible(){return this.#i}set isVisible(t){this.#i=t,this.isVisible?this.#o():this.#l?.()}render(){return html`<div class="component" @mouseover="${this.#s}" @mouseout="${this.#a}"><div aria-labelledby="tooltip" class="target" slot="target" @focusin="${this.#r}" @focusout="${this.#n}" @keydown="${this.#f}" ${ref(this.#c)}><slot @slotchange="${this.#p}" ${ref(this.#e)} name="target"></slot></div><div class="${classMap({tooltip:!0,visible:this.isVisible})}" id="tooltip" role="tooltip" ${ref(this.#m)}><span aria-label="Tooltip: "></span><slot @slotchange="${this.#h}" ${ref(this.#t)}></slot><div class="arrow" ${ref(this.#d)}></div></div></div>`}setContainingBlock(t){this.containingBlock=t}#d=createRef();#l;#u;#t=createRef();#i=!1;#c=createRef();#e=createRef();#m=createRef();#g(){clearTimeout(this.#u)}#h(){owSlot(this.#t.value)}#r(){this.isVisible=!0}#n(){this.isVisible=!1}#f(t){"Escape"===t.key&&(this.isVisible=!1)}#a(){this.#v()}#s(){this.#g(),this.isVisible=!0}#p(){owSlot(this.#e.value)}#v(){this.#u=setTimeout((()=>{this.isVisible=!1}),200)}#o(){this.#c.value&&this.#m.value&&(this.#l=autoUpdate(this.#c.value,this.#m.value,(()=>{(async()=>{if(this.#c.value&&this.#m.value){const t=this.#d.value,{placement:e,x:o,y:i,middlewareData:l}=await computePosition(this.#c.value,this.#m.value,{platform:{...platform,getOffsetParent:t=>this.containingBlock&&t!==this.#d.value?this.containingBlock:platform.getOffsetParent(t,offsetParent)},placement:this.placement,strategy:"fixed",middleware:[offset(6),flip({fallbackStrategy:"initialPlacement"}),shift(),arrow({element:t})]});Object.assign(this.#m.value.style,{left:`${o}px`,top:`${i}px`});const s=l.arrow?.x??null,a=l.arrow?.y??null,r={top:"bottom",right:"left",bottom:"top",left:"right"}[e.split("-")[0]];Object.assign(t.style,{left:null===s?"":`${s}px`,top:null===a?"":`${a}px`,right:"",bottom:"",[r]:"-3px"}),this.effectivePlacement=e}})()})))}};__decorate([property()],GlideCoreTooltip.prototype,"placement",void 0),__decorate([state()],GlideCoreTooltip.prototype,"containingBlock",void 0),__decorate([state()],GlideCoreTooltip.prototype,"isVisible",null),__decorate([state()],GlideCoreTooltip.prototype,"effectivePlacement",void 0),GlideCoreTooltip=__decorate([customElement("glide-core-tooltip")],GlideCoreTooltip);export default GlideCoreTooltip;
@@ -1,4 +1,4 @@
1
- "use strict";import{css as e}from"lit";import i from"./styles/focus-outline.js";export default[e`
1
+ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export default[css`
2
2
  .component {
3
3
  /* https://github.com/CrowdStrike/glide-core/pull/119#issuecomment-2113314591 */
4
4
  display: flex;
@@ -19,7 +19,7 @@
19
19
  }
20
20
 
21
21
  &:focus-visible {
22
- ${i};
22
+ ${focusOutline};
23
23
  }
24
24
 
25
25
  ::slotted svg {
@@ -39,6 +39,8 @@
39
39
  inset-block-start: 50%;
40
40
  inset-block-start: 0;
41
41
  inset-inline-start: 0;
42
+ max-inline-size: 11.25rem;
43
+ overflow-wrap: break-word;
42
44
  padding: var(--glide-core-spacing-xs) var(--glide-core-spacing-sm);
43
45
  position: fixed;
44
46
  z-index: 1;
@@ -63,4 +65,4 @@
63
65
  position: absolute;
64
66
  transform: rotate(45deg);
65
67
  }
66
- `];
68
+ `];
@@ -0,0 +1,64 @@
1
+ import './tooltip.js';
2
+ import { ArgumentError } from 'ow';
3
+ import { expect, fixture, html } from '@open-wc/testing';
4
+ import GlideCoreTooltip from './tooltip.js';
5
+ import sinon from 'sinon';
6
+ GlideCoreTooltip.shadowRootOptions.mode = 'open';
7
+ it('registers', async () => {
8
+ expect(window.customElements.get('glide-core-tooltip')).to.equal(GlideCoreTooltip);
9
+ });
10
+ it('is accessible', async () => {
11
+ const component = await fixture(html `<glide-core-tooltip>
12
+ Tooltip
13
+ <span slot="target" tabindex="0">Target</span>
14
+ </glide-core-tooltip>`);
15
+ // See the comment in the component's `render` method for an explanation.
16
+ await expect(component).to.be.accessible({
17
+ ignoredRules: ['aria-tooltip-name'],
18
+ });
19
+ });
20
+ it('can have a tooltip', async () => {
21
+ const component = await fixture(html `<glide-core-tooltip aria-label="Label">
22
+ Tooltip
23
+ <span slot="target" tabindex="0">Target</span>
24
+ </glide-core-tooltip>`);
25
+ const tooltip = component?.shadowRoot
26
+ ?.querySelector('slot:not([name])')
27
+ ?.assignedNodes()
28
+ .at(0);
29
+ expect(tooltip?.textContent?.trim()).to.equal('Tooltip');
30
+ });
31
+ it('can have a target', async () => {
32
+ const component = await fixture(html `<glide-core-tooltip>
33
+ Tooltip
34
+ <span slot="target" tabindex="0">Target</span>
35
+ </glide-core-tooltip>`);
36
+ const assignedElements = component.shadowRoot
37
+ ?.querySelector('slot[name="target"]')
38
+ ?.assignedElements();
39
+ expect(assignedElements?.at(0)?.textContent).to.equal('Target');
40
+ });
41
+ it('throws if it does not have a default slot', async () => {
42
+ const spy = sinon.spy();
43
+ try {
44
+ await fixture(html `<glide-core-tooltip></glide-core-tooltip>`);
45
+ }
46
+ catch (error) {
47
+ if (error instanceof ArgumentError) {
48
+ spy();
49
+ }
50
+ }
51
+ expect(spy.called).to.be.true;
52
+ });
53
+ it('throws if it does not have a "target" slot', async () => {
54
+ const spy = sinon.spy();
55
+ try {
56
+ await fixture(html `<glide-core-tooltip> Tooltip </glide-core-tooltip>`);
57
+ }
58
+ catch (error) {
59
+ if (error instanceof ArgumentError) {
60
+ spy();
61
+ }
62
+ }
63
+ expect(spy.called).to.be.true;
64
+ });
@@ -0,0 +1,78 @@
1
+ import './tooltip.js';
2
+ import { elementUpdated, expect, fixture, html } from '@open-wc/testing';
3
+ import { sendKeys } from '@web/test-runner-commands';
4
+ import GlideCoreTooltip from './tooltip.js';
5
+ import sinon from 'sinon';
6
+ GlideCoreTooltip.shadowRootOptions.mode = 'open';
7
+ it('is visible on "focusin"', async () => {
8
+ const component = await fixture(html `<glide-core-tooltip>
9
+ Tooltip
10
+ <span slot="target" tabindex="0">Target</span>
11
+ </glide-core-tooltip>`);
12
+ component.shadowRoot
13
+ ?.querySelector('[aria-labelledby="tooltip"]')
14
+ ?.dispatchEvent(new FocusEvent('focusin'));
15
+ await elementUpdated(component);
16
+ expect(component.shadowRoot?.querySelector('[role="tooltip"]')?.checkVisibility()).to.be.true;
17
+ });
18
+ it('is hidden on "blur"', async () => {
19
+ const component = await fixture(html `<glide-core-tooltip>
20
+ Tooltip
21
+ <span slot="target" tabindex="0">Target</span>
22
+ </glide-core-tooltip>`);
23
+ component.shadowRoot
24
+ ?.querySelector('[aria-labelledby="tooltip"]')
25
+ ?.dispatchEvent(new FocusEvent('focusin'));
26
+ await elementUpdated(component);
27
+ component.shadowRoot
28
+ ?.querySelector('[aria-labelledby="tooltip"]')
29
+ ?.dispatchEvent(new FocusEvent('focusout'));
30
+ await elementUpdated(component);
31
+ expect(component.shadowRoot?.querySelector('[role="tooltip"]')?.checkVisibility()).to.be.false;
32
+ });
33
+ it('is hidden on Escape', async () => {
34
+ const component = await fixture(html `<glide-core-tooltip>
35
+ Tooltip
36
+ <span slot="target" tabindex="0">Target</span>
37
+ </glide-core-tooltip>`);
38
+ component.shadowRoot
39
+ ?.querySelector('[aria-labelledby="tooltip"]')
40
+ ?.dispatchEvent(new FocusEvent('focusin'));
41
+ await elementUpdated(component);
42
+ // So the key is sent to the component instead of `<body>`. It's not
43
+ // clear why `component.focus()` doesn't focus the span when using
44
+ // Playwright.
45
+ component.querySelector('span')?.focus();
46
+ await sendKeys({ press: 'Escape' });
47
+ await elementUpdated(component);
48
+ expect(component.shadowRoot?.querySelector('[role="tooltip"]')?.checkVisibility()).to.be.false;
49
+ });
50
+ it('is visible on "mouseover"', async () => {
51
+ const component = await fixture(html `<glide-core-tooltip>
52
+ Tooltip
53
+ <span slot="target" tabindex="0">Target</span>
54
+ </glide-core-tooltip>`);
55
+ component.shadowRoot
56
+ ?.querySelector('.component')
57
+ ?.dispatchEvent(new MouseEvent('mouseover'));
58
+ await elementUpdated(component);
59
+ expect(component.shadowRoot?.querySelector('[role="tooltip"]')?.checkVisibility()).to.be.true;
60
+ });
61
+ it('is hidden on "mouseout"', async () => {
62
+ const clock = sinon.useFakeTimers();
63
+ const component = await fixture(html `<glide-core-tooltip>
64
+ Tooltip
65
+ <span slot="target" tabindex="0">Target</span>
66
+ </glide-core-tooltip>`);
67
+ component.shadowRoot
68
+ ?.querySelector('.component')
69
+ ?.dispatchEvent(new MouseEvent('mouseover'));
70
+ await elementUpdated(component);
71
+ component.shadowRoot
72
+ ?.querySelector('.component')
73
+ ?.dispatchEvent(new MouseEvent('mouseout'));
74
+ clock.tick(300);
75
+ await elementUpdated(component);
76
+ expect(component.shadowRoot?.querySelector('[role="tooltip"]')?.checkVisibility()).to.be.false;
77
+ clock.restore();
78
+ });
@@ -0,0 +1,3 @@
1
+ import type { Translation } from '../library/localize.js';
2
+ declare const translation: Translation;
3
+ export default translation;
@@ -0,0 +1 @@
1
+ const translation={$code:"en",$name:"English",$dir:"ltr",close:"Close",dismiss:"Dismiss",open:"Open",selectAll:"Select all",clearEntry:"Clear entry",moreInformation:"More information",notifications:"Notifications",removeTag:e=>`Remove tag: ${e}`};export default translation;
@@ -0,0 +1,3 @@
1
+ import type { Translation } from '../library/localize.js';
2
+ declare const translation: Translation;
3
+ export default translation;
@@ -0,0 +1 @@
1
+ const translation={$code:"fr",$name:"French",$dir:"ltr",close:"Fermer",dismiss:"Congédier",open:"Ouvrir",selectAll:"Tout sélectionner",clearEntry:"Effacer l’entrée",moreInformation:"Plus d’informations",notifications:"Notifications",removeTag:e=>`Supprimer la balise : ${e}`};export default translation;
@@ -0,0 +1,3 @@
1
+ import type { Translation } from '../library/localize.js';
2
+ declare const translation: Translation;
3
+ export default translation;
@@ -0,0 +1 @@
1
+ const translation={$code:"ja",$name:"Japanese",$dir:"ltr",close:"閉じる",dismiss:"無視",open:"オープン",selectAll:"すべて選択",clearEntry:"入力のクリア",moreInformation:"詳細情報",notifications:"通知",removeTag:e=>`タグを削除: ${e}`};export default translation;
package/dist/tree.d.ts CHANGED
@@ -22,5 +22,6 @@ export default class GlideCoreTree extends LitElement {
22
22
  firstUpdated(): void;
23
23
  render(): import("lit").TemplateResult<1>;
24
24
  selectItem(item: GlideCoreTreeItem): void;
25
+ setContainingBlock(containingBlock: Element): void;
25
26
  constructor();
26
27
  }
@@ -1,5 +1,6 @@
1
1
  import './tree.item.menu.js';
2
2
  import { LitElement } from 'lit';
3
+ import GlideCoreMenu from './menu.js';
3
4
  declare global {
4
5
  interface HTMLElementTagNameMap {
5
6
  'glide-core-tree-item': GlideCoreTreeItem;
@@ -21,7 +22,7 @@ export default class GlideCoreTreeItem extends LitElement {
21
22
  label: string;
22
23
  level: number;
23
24
  selected: boolean;
24
- menuSlotAssignedElements: HTMLElement[];
25
+ menuSlotAssignedElements: GlideCoreMenu[];
25
26
  prefixSlotAssignedElements: HTMLElement[];
26
27
  slotElements: GlideCoreTreeItem[];
27
28
  suffixSlotAssignedElements: HTMLElement[];
@@ -35,6 +36,7 @@ export default class GlideCoreTreeItem extends LitElement {
35
36
  * Returns the selected item
36
37
  */
37
38
  selectItem(item: GlideCoreTreeItem): GlideCoreTreeItem | undefined;
39
+ setContainingBlock(containingBlock: Element): void;
38
40
  toggleExpand(): void;
39
41
  private childTreeItems;
40
42
  private hasMenuSlot;
@@ -1 +1 @@
1
- "use strict";var b=Object.defineProperty;var E=Object.getOwnPropertyDescriptor;var f=(e,t,o,a)=>{for(var i=a>1?void 0:a?E(t,o):t,n=e.length-1,d;n>=0;n--)(d=e[n])&&(i=(a?d(t,o,i):d(i))||i);return a&&i&&b(t,o,i),i};var p=(e,t,o)=>{if(!t.has(e))throw TypeError("Cannot "+o)};var s=(e,t,o)=>(p(e,t,"read from private field"),o?o.call(e):t.get(e)),c=(e,t,o)=>{if(t.has(e))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(e):t.set(e,o)};var h=(e,t,o)=>(p(e,t,"access private method"),o);var l,m,v;import"./icon-button.js";import{LitElement as g,html as R}from"lit";import{createRef as S,ref as w}from"lit/directives/ref.js";import{customElement as y}from"lit/decorators.js";import{owSlot as u}from"./library/ow.js";import L from"./tree.item.icon-button.styles.js";let r=class extends g{constructor(){super(...arguments);c(this,m);c(this,l,S())}firstUpdated(){u(s(this,l).value)}render(){return R`<glide-core-icon-button class="component" variant="tertiary"><slot @slotchange="${h(this,m,v)}" ${w(s(this,l))}></slot></glide-core-icon-button>`}};l=new WeakMap,m=new WeakSet,v=function(){u(s(this,l).value)},r.shadowRootOptions={...g.shadowRootOptions,mode:"closed"},r.styles=L,r=f([y("glide-core-tree-item-icon-button")],r);export{r as default};
1
+ var __decorate=this&&this.__decorate||function(e,t,o,r){var l,n=arguments.length,i=n<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,o):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)i=Reflect.decorate(e,t,o,r);else for(var s=e.length-1;s>=0;s--)(l=e[s])&&(i=(n<3?l(i):n>3?l(t,o,i):l(t,o))||i);return n>3&&i&&Object.defineProperty(t,o,i),i};import"./icon-button.js";import{LitElement,html}from"lit";import{createRef,ref}from"lit/directives/ref.js";import{customElement}from"lit/decorators.js";import{owSlot}from"./library/ow.js";import styles from"./tree.item.icon-button.styles.js";let GlideCoreTreeItemIconButton=class GlideCoreTreeItemIconButton extends LitElement{static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}firstUpdated(){owSlot(this.#e.value)}render(){return html`<glide-core-icon-button class="component" variant="tertiary"><slot @slotchange="${this.#t}" ${ref(this.#e)}></slot></glide-core-icon-button>`}#e=createRef();#t(){owSlot(this.#e.value)}};GlideCoreTreeItemIconButton=__decorate([customElement("glide-core-tree-item-icon-button")],GlideCoreTreeItemIconButton);export default GlideCoreTreeItemIconButton;