@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,4 +1,4 @@
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
  display: flex;
4
4
 
@@ -6,4 +6,4 @@
6
6
  --hovered-icon-color: var(--hovered-icon-button-color);
7
7
  --size: 1rem;
8
8
  }
9
- `];
9
+ `];
@@ -0,0 +1,13 @@
1
+ import { expect, fixture, html } from '@open-wc/testing';
2
+ import GlideCoreTreeItemIconButton from './tree.item.icon-button.js';
3
+ import expectArgumentError from './library/expect-argument-error.js';
4
+ it('registers', async () => {
5
+ expect(window.customElements.get('glide-core-tree-item-icon-button')).to.equal(GlideCoreTreeItemIconButton);
6
+ });
7
+ it('throws if it does not have a default slot', async () => {
8
+ await expectArgumentError(() => {
9
+ return fixture(html `
10
+ <glide-core-tree-item-icon-button></glide-core-tree-item-icon-button>
11
+ `);
12
+ });
13
+ });
package/dist/tree.item.js CHANGED
@@ -1 +1 @@
1
- "use strict";var N=Object.defineProperty;var O=Object.getOwnPropertyDescriptor;var l=(i,s,t,o)=>{for(var n=o>1?void 0:o?O(s,t):s,r=i.length-1,b;r>=0;r--)(b=i[r])&&(n=(o?b(s,t,n):b(n))||n);return o&&n&&N(s,t,n),n};var A=(i,s,t)=>{if(!s.has(i))throw TypeError("Cannot "+t)};var d=(i,s,t)=>(A(i,s,"read from private field"),t?t.call(i):s.get(i)),a=(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)};var h=(i,s,t)=>(A(i,s,"access private method"),t);var f,p,H,x,I,g,R,v,k,S,B,E,P,$,T;import"./tree.item.menu.js";import{LitElement as w,html as y}from"lit";import{classMap as M}from"lit/directives/class-map.js";import{createRef as j,ref as q}from"lit/directives/ref.js";import{customElement as D,property as c,queryAssignedElements as m,state as u}from"lit/decorators.js";import{ifDefined as L}from"lit/directives/if-defined.js";import{when as F}from"lit/directives/when.js";import U from"./tree.item.styles.js";let e=class extends w{constructor(){super(...arguments);a(this,p);a(this,x);a(this,g);a(this,v);a(this,S);a(this,E);a(this,$);this.expanded=!1;this.label="";this.level=1;this.selected=!1;this.childTreeItems=[];this.hasMenuSlot=!1;this.hasPrefixSlot=!1;this.hasSuffixSlot=!1;a(this,f,j())}firstUpdated(){h(this,$,T).call(this)}focus(){d(this,f).value?.focus()}get hasChildTreeItems(){return this.childTreeItems.length>0}render(){return y`<div class="${M({component:!0,expanded:this.expanded,selected:this.selected})}" role="treeitem" aria-label="${this.label}" aria-selected="${L(d(this,x,I))}" aria-expanded="${L(d(this,p,H))}"><div class="${M({"label-container":!0})}" tabindex="-1" ${q(d(this,f))}><div style="width:${d(this,g,R)};"></div><div class="expand-icon-container">${F(this.hasChildTreeItems,()=>y`<div><svg aria-hidden="true" class="${M({"expand-icon":!0,"expand-icon-expanded":this.expanded})}" width="16" height="16" viewBox="0 0 24 24" fill="none"><path d="M9 18L15 12L9 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></div>`)}</div><slot name="prefix" @slotchange="${h(this,S,B)}"></slot><div class="label">${this.label}</div><slot name="menu" @slotchange="${h(this,v,k)}"></slot><slot name="suffix" @slotchange="${h(this,E,P)}"></slot></div><div class="child-items" role="group"><slot></slot></div></div>`}selectItem(t){let o;for(const n of this.slotElements)if(t===n)n.setAttribute("selected","true"),o=n;else{n.removeAttribute("selected");const r=n.selectItem(t);r&&(o=r)}return o}toggleExpand(){this.expanded=!this.expanded}};f=new WeakMap,p=new WeakSet,H=function(){if(this.hasChildTreeItems)return this.expanded?"true":"false"},x=new WeakSet,I=function(){if(!this.hasChildTreeItems)return this.selected?"true":"false"},g=new WeakSet,R=function(){return`${(this.level-1)*20}px`},v=new WeakSet,k=function(){this.hasMenuSlot=this.menuSlotAssignedElements.length>0},S=new WeakSet,B=function(){this.hasPrefixSlot=this.prefixSlotAssignedElements.length>0},E=new WeakSet,P=function(){this.hasSuffixSlot=this.suffixSlotAssignedElements.length>0},$=new WeakSet,T=function(){const t=[];for(const o of this.slotElements)o.level=this.level+1,t.push(o);this.childTreeItems=t},e.shadowRootOptions={...w.shadowRootOptions,delegatesFocus:!0,mode:"closed"},e.styles=U,l([c({type:Boolean})],e.prototype,"expanded",2),l([c({reflect:!0})],e.prototype,"label",2),l([c({type:Number})],e.prototype,"level",2),l([c({type:Boolean})],e.prototype,"selected",2),l([m({slot:"menu"})],e.prototype,"menuSlotAssignedElements",2),l([m({slot:"prefix"})],e.prototype,"prefixSlotAssignedElements",2),l([m()],e.prototype,"slotElements",2),l([m({slot:"suffix"})],e.prototype,"suffixSlotAssignedElements",2),l([u()],e.prototype,"childTreeItems",2),l([u()],e.prototype,"hasMenuSlot",2),l([u()],e.prototype,"hasPrefixSlot",2),l([u()],e.prototype,"hasSuffixSlot",2),e=l([D("glide-core-tree-item")],e);export{e as default};
1
+ var __decorate=this&&this.__decorate||function(e,t,s,i){var o,r=arguments.length,l=r<3?t:null===i?i=Object.getOwnPropertyDescriptor(t,s):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)l=Reflect.decorate(e,t,s,i);else for(var n=e.length-1;n>=0;n--)(o=e[n])&&(l=(r<3?o(l):r>3?o(t,s,l):o(t,s))||l);return r>3&&l&&Object.defineProperty(t,s,l),l};import"./tree.item.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,queryAssignedElements,state}from"lit/decorators.js";import{ifDefined}from"lit/directives/if-defined.js";import GlideCoreMenu from"./menu.js";import{when}from"lit/directives/when.js";import styles from"./tree.item.styles.js";let GlideCoreTreeItem=class GlideCoreTreeItem extends LitElement{constructor(){super(...arguments),this.expanded=!1,this.label="",this.level=1,this.selected=!1,this.childTreeItems=[],this.hasMenuSlot=!1,this.hasPrefixSlot=!1,this.hasSuffixSlot=!1,this.#e=createRef()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,delegatesFocus:!0,mode:"closed"}}static{this.styles=styles}firstUpdated(){this.#t()}focus(){this.#e.value?.focus()}get hasChildTreeItems(){return this.childTreeItems.length>0}render(){return html`<div class="${classMap({component:!0,expanded:this.expanded,selected:this.selected})}" role="treeitem" aria-label="${this.label}" aria-selected="${ifDefined(this.#s)}" aria-expanded="${ifDefined(this.#i)}"><div class="${classMap({"label-container":!0})}" tabindex="-1" ${ref(this.#e)}><div style="flex-shrink: 0; width:${this.#o};"></div><div class="expand-icon-container">${when(this.hasChildTreeItems,(()=>html`<div><svg aria-hidden="true" class="${classMap({"expand-icon":!0,"expand-icon-expanded":this.expanded})}" width="16" height="16" viewBox="0 0 24 24" fill="none"><path d="M9 18L15 12L9 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></div>`))}</div><slot name="prefix" @slotchange="${this.#r}"></slot><div class="label">${this.label}</div><div class="icon-container"><slot name="menu" @slotchange="${this.#l}"></slot><slot name="suffix" @slotchange="${this.#n}"></slot></div></div><div class="child-items" role="group"><slot></slot></div></div>`}selectItem(e){let t;for(const s of this.slotElements)if(e===s)s.setAttribute("selected","true"),t=s;else{s.removeAttribute("selected");const i=s.selectItem(e);i&&(t=i)}return t}setContainingBlock(e){for(const t of this.menuSlotAssignedElements)t.setContainingBlock(e)}toggleExpand(){this.expanded=!this.expanded}#e;get#i(){return this.hasChildTreeItems?this.expanded?"true":"false":void 0}get#s(){return this.hasChildTreeItems?void 0:this.selected?"true":"false"}get#o(){return 20*(this.level-1)+"px"}#l(){this.hasMenuSlot=this.menuSlotAssignedElements.length>0}#r(){this.hasPrefixSlot=this.prefixSlotAssignedElements.length>0}#n(){this.hasSuffixSlot=this.suffixSlotAssignedElements.length>0}#t(){const e=[];for(const t of this.slotElements)t.level=this.level+1,e.push(t);this.childTreeItems=e}};__decorate([property({type:Boolean})],GlideCoreTreeItem.prototype,"expanded",void 0),__decorate([property({reflect:!0})],GlideCoreTreeItem.prototype,"label",void 0),__decorate([property({type:Number})],GlideCoreTreeItem.prototype,"level",void 0),__decorate([property({type:Boolean})],GlideCoreTreeItem.prototype,"selected",void 0),__decorate([queryAssignedElements({slot:"menu"})],GlideCoreTreeItem.prototype,"menuSlotAssignedElements",void 0),__decorate([queryAssignedElements({slot:"prefix"})],GlideCoreTreeItem.prototype,"prefixSlotAssignedElements",void 0),__decorate([queryAssignedElements()],GlideCoreTreeItem.prototype,"slotElements",void 0),__decorate([queryAssignedElements({slot:"suffix"})],GlideCoreTreeItem.prototype,"suffixSlotAssignedElements",void 0),__decorate([state()],GlideCoreTreeItem.prototype,"childTreeItems",void 0),__decorate([state()],GlideCoreTreeItem.prototype,"hasMenuSlot",void 0),__decorate([state()],GlideCoreTreeItem.prototype,"hasPrefixSlot",void 0),__decorate([state()],GlideCoreTreeItem.prototype,"hasSuffixSlot",void 0),GlideCoreTreeItem=__decorate([customElement("glide-core-tree-item")],GlideCoreTreeItem);export default GlideCoreTreeItem;
@@ -1,5 +1,6 @@
1
1
  import './icon-button.js';
2
2
  import './menu.js';
3
+ import './menu.options.js';
3
4
  import { LitElement } from 'lit';
4
5
  declare global {
5
6
  interface HTMLElementTagNameMap {
@@ -18,4 +19,5 @@ export default class GlideCoreTreeItemMenu extends LitElement {
18
19
  static styles: import("lit").CSSResult[];
19
20
  firstUpdated(): void;
20
21
  render(): import("lit").TemplateResult<1>;
22
+ setContainingBlock(containingBlock: Element): void;
21
23
  }
@@ -1 +1 @@
1
- "use strict";var E=Object.defineProperty;var R=Object.getOwnPropertyDescriptor;var h=(o,t,e,a)=>{for(var i=a>1?void 0:a?R(t,e):t,m=o.length-1,d;m>=0;m--)(d=o[m])&&(i=(a?d(t,e,i):d(i))||i);return a&&i&&E(t,e,i),i};var p=(o,t,e)=>{if(!t.has(o))throw TypeError("Cannot "+e)};var s=(o,t,e)=>(p(o,t,"read from private field"),e?e.call(o):t.get(o)),c=(o,t,e)=>{if(t.has(o))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(o):t.set(o,e)};var f=(o,t,e)=>(p(o,t,"access private method"),e);var r,n,S;import"./icon-button.js";import"./menu.js";import{LitElement as u,html as y}from"lit";import{createRef as L,ref as M}from"lit/directives/ref.js";import{customElement as b}from"lit/decorators.js";import{owSlot as g,owSlotType as v}from"./library/ow.js";import C from"./menu.button.js";import w from"./menu.link.js";import k from"./tree.item.menu.styles.js";let l=class extends u{constructor(){super(...arguments);c(this,n);c(this,r,L())}firstUpdated(){g(s(this,r).value),v(s(this,r).value,[C,w])}render(){return y`<glide-core-menu class="component"><slot @slotchange="${f(this,n,S)}" ${M(s(this,r))}></slot><glide-core-icon-button slot="target" variant="tertiary"><svg width="4" height="14" viewBox="0 0 4 18" fill="none" stroke="currentColor" stroke-width="2"><path d="M2 15C2.55228 15 3 15.4477 3 16C3 16.5523 2.55228 17 2 17C1.44772 17 1 16.5523 1 16C1 15.4477 1.44772 15 2 15Z"/><path d="M2 8C2.55228 8 3 8.44772 3 9C3 9.55228 2.55228 10 2 10C1.44772 10 1 9.55228 1 9C1 8.44772 1.44772 8 2 8Z"/><path d="M2 1C2.55228 1 3 1.44772 3 2C3 2.55228 2.55228 3 2 3C1.44772 3 1 2.55228 1 2C1 1.44772 1.44772 1 2 1Z"/></svg></glide-core-icon-button></glide-core-menu>`}};r=new WeakMap,n=new WeakSet,S=function(){g(s(this,r).value),v(s(this,r).value,[C,w])},l.shadowRootOptions={...u.shadowRootOptions,mode:"closed"},l.styles=k,l=h([b("glide-core-tree-item-menu")],l);export{l as default};
1
+ var __decorate=this&&this.__decorate||function(e,t,o,l){var n,r=arguments.length,i=r<3?t:null===l?l=Object.getOwnPropertyDescriptor(t,o):l;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)i=Reflect.decorate(e,t,o,l);else for(var s=e.length-1;s>=0;s--)(n=e[s])&&(i=(r<3?n(i):r>3?n(t,o,i):n(t,o))||i);return r>3&&i&&Object.defineProperty(t,o,i),i};import"./icon-button.js";import"./menu.js";import"./menu.options.js";import{LitElement,html}from"lit";import{createRef,ref}from"lit/directives/ref.js";import{customElement}from"lit/decorators.js";import{owSlot,owSlotType}from"./library/ow.js";import GlideCoreMenu from"./menu.js";import GlideCoreMenuButton from"./menu.button.js";import GlideCoreMenuLink from"./menu.link.js";import styles from"./tree.item.menu.styles.js";let GlideCoreTreeItemMenu=class GlideCoreTreeItemMenu extends LitElement{static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}firstUpdated(){owSlot(this.#e.value),owSlotType(this.#e.value,[GlideCoreMenuButton,GlideCoreMenuLink])}render(){return html`<glide-core-menu class="component" ${ref(this.#t)}><glide-core-menu-options><slot @slotchange="${this.#o}" ${ref(this.#e)}></slot></glide-core-menu-options><glide-core-icon-button slot="target" variant="tertiary"><svg width="4" height="14" viewBox="0 0 4 18" fill="none" stroke="currentColor" stroke-width="2"><path d="M2 15C2.55228 15 3 15.4477 3 16C3 16.5523 2.55228 17 2 17C1.44772 17 1 16.5523 1 16C1 15.4477 1.44772 15 2 15Z"/><path d="M2 8C2.55228 8 3 8.44772 3 9C3 9.55228 2.55228 10 2 10C1.44772 10 1 9.55228 1 9C1 8.44772 1.44772 8 2 8Z"/><path d="M2 1C2.55228 1 3 1.44772 3 2C3 2.55228 2.55228 3 2 3C1.44772 3 1 2.55228 1 2C1 1.44772 1.44772 1 2 1Z"/></svg></glide-core-icon-button></glide-core-menu>`}setContainingBlock(e){this.#t.value.setContainingBlock(e)}#e=createRef();#t=createRef();#o(){owSlot(this.#e.value),owSlotType(this.#e.value,[GlideCoreMenuButton,GlideCoreMenuLink])}};GlideCoreTreeItemMenu=__decorate([customElement("glide-core-tree-item-menu")],GlideCoreTreeItemMenu);export default GlideCoreTreeItemMenu;
@@ -1,4 +1,4 @@
1
- "use strict";import{css as o}from"lit";export default[o`
1
+ import{css}from"lit";export default[css`
2
2
  :host {
3
3
  display: contents;
4
4
  }
@@ -14,4 +14,4 @@
14
14
  --hovered-icon-color: var(--hovered-icon-button-color);
15
15
  --size: 1rem;
16
16
  }
17
- `];
17
+ `];
@@ -0,0 +1,33 @@
1
+ import { expect, fixture, html, waitUntil } from '@open-wc/testing';
2
+ import GlideCoreTreeItemMenu from './tree.item.menu.js';
3
+ import expectArgumentError from './library/expect-argument-error.js';
4
+ import sinon from 'sinon';
5
+ it('registers', async () => {
6
+ expect(window.customElements.get('glide-core-tree-item-menu')).to.equal(GlideCoreTreeItemMenu);
7
+ });
8
+ it('throws if it does not have a default slot', async () => {
9
+ await expectArgumentError(() => {
10
+ return fixture(html `
11
+ <glide-core-tree-item-menu></glide-core-tree-item-menu>
12
+ `);
13
+ });
14
+ });
15
+ it('throws if the default slot is the incorrect type', async () => {
16
+ await expectArgumentError(() => {
17
+ return fixture(html `
18
+ <glide-core-tree-item-menu>
19
+ <button>Button</button>
20
+ </glide-core-tree-item-menu>
21
+ `);
22
+ });
23
+ // Menu is rendered asynchronously outside of Tree Menu Item's lifecycle
24
+ // and asserts against its default slot. That assertion, which is expected
25
+ // to fail in this case, results in an unhandled rejection that gets logged.
26
+ // `console.error` is stubbed so the logs aren't muddied.
27
+ const stub = sinon.stub(console, 'error');
28
+ // Menu asserts against its default slot once on `firstUpdated` and again
29
+ // on "slotchange". So we wait until the stub is called twice before restoring
30
+ // it.
31
+ await waitUntil(() => stub.calledTwice);
32
+ stub.restore();
33
+ });
@@ -1,4 +1,4 @@
1
- "use strict";import{css as e}from"lit";export default[e`
1
+ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export default[css`
2
2
  :host {
3
3
  cursor: pointer;
4
4
  display: flex;
@@ -20,6 +20,7 @@
20
20
  }
21
21
 
22
22
  .expand-icon-container {
23
+ flex-shrink: 0;
23
24
  min-inline-size: 1.5625rem;
24
25
  }
25
26
 
@@ -43,7 +44,7 @@
43
44
 
44
45
  .label-container {
45
46
  align-items: center;
46
- border-radius: 0.625rem;
47
+ border-radius: 0.5rem;
47
48
  color: var(--color);
48
49
  display: flex;
49
50
  font-size: var(--glide-core-body-sm-font-size);
@@ -63,10 +64,15 @@
63
64
  }
64
65
 
65
66
  &:focus-visible {
66
- outline: var(--glide-core-border-primary);
67
- outline-offset: -1px;
68
- outline-style: auto;
69
- outline-width: 2px;
67
+ ${focusOutline};
68
+
69
+ /* The outline is inside the component since children have overflow hidden */
70
+ outline-offset: -2px;
71
+
72
+ .component.selected & {
73
+ outline: 1px solid var(--glide-core-icon-selected);
74
+ outline-offset: -3px;
75
+ }
70
76
  }
71
77
 
72
78
  .component.selected & {
@@ -112,7 +118,10 @@
112
118
  }
113
119
 
114
120
  .label {
115
- flex-grow: 1;
121
+ min-inline-size: 0;
122
+ overflow: hidden;
123
+ text-overflow: ellipsis;
124
+ white-space: nowrap;
116
125
  }
117
126
 
118
127
  .child-items {
@@ -127,4 +136,10 @@
127
136
  block-size: auto;
128
137
  }
129
138
  }
130
- `];
139
+
140
+ .icon-container {
141
+ display: flex;
142
+ flex: 1;
143
+ justify-content: flex-end;
144
+ }
145
+ `];
@@ -0,0 +1,102 @@
1
+ import { expect, fixture, html } from '@open-wc/testing';
2
+ import TreeItem from './tree.item.js';
3
+ TreeItem.shadowRootOptions.mode = 'open';
4
+ it('registers', () => {
5
+ expect(window.customElements.get('glide-core-tree-item')).to.equal(TreeItem);
6
+ });
7
+ it('renders and sets default attributes', async () => {
8
+ const treeItem = await fixture(html `
9
+ <glide-core-tree-item label="Item"></glide-core-tree-item>
10
+ `);
11
+ expect(treeItem.expanded).to.equal(false);
12
+ expect(treeItem.label).to.equal('Item');
13
+ expect(treeItem.level).to.equal(1);
14
+ });
15
+ it('renders with a prefix slot', async () => {
16
+ await fixture(html `
17
+ <glide-core-tree-item label="Item">
18
+ <span slot="prefix" data-prefix>prefix</span>
19
+ </glide-core-tree-item>
20
+ `);
21
+ expect(document.querySelector('[data-prefix]')).to.be.ok;
22
+ });
23
+ it('renders with a menu slot', async () => {
24
+ await fixture(html `
25
+ <glide-core-tree-item label="Item">
26
+ <span slot="menu" data-menu>menu</span>
27
+ </glide-core-tree-item>
28
+ `);
29
+ expect(document.querySelector('[data-menu]')).to.be.ok;
30
+ });
31
+ it('renders with a suffix slot', async () => {
32
+ await fixture(html `
33
+ <glide-core-tree-item label="Item">
34
+ <span slot="suffix" data-suffix>suffix</span>
35
+ </glide-core-tree-item>
36
+ `);
37
+ expect(document.querySelector('[data-suffix]')).to.be.ok;
38
+ });
39
+ it('does not have an expand icon if there are no child tree items', async () => {
40
+ const treeItem = await fixture(html `
41
+ <glide-core-tree-item label="Item"></glide-core-tree-item>
42
+ `);
43
+ expect(treeItem.shadowRoot?.querySelector('.expand-icon')).to.equal(null);
44
+ });
45
+ it('can expand', async () => {
46
+ const treeItem = await fixture(html `
47
+ <glide-core-tree-item label="Item">
48
+ <glide-core-tree-item label="Child Item 1"></glide-core-tree-item>
49
+ </glide-core-tree-item>
50
+ `);
51
+ expect([
52
+ ...treeItem.shadowRoot.querySelector('.component').classList,
53
+ ]).to.deep.equal(['component']);
54
+ expect([
55
+ ...treeItem.shadowRoot.querySelector('.expand-icon').classList,
56
+ ]).to.deep.equal(['expand-icon']);
57
+ treeItem.toggleExpand();
58
+ await treeItem.updateComplete;
59
+ expect([
60
+ ...treeItem.shadowRoot.querySelector('.component').classList,
61
+ ]).to.deep.equal(['component', 'expanded']);
62
+ expect([
63
+ ...treeItem.shadowRoot.querySelector('.expand-icon').classList,
64
+ ]).to.deep.equal(['expand-icon', 'expand-icon-expanded']);
65
+ });
66
+ it('renders child and grandchild tree items', async () => {
67
+ const treeItem = await fixture(html `
68
+ <glide-core-tree-item expanded label="Item">
69
+ <glide-core-tree-item label="Child Item 1"></glide-core-tree-item>
70
+ <glide-core-tree-item label="Child Item 2">
71
+ <glide-core-tree-item label="Grandchild Item 1"></glide-core-tree-item>
72
+ </glide-core-tree-item>
73
+ </glide-core-tree-item>
74
+ `);
75
+ expect(treeItem.shadowRoot?.querySelector('.expand-icon')).to.be.ok;
76
+ const childItems = treeItem.slotElements;
77
+ expect(childItems?.length).to.equal(2);
78
+ expect(childItems?.[0].level).to.equal(2, 'Children are level 2');
79
+ const grandchildItems = childItems?.[1].slotElements;
80
+ expect(grandchildItems?.length).to.equal(1);
81
+ expect(grandchildItems?.[0].level).to.equal(3, 'Grandchildren are level 3');
82
+ });
83
+ it('can select child and grandchild items', async () => {
84
+ const treeItem = await fixture(html `
85
+ <glide-core-tree-item expanded label="Item">
86
+ <glide-core-tree-item label="Child Item 1"></glide-core-tree-item>
87
+ <glide-core-tree-item label="Child Item 2">
88
+ <glide-core-tree-item label="Grandchild Item 1"></glide-core-tree-item>
89
+ </glide-core-tree-item>
90
+ </glide-core-tree-item>
91
+ `);
92
+ const childItems = treeItem.slotElements;
93
+ const grandchildItems = childItems?.[1].slotElements;
94
+ treeItem.selectItem(childItems[0]);
95
+ expect(childItems[0].selected).to.equal(true);
96
+ expect(childItems[1].selected).to.equal(false);
97
+ expect(grandchildItems[0].selected).to.equal(false);
98
+ treeItem.selectItem(grandchildItems[0]);
99
+ expect(childItems[0].selected).to.equal(false);
100
+ expect(childItems[1].selected).to.equal(false);
101
+ expect(grandchildItems[0].selected).to.equal(true);
102
+ });
package/dist/tree.js CHANGED
@@ -1 +1 @@
1
- "use strict";var O=Object.defineProperty;var D=Object.getOwnPropertyDescriptor;var f=(r,o,e,t)=>{for(var s=t>1?void 0:t?D(o,e):o,l=r.length-1,h;l>=0;l--)(h=r[l])&&(s=(t?h(o,e,s):h(s))||s);return t&&s&&O(o,e,s),s};var A=(r,o,e)=>{if(!o.has(r))throw TypeError("Cannot "+e)};var u=(r,o,e)=>(A(r,o,"read from private field"),e?e.call(r):o.get(r)),d=(r,o,e)=>{if(o.has(r))throw TypeError("Cannot add the same private member more than once");o instanceof WeakSet?o.add(r):o.set(r,e)};var i=(r,o,e)=>(A(r,o,"access private method"),e);var m,c,a,g,F,E,R,v,H,I,y,p,k,w,M,T,$;import{LitElement as L,html as U}from"lit";import{createRef as q,ref as K}from"lit/directives/ref.js";import{customElement as N,queryAssignedElements as j,state as b}from"lit/decorators.js";import{owSlot as S,owSlotType as C}from"./library/ow.js";import x from"./tree.item.js";import z from"./tree.styles.js";let n=class extends L{constructor(){super();d(this,c);d(this,g);d(this,E);d(this,v);d(this,I);d(this,p);d(this,w);d(this,T);this.privateTabIndex=0;d(this,m,q());this.addEventListener("focusin",i(this,I,y)),this.addEventListener("focusout",i(this,p,k))}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener("focusin",i(this,I,y)),this.removeEventListener("focusout",i(this,p,k))}firstUpdated(){S(u(this,m).value),C(u(this,m).value,[x])}render(){return U`<div class="component" role="tree" tabindex="${this.privateTabIndex}" @click="${i(this,v,H)}" @keydown="${i(this,w,M)}"><slot @slotchange="${i(this,T,$)}" ${K(u(this,m))}></slot></div>`}selectItem(e){for(const t of this.slotElements)if(e===t)t.setAttribute("selected","true"),this.selectedItem=t;else{t.removeAttribute("selected");const s=t.selectItem(e);s&&(this.selectedItem=s)}this.dispatchEvent(new CustomEvent("item-selected",{bubbles:!0,detail:e}))}};m=new WeakMap,c=new WeakSet,a=function(e){e?.focus(),this.focusedItem=e},g=new WeakSet,F=function(){return[...this.querySelectorAll("glide-core-tree-item")]},E=new WeakSet,R=function(){const e=i(this,g,F).call(this),t=new Set;return e.filter(s=>{const l=s.parentElement?.closest("glide-core-tree-item");return l&&(!l.expanded||t.has(l))&&t.add(s),!t.has(s)})},v=new WeakSet,H=function(e){const t=e.target;if(t.closest("glide-core-tree-item-icon-button")??t.closest("glide-core-tree-item-menu"))return;const s=t.closest("glide-core-tree-item");s&&(s.hasChildTreeItems?s.toggleExpand():this.selectItem(s))},I=new WeakSet,y=function(e){let t;e.target===this?t=this.selectedItem??this.slotElements[0]:e.target instanceof x&&(t=e.target,this.privateTabIndex=-1),i(this,c,a).call(this,t)},p=new WeakSet,k=function(e){const t=e.relatedTarget;(!t||!this.contains(t))&&(this.privateTabIndex=0,this.focusedItem=void 0)},w=new WeakSet,M=function(e){if(!["ArrowRight","ArrowLeft","ArrowDown","ArrowUp","Home","End","Enter"].includes(e.key))return;const t=i(this,E,R).call(this),{focusedItem:s}=this,l=t.findIndex(h=>h.matches(":focus"));if(e.key==="ArrowRight"&&s?.hasChildTreeItems&&(s.expanded?i(this,c,a).call(this,s.slotElements[0]):s.toggleExpand()),e.key==="ArrowLeft")if(s?.expanded)s.toggleExpand();else{const h=s?.parentElement?.closest("glide-core-tree-item");i(this,c,a).call(this,h)}e.key==="ArrowDown"&&l!==-1&&l<t.length-1&&i(this,c,a).call(this,t[l+1]),e.key==="ArrowUp"&&l>0&&i(this,c,a).call(this,t[l-1]),e.key==="Home"&&i(this,c,a).call(this,t[0]),e.key==="End"&&i(this,c,a).call(this,t.at(-1)),e.key==="Enter"&&s&&(s.hasChildTreeItems?s.toggleExpand():this.selectItem(s))},T=new WeakSet,$=function(){S(u(this,m).value),C(u(this,m).value,[x])},n.shadowRootOptions={...L.shadowRootOptions,mode:"closed"},n.styles=z,f([b()],n.prototype,"selectedItem",2),f([b()],n.prototype,"focusedItem",2),f([b()],n.prototype,"privateTabIndex",2),f([j()],n.prototype,"slotElements",2),n=f([N("glide-core-tree")],n);export{n as default};
1
+ var __decorate=this&&this.__decorate||function(e,t,o,s){var r,l=arguments.length,i=l<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,o):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)i=Reflect.decorate(e,t,o,s);else for(var n=e.length-1;n>=0;n--)(r=e[n])&&(i=(l<3?r(i):l>3?r(t,o,i):r(t,o))||i);return l>3&&i&&Object.defineProperty(t,o,i),i};import{LitElement,html}from"lit";import{createRef,ref}from"lit/directives/ref.js";import{customElement,queryAssignedElements,state}from"lit/decorators.js";import{owSlot,owSlotType}from"./library/ow.js";import GlideCoreTreeItem from"./tree.item.js";import styles from"./tree.styles.js";let GlideCoreTree=class GlideCoreTree extends LitElement{static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener("focusin",this.#e),this.removeEventListener("focusout",this.#t)}firstUpdated(){owSlot(this.#o.value),owSlotType(this.#o.value,[GlideCoreTreeItem])}render(){return html`<div class="component" role="tree" tabindex="${this.privateTabIndex}" @click="${this.#s}" @keydown="${this.#r}"><slot @slotchange="${this.#l}" ${ref(this.#o)}></slot></div>`}selectItem(e){for(const t of this.slotElements)if(e===t)t.setAttribute("selected","true"),this.selectedItem=t;else{t.removeAttribute("selected");const o=t.selectItem(e);o&&(this.selectedItem=o)}this.dispatchEvent(new CustomEvent("item-selected",{bubbles:!0,detail:e}))}setContainingBlock(e){for(const t of this.#i())t.setContainingBlock(e)}constructor(){super(),this.privateTabIndex=0,this.#o=createRef(),this.addEventListener("focusin",this.#e),this.addEventListener("focusout",this.#t)}#o;#n(e){e?.focus(),this.focusedItem=e}#i(){return[...this.querySelectorAll("glide-core-tree-item")]}#d(){const e=this.#i(),t=new Set;return e.filter((e=>{const o=e.parentElement?.closest("glide-core-tree-item");return!o||o.expanded&&!t.has(o)||t.add(e),!t.has(e)}))}#s(e){const t=e.target;if(t.closest("glide-core-tree-item-icon-button")??t.closest("glide-core-tree-item-menu"))return;const o=t.closest("glide-core-tree-item");o&&(o.hasChildTreeItems?o.toggleExpand():this.selectItem(o))}#e(e){let t;e.target===this?t=this.selectedItem??this.slotElements[0]:e.target instanceof GlideCoreTreeItem&&(t=e.target,this.privateTabIndex=-1),this.#n(t)}#t(e){const t=e.relatedTarget;t&&this.contains(t)||(this.privateTabIndex=0,this.focusedItem=void 0)}#r(e){if(!["ArrowRight","ArrowLeft","ArrowDown","ArrowUp","Home","End","Enter"].includes(e.key))return;const t=this.#d(),{focusedItem:o}=this,s=t.findIndex((e=>e.matches(":focus")));if("ArrowRight"===e.key&&o?.hasChildTreeItems&&(o.expanded?this.#n(o.slotElements[0]):o.toggleExpand()),"ArrowLeft"===e.key)if(o?.expanded)o.toggleExpand();else{const e=o?.parentElement?.closest("glide-core-tree-item");this.#n(e)}"ArrowDown"===e.key&&-1!==s&&s<t.length-1&&this.#n(t[s+1]),"ArrowUp"===e.key&&s>0&&this.#n(t[s-1]),"Home"===e.key&&this.#n(t[0]),"End"===e.key&&this.#n(t.at(-1)),"Enter"===e.key&&o&&(o.hasChildTreeItems?o.toggleExpand():this.selectItem(o))}#l(){owSlot(this.#o.value),owSlotType(this.#o.value,[GlideCoreTreeItem])}};__decorate([state()],GlideCoreTree.prototype,"selectedItem",void 0),__decorate([state()],GlideCoreTree.prototype,"focusedItem",void 0),__decorate([state()],GlideCoreTree.prototype,"privateTabIndex",void 0),__decorate([queryAssignedElements()],GlideCoreTree.prototype,"slotElements",void 0),GlideCoreTree=__decorate([customElement("glide-core-tree")],GlideCoreTree);export default GlideCoreTree;
@@ -1,5 +1,6 @@
1
1
  import './icon-button.js';
2
2
  import './icons/storybook.js';
3
+ import './menu.link.js';
3
4
  import './tree.item.icon-button.js';
4
5
  import './tree.item.js';
5
6
  import './tree.js';
@@ -1,7 +1,7 @@
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
  font-family: var(--glide-core-body-sm-font-family);
4
4
  font-style: var(--glide-core-body-sm-font-style);
5
5
  font-weight: var(--glide-core-body-sm-font-weight);
6
6
  }
7
- `];
7
+ `];
@@ -0,0 +1,86 @@
1
+ import { expect, fixture, html } from '@open-wc/testing';
2
+ import GlideCoreTree from './tree.js';
3
+ import GlideCoreTreeItem from './tree.item.js';
4
+ GlideCoreTree.shadowRootOptions.mode = 'open';
5
+ GlideCoreTreeItem.shadowRootOptions.mode = 'open';
6
+ it('is accessible', async () => {
7
+ const component = await fixture(html `
8
+ <glide-core-tree>
9
+ <glide-core-tree-item label="Child Item 1"></glide-core-tree-item>
10
+ <glide-core-tree-item label="Child Item 2">
11
+ <glide-core-tree-item label="Grandchild Item 1"></glide-core-tree-item>
12
+ </glide-core-tree-item>
13
+ </glide-core-tree>
14
+ `);
15
+ await expect(component).to.be.accessible();
16
+ });
17
+ it('sets roles tree and treeitem', async () => {
18
+ const component = await fixture(html `
19
+ <glide-core-tree>
20
+ <glide-core-tree-item label="Child Item 1"></glide-core-tree-item>
21
+ <glide-core-tree-item label="Child Item 2">
22
+ <glide-core-tree-item label="Grandchild Item 1"></glide-core-tree-item>
23
+ </glide-core-tree-item>
24
+ </glide-core-tree>
25
+ `);
26
+ const childItems = component.slotElements;
27
+ expect(component.shadowRoot?.firstElementChild?.getAttribute('role')).to.equal('tree');
28
+ expect(childItems[0].shadowRoot?.querySelector('.component')?.getAttribute('role')).to.equal('treeitem');
29
+ expect(childItems[1].shadowRoot?.querySelector('.component')?.getAttribute('role')).to.equal('treeitem');
30
+ expect(childItems[1].slotElements[0].shadowRoot
31
+ ?.querySelector('.component')
32
+ ?.getAttribute('role')).to.equal('treeitem');
33
+ });
34
+ it('sets aria-expanded correctly', async () => {
35
+ const component = await fixture(html `
36
+ <glide-core-tree>
37
+ <glide-core-tree-item label="Child Item 1"></glide-core-tree-item>
38
+ <glide-core-tree-item label="Child Item 2">
39
+ <glide-core-tree-item label="Grandchild Item 1"></glide-core-tree-item>
40
+ </glide-core-tree-item>
41
+ <glide-core-tree-item label="Expanded child item" expanded>
42
+ <glide-core-tree-item label="Grandchild Item 2"></glide-core-tree-item>
43
+ </glide-core-tree-item>
44
+ </glide-core-tree>
45
+ `);
46
+ const childItems = component.slotElements;
47
+ expect(childItems[0].getAttribute('aria-expanded')).to.equal(null, 'does not set at all if there are no child items');
48
+ expect(childItems[1].shadowRoot
49
+ ?.querySelector('.component')
50
+ ?.getAttribute('aria-expanded')).to.equal('false', 'sets to string "false" if not expanded');
51
+ childItems[1].toggleExpand();
52
+ await childItems[1].updateComplete;
53
+ expect(childItems[1].shadowRoot
54
+ ?.querySelector('.component')
55
+ ?.getAttribute('aria-expanded')).to.equal('true', 'sets to string "true" after being expanded');
56
+ expect(childItems[2].shadowRoot
57
+ ?.querySelector('.component')
58
+ ?.getAttribute('aria-expanded')).to.equal('true', 'sets to string "true" if starts as expanded');
59
+ });
60
+ it('sets aria-selected correctly', async () => {
61
+ const component = await fixture(html `
62
+ <glide-core-tree>
63
+ <glide-core-tree-item label="Child Item 1">
64
+ <glide-core-tree-item label="Grandchild Item 1"></glide-core-tree-item>
65
+ </glide-core-tree-item>
66
+ <glide-core-tree-item label="Child Item 2"></glide-core-tree-item>
67
+ <glide-core-tree-item
68
+ label="Child Item 3"
69
+ selected
70
+ ></glide-core-tree-item>
71
+ </glide-core-tree>
72
+ `);
73
+ const childItems = component.slotElements;
74
+ expect(childItems[0].getAttribute('aria-selected')).to.equal(null, 'does not set at all if there are child items');
75
+ expect(childItems[1].shadowRoot
76
+ ?.querySelector('.component')
77
+ ?.getAttribute('aria-selected')).to.equal('false', 'sets to string "false" if not selected');
78
+ expect(childItems[2].shadowRoot
79
+ ?.querySelector('.component')
80
+ ?.getAttribute('aria-selected')).to.equal('true', 'sets to string "true" if starts as selected');
81
+ component.selectItem(childItems[1]);
82
+ await childItems[1].updateComplete;
83
+ expect(childItems[1].shadowRoot
84
+ ?.querySelector('.component')
85
+ ?.getAttribute('aria-selected')).to.equal('true', 'sets to string "true" after being selected');
86
+ });
@@ -0,0 +1,123 @@
1
+ import './tree.item.icon-button.js';
2
+ import './tree.item.js';
3
+ import './tree.js';
4
+ import { ArgumentError } from 'ow';
5
+ import { assert, expect, fixture, html } from '@open-wc/testing';
6
+ import GlideCoreTree from './tree.js';
7
+ import expectArgumentError from './library/expect-argument-error.js';
8
+ import sinon from 'sinon';
9
+ GlideCoreTree.shadowRootOptions.mode = 'open';
10
+ it('registers', async () => {
11
+ expect(window.customElements.get('glide-core-tree')).to.equal(GlideCoreTree);
12
+ });
13
+ it('renders and sets default attributes', async () => {
14
+ const tree = await fixture(html `
15
+ <glide-core-tree>
16
+ <glide-core-tree-item label="Child Item"></glide-core-tree-item>
17
+ </glide-core-tree>
18
+ `);
19
+ expect(tree.selectedItem).to.equal(undefined);
20
+ });
21
+ it('can select child and grandchild items', async () => {
22
+ const tree = await fixture(html `
23
+ <glide-core-tree>
24
+ <glide-core-tree-item label="Child Item 1"></glide-core-tree-item>
25
+ <glide-core-tree-item label="Child Item 2">
26
+ <glide-core-tree-item label="Grandchild Item 1"></glide-core-tree-item>
27
+ </glide-core-tree-item>
28
+ </glide-core-tree>
29
+ `);
30
+ const childItems = tree.slotElements;
31
+ const grandchildItems = childItems?.[1].slotElements;
32
+ tree.selectItem(childItems[0]);
33
+ expect(childItems[0].selected).to.equal(true);
34
+ expect(tree.selectedItem).to.equal(childItems[0]);
35
+ expect(childItems[1].selected).to.equal(false);
36
+ expect(grandchildItems[0].selected).to.equal(false);
37
+ tree.selectItem(grandchildItems[0]);
38
+ expect(childItems[0].selected).to.equal(false);
39
+ expect(childItems[1].selected).to.equal(false);
40
+ expect(grandchildItems[0].selected).to.equal(true);
41
+ expect(tree.selectedItem).to.equal(grandchildItems[0]);
42
+ });
43
+ it('can click child and grandchild items to expand or select them', async () => {
44
+ const tree = await fixture(html `
45
+ <glide-core-tree>
46
+ <glide-core-tree-item label="Child Item 1"></glide-core-tree-item>
47
+ <glide-core-tree-item label="Child Item 2">
48
+ <glide-core-tree-item label="Grandchild Item 1"></glide-core-tree-item>
49
+ </glide-core-tree-item>
50
+ </glide-core-tree>
51
+ `);
52
+ const childItems = tree.slotElements;
53
+ const grandchildItems = childItems?.[1].slotElements;
54
+ // Clicking an item that doesn't have children selects it
55
+ childItems[0].click();
56
+ expect(childItems[0].selected).to.equal(true);
57
+ expect(childItems[1].selected).to.equal(false);
58
+ expect(grandchildItems[0].selected).to.equal(false);
59
+ expect(childItems[1].expanded).to.equal(false);
60
+ // Clicking an item that has children expands it
61
+ childItems[1].click();
62
+ expect(childItems[1].expanded).to.equal(true);
63
+ // Can click and select a grandchild item
64
+ grandchildItems[0].click();
65
+ expect(grandchildItems[0].selected).to.equal(true);
66
+ });
67
+ it('does not select an item if a tree-item-icon-button is clicked', async () => {
68
+ const tree = await fixture(html `
69
+ <glide-core-tree>
70
+ <glide-core-tree-item label="Child Item 1">
71
+ <glide-core-tree-item-icon-button slot="suffix" data-test-icon-button>
72
+ <svg viewBox="0 0 24 24">
73
+ <path d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
74
+ </svg>
75
+ </glide-core-tree-item-icon-button>
76
+ </glide-core-tree-item>
77
+ </glide-core-tree>
78
+ `);
79
+ const childItems = tree.slotElements;
80
+ const iconButton = childItems[0].querySelector('[data-test-icon-button]');
81
+ assert(iconButton);
82
+ iconButton.click();
83
+ await iconButton.updateComplete;
84
+ expect(childItems[0].selected).to.equal(false);
85
+ });
86
+ it('does not select an item if its menu slot is clicked', async () => {
87
+ const tree = await fixture(html `
88
+ <glide-core-tree>
89
+ <glide-core-tree-item label="Child Item 1">
90
+ <glide-core-tree-item-menu slot="menu" data-test-menu>
91
+ <glide-core-menu-link label="Edit" url="/edit"></glide-core-menu-link>
92
+ </glide-core-tree-item-menu>
93
+ </glide-core-tree-item>
94
+ </glide-core-tree>
95
+ `);
96
+ const childItems = tree.slotElements;
97
+ const menu = childItems[0].querySelector('[data-test-menu]');
98
+ assert(menu);
99
+ menu.click();
100
+ await menu.updateComplete;
101
+ expect(childItems[0].selected).to.equal(false);
102
+ });
103
+ it('throws if it does not have a default slot', async () => {
104
+ const spy = sinon.spy();
105
+ try {
106
+ await fixture(html `<glide-core-tree></glide-core-tree>`);
107
+ }
108
+ catch (error) {
109
+ if (error instanceof ArgumentError) {
110
+ spy();
111
+ }
112
+ }
113
+ expect(spy.called).to.be.true;
114
+ });
115
+ it('throws if the default slot is the incorrect type', async () => {
116
+ await expectArgumentError(() => {
117
+ return fixture(html `
118
+ <glide-core-tree>
119
+ <button>Button</button>
120
+ </glide-core-tree>
121
+ `);
122
+ });
123
+ });
@@ -0,0 +1,19 @@
1
+ import './tree.item.menu.js';
2
+ import './tree.js';
3
+ import { expect, fixture, html, oneEvent } from '@open-wc/testing';
4
+ import GlideCoreTree from './tree.js';
5
+ import GlideCoreTreeItem from './tree.item.js';
6
+ it('dispatches an "item-selected" event when an item is clicked', async () => {
7
+ const component = await fixture(html `
8
+ <glide-core-tree>
9
+ <glide-core-tree-item label="Child Item"></glide-core-tree-item>
10
+ </glide-core-tree>
11
+ `);
12
+ setTimeout(() => {
13
+ component.querySelector('glide-core-tree-item')?.click();
14
+ });
15
+ const event = await oneEvent(component, 'item-selected');
16
+ expect(event instanceof CustomEvent).to.be.true;
17
+ expect(event.bubbles).to.be.true;
18
+ expect(event.detail instanceof GlideCoreTreeItem).to.be.true;
19
+ });