@crowdstrike/glide-core 0.6.5 → 0.8.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 (140) hide show
  1. package/README.md +44 -5
  2. package/dist/accordion.test.basics.js +1 -0
  3. package/dist/accordion.test.events.js +1 -0
  4. package/dist/button-group.button.test.basics.js +1 -0
  5. package/dist/button-group.button.test.events.js +1 -0
  6. package/dist/button-group.test.basics.js +1 -0
  7. package/dist/button-group.test.events.js +1 -0
  8. package/dist/button.test.basics.js +1 -0
  9. package/dist/button.test.events.js +1 -0
  10. package/dist/button.test.form.js +1 -0
  11. package/dist/checkbox-group.d.ts +1 -0
  12. package/dist/checkbox-group.js +1 -1
  13. package/dist/checkbox-group.test.basics.js +1 -0
  14. package/dist/checkbox-group.test.events.js +1 -0
  15. package/dist/checkbox-group.test.focus.js +24 -0
  16. package/dist/checkbox-group.test.form.js +1 -0
  17. package/dist/checkbox-group.test.validity.js +1 -0
  18. package/dist/checkbox.d.ts +3 -1
  19. package/dist/checkbox.js +1 -1
  20. package/dist/checkbox.styles.js +4 -5
  21. package/dist/checkbox.test.basics.js +1 -0
  22. package/dist/checkbox.test.events.js +1 -0
  23. package/dist/checkbox.test.focus.js +11 -0
  24. package/dist/checkbox.test.form.js +1 -0
  25. package/dist/checkbox.test.states.js +1 -0
  26. package/dist/checkbox.test.validity.js +1 -0
  27. package/dist/drawer.styles.js +4 -3
  28. package/dist/drawer.test.basics.js +1 -0
  29. package/dist/drawer.test.closing.js +1 -0
  30. package/dist/drawer.test.events.js +1 -0
  31. package/dist/drawer.test.floating-components.js +1 -0
  32. package/dist/drawer.test.methods.js +1 -0
  33. package/dist/dropdown.d.ts +1 -0
  34. package/dist/dropdown.js +1 -1
  35. package/dist/dropdown.option.d.ts +1 -0
  36. package/dist/dropdown.option.js +1 -1
  37. package/dist/dropdown.option.test.basics.js +1 -0
  38. package/dist/dropdown.option.test.basics.multiple.js +1 -0
  39. package/dist/dropdown.option.test.basics.single.js +1 -0
  40. package/dist/dropdown.option.test.events.js +1 -0
  41. package/dist/dropdown.option.test.interactions.multiple.js +1 -0
  42. package/dist/dropdown.option.test.interactions.single.js +1 -0
  43. package/dist/dropdown.styles.js +8 -4
  44. package/dist/dropdown.test.basics.filterable.js +1 -0
  45. package/dist/dropdown.test.basics.js +1 -0
  46. package/dist/dropdown.test.basics.multiple.js +1 -1
  47. package/dist/dropdown.test.basics.single.js +1 -1
  48. package/dist/dropdown.test.events.js +1 -0
  49. package/dist/dropdown.test.events.multiple.js +72 -5
  50. package/dist/dropdown.test.events.single.js +46 -5
  51. package/dist/dropdown.test.focus.js +11 -2
  52. package/dist/dropdown.test.focus.multiple.js +0 -1
  53. package/dist/dropdown.test.form.js +1 -0
  54. package/dist/dropdown.test.form.multiple.js +1 -0
  55. package/dist/dropdown.test.form.single.js +1 -0
  56. package/dist/dropdown.test.interactions.filterable.js +1 -0
  57. package/dist/dropdown.test.interactions.js +1 -0
  58. package/dist/dropdown.test.interactions.multiple.js +1 -1
  59. package/dist/dropdown.test.interactions.single.js +1 -0
  60. package/dist/dropdown.test.validity.js +1 -0
  61. package/dist/form-controls-layout.test.basics.js +1 -0
  62. package/dist/icon-button.test.basics.js +1 -0
  63. package/dist/input.d.ts +2 -1
  64. package/dist/input.js +1 -1
  65. package/dist/input.test.basics.js +1 -0
  66. package/dist/input.test.events.js +1 -0
  67. package/dist/input.test.focus.js +6 -3
  68. package/dist/input.test.form.js +1 -0
  69. package/dist/input.test.validity.js +1 -0
  70. package/dist/label.styles.js +11 -11
  71. package/dist/label.test.basics.js +1 -0
  72. package/dist/library/localize.d.ts +2 -0
  73. package/dist/library/ow.test.d.ts +2 -1
  74. package/dist/library/ow.test.js +8 -3
  75. package/dist/menu.button.test.basics.js +1 -0
  76. package/dist/menu.link.test.basics.js +1 -0
  77. package/dist/menu.options.test.basics.js +1 -0
  78. package/dist/menu.styles.js +4 -4
  79. package/dist/menu.test.basics.js +1 -0
  80. package/dist/menu.test.events.d.ts +1 -0
  81. package/dist/menu.test.events.js +2 -1
  82. package/dist/menu.test.focus.js +1 -0
  83. package/dist/menu.test.interactions.js +1 -0
  84. package/dist/modal.icon-button.test.basics.js +1 -0
  85. package/dist/modal.tertiary-icon.test.basics.js +1 -0
  86. package/dist/modal.test.accessibility.js +1 -0
  87. package/dist/modal.test.basics.js +1 -0
  88. package/dist/modal.test.close.js +1 -0
  89. package/dist/modal.test.events.js +1 -0
  90. package/dist/modal.test.floating-components.js +1 -0
  91. package/dist/modal.test.lock-scroll.js +1 -0
  92. package/dist/modal.test.methods.js +1 -0
  93. package/dist/modal.test.scrollbars.js +1 -0
  94. package/dist/radio-group.d.ts +1 -0
  95. package/dist/radio-group.js +1 -1
  96. package/dist/radio-group.test.basics.js +1 -0
  97. package/dist/radio-group.test.events.js +1 -0
  98. package/dist/radio-group.test.focus.js +20 -0
  99. package/dist/radio-group.test.form.js +1 -0
  100. package/dist/radio-group.test.validity.js +1 -0
  101. package/dist/split-button.test.basics.js +1 -0
  102. package/dist/split-container.test.basics.js +1 -0
  103. package/dist/split-link.test.basics.js +1 -0
  104. package/dist/split-link.test.interactions.js +1 -0
  105. package/dist/tab.d.ts +0 -2
  106. package/dist/tab.group.d.ts +3 -5
  107. package/dist/tab.group.js +1 -1
  108. package/dist/tab.group.styles.js +27 -13
  109. package/dist/tab.group.test.basics.js +7 -56
  110. package/dist/tab.group.test.interactions.d.ts +3 -0
  111. package/dist/tab.group.test.interactions.js +258 -0
  112. package/dist/tab.js +1 -1
  113. package/dist/tab.styles.js +7 -68
  114. package/dist/tab.test.basics.js +0 -20
  115. package/dist/tabs.stories.d.ts +1 -2
  116. package/dist/tag.test.basics.js +1 -0
  117. package/dist/textarea.d.ts +1 -0
  118. package/dist/textarea.js +2 -2
  119. package/dist/textarea.test.basics.js +1 -0
  120. package/dist/textarea.test.events.js +1 -0
  121. package/dist/textarea.test.form.js +1 -0
  122. package/dist/textarea.test.validity.js +14 -1
  123. package/dist/toggle.test.basics.js +1 -0
  124. package/dist/toggle.test.events.js +1 -0
  125. package/dist/toggle.test.states.js +1 -0
  126. package/dist/tooltip.test.basics.js +1 -0
  127. package/dist/tooltip.test.interactions.js +1 -0
  128. package/dist/translations/en.js +1 -1
  129. package/dist/translations/fr.js +1 -1
  130. package/dist/translations/ja.js +1 -1
  131. package/dist/tree.item.d.ts +4 -1
  132. package/dist/tree.item.js +1 -1
  133. package/dist/tree.item.menu.js +1 -1
  134. package/dist/tree.item.test.basics.js +12 -0
  135. package/dist/tree.js +1 -1
  136. package/dist/tree.stories.d.ts +1 -0
  137. package/dist/tree.test.basics.js +7 -0
  138. package/dist/tree.test.events.js +1 -1
  139. package/dist/tree.test.focus.js +32 -0
  140. package/package.json +39 -26
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-expressions */
1
2
  import './button.js';
2
3
  import { ArgumentError } from 'ow';
3
4
  import { expect, fixture, html } from '@open-wc/testing';
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-expressions */
1
2
  import { expect, fixture, html } from '@open-wc/testing';
2
3
  import GlideCoreModal from './modal.js';
3
4
  GlideCoreModal.shadowRootOptions.mode = 'open';
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-expressions */
1
2
  import './button.js';
2
3
  import './modal.icon-button.js';
3
4
  import './modal.js';
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-expressions */
1
2
  import { expect, fixture, html } from '@open-wc/testing';
2
3
  import { sendKeys } from '@web/test-runner-commands';
3
4
  import GlideCoreModal from './modal.js';
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-expressions */
1
2
  import './modal.js';
2
3
  import { expect, fixture, html } from '@open-wc/testing';
3
4
  import { sendKeys, sendMouse } from '@web/test-runner-commands';
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-expressions */
1
2
  import { expect, fixture, html } from '@open-wc/testing';
2
3
  import GlideCoreModal from './modal.js';
3
4
  import GlideCoreModalTertiaryIcon from './modal.tertiary-icon.js';
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-expressions */
1
2
  import * as sinon from 'sinon';
2
3
  import { expect, fixture, html } from '@open-wc/testing';
3
4
  import { sendKeys, sendMouse } from '@web/test-runner-commands';
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-expressions */
1
2
  import { expect, fixture, html } from '@open-wc/testing';
2
3
  import GlideCoreModal from './modal.js';
3
4
  GlideCoreModal.shadowRootOptions.mode = 'open';
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-expressions */
1
2
  import './modal.js';
2
3
  import * as sinon from 'sinon';
3
4
  import { expect, fixture, html } from '@open-wc/testing';
@@ -44,6 +44,7 @@ export default class GlideCoreRadioGroup extends LitElement {
44
44
  updated(changedProperties: PropertyValueMap<GlideCoreRadioGroup>): void;
45
45
  willUpdate(changedProperties: PropertyValueMap<GlideCoreRadioGroup>): void;
46
46
  constructor();
47
+ private isBlurring;
47
48
  private isCheckingValidity;
48
49
  private isReportValidityOrSubmit;
49
50
  }
@@ -1 +1 @@
1
- var __decorate=this&&this.__decorate||function(e,i,t,o){var s,d=arguments.length,a=d<3?i:null===o?o=Object.getOwnPropertyDescriptor(i,t):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,i,t,o);else for(var r=e.length-1;r>=0;r--)(s=e[r])&&(a=(d<3?s(a):d>3?s(i,t,a):s(i,t))||a);return d>3&&a&&Object.defineProperty(i,t,a),a};import"./label.js";import"./tooltip.js";import{LitElement,html}from"lit";import{classMap}from"lit/directives/class-map.js";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property,state}from"lit/decorators.js";import{ifDefined}from"lit/directives/if-defined.js";import{owSlot,owSlotType}from"./library/ow.js";import GlideCoreRadio from"./radio.js";import styles from"./radio-group.styles.js";let GlideCoreRadioGroup=class GlideCoreRadioGroup extends LitElement{static{this.formAssociated=!0}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}checkValidity(){return this.isCheckingValidity=!0,this.#e.checkValidity()}disconnectedCallback(){super.disconnectedCallback(),this.form?.removeEventListener("formdata",this.#i),this.#t=void 0}firstUpdated(){owSlot(this.#o.value),owSlotType(this.#o.value,[GlideCoreRadio]),this.#t=this.#s.find((e=>e.checked)),this.#d()}focus(e){let i=this.#s.find((e=>e.checked));i||(i=this.#s.find((e=>0===e.tabIndex))),i?.focus(e)}get form(){return this.#e.form}get validity(){return this.#e.validity}get willValidate(){return this.#e.willValidate}formAssociatedCallback(){this.form?.addEventListener("formdata",this.#i)}formResetCallback(){if(this.#t&&this.contains(this.#t))for(const e of this.#s)this.#a(e===this.#t,e)}render(){return html`<div class="component" @click="${this.#r}" @keydown="${this.#l}" ${ref(this.#n)}><glide-core-label orientation="horizontal" split="${ifDefined(this.privateSplit??void 0)}" ?disabled="${this.disabled}" ?error="${this.#h}" ?hide="${this.hideLabel}" ?required="${this.required}"><label id="label" data-test="label">${this.label}</label><div class="${classMap({"radio-container":!0,vertical:!0,invalid:this.#h})}" role="radiogroup" slot="control" aria-labelledby="label description"><slot ${ref(this.#o)} @slotchange="${this.#c}"></slot></div><slot name="tooltip" slot="tooltip"></slot><slot id="description" name="description" slot="description"></slot></glide-core-label></div>`}reportValidity(){return this.#e.reportValidity()}updated(e){this.hasUpdated&&(e.has("value")||e.has("required"))&&(this.#p(),this.#f(!this.#e.validity.valid),this.requestUpdate())}willUpdate(e){if(this.hasUpdated){if(e.has("required")&&this.#u(),e.has("disabled")){for(const e of this.#s)this.#R(this.disabled,e);!this.disabled&&this.#m()}if(e.has("value"))for(const e of this.#s)e.checked=e.value===this.value}}constructor(){super(),this.description="",this.disabled=!1,this.label="",this.hideLabel=!1,this.name="",this.required=!1,this.value="",this.isCheckingValidity=!1,this.isReportValidityOrSubmit=!1,this.#n=createRef(),this.#o=createRef(),this.#t=void 0,this.#i=({formData:e})=>{this.name&&this.value.length>0&&!this.disabled&&e.append(this.name,this.value)},this.#e=this.attachInternals(),this.addEventListener("invalid",this.#b)}#n;#o;#t;#e;#v;#i;#d(){const e=this.#s.find((e=>e.checked));this.value=e?.value??this.#t?.value??"",this.#v=e??this.#t,this.required&&this.#u();for(const e of this.#s)this.disabled?this.#R(this.disabled,e):this.#R(e.disabled,e);!this.disabled&&this.#m()}get#h(){const e=!this.disabled&&!this.validity.valid&&this.isReportValidityOrSubmit;return this.#f(e),e}#r(e){if(this.disabled)return;if(e.target instanceof GlideCoreRadio&&e.target.disabled&&this.#v&&!this.#v.disabled)return void this.#v?.focus();const i=e.target;if(i instanceof GlideCoreRadio&&i&&!i.disabled){this.#a(!0,i);for(const e of this.#s)e!==i&&this.#a(!1,e)}}#c(){owSlot(this.#o.value),owSlotType(this.#o.value,[GlideCoreRadio]),this.#d()}#b(e){e.preventDefault(),this.isCheckingValidity||(this.isReportValidityOrSubmit=!0,this.focus())}#l(e){if(!(this.disabled||e.target instanceof GlideCoreRadio&&e.target?.disabled)&&e.target instanceof GlideCoreRadio){const i=e.target;switch(e.key){case"ArrowUp":case"ArrowLeft":{e.preventDefault();let t=i.previousElementSibling;for(;(!t||t instanceof GlideCoreRadio&&t.disabled||!(t instanceof GlideCoreRadio))&&t!==i;)if(null===t){const e=this.#s.at(-1);e&&(t=e)}else t=t.previousElementSibling;t&&t instanceof GlideCoreRadio&&!t.disabled&&t!==i&&(this.#a(!1,i),this.#a(!0,t));break}case"ArrowDown":case"ArrowRight":{e.preventDefault();let t=i.nextElementSibling;for(;(!t||t instanceof GlideCoreRadio&&t.disabled||!(t instanceof GlideCoreRadio))&&t!==i;)if(null===t){const e=this.#s.at(0);e&&(t=e)}else t=t.nextElementSibling;t&&t instanceof GlideCoreRadio&&!t.disabled&&t!==i&&(this.#a(!1,i),this.#a(!0,t));break}case" ":if(e.preventDefault(),!i.disabled&&!i.checked){this.#a(!0,i);for(const e of this.#s)e!==i&&this.#a(!1,e)}}}}#p(){const e=this.#s.find((e=>e.checked));this.required&&!e?this.#e.setValidity({valueMissing:!0}," ",this.#n.value):this.#e.setValidity({})}get#s(){return this.#o.value?.assignedElements().filter((e=>e instanceof GlideCoreRadio))??[]}#a(e,i){i.checked=e,i.tabIndex=e?0:-1,e&&(this.#v=i,this.value=i.value,i.focus(),i.dispatchEvent(new Event("change",{bubbles:!0})),i.dispatchEvent(new Event("input",{bubbles:!0})))}#R(e,i){i.disabled=e,e&&(i.tabIndex=-1)}#f(e){for(const i of this.#s)i.invalid=e}#m(){if(this.disabled||this.#s.every((e=>e.disabled)))return;let e=null;const i=this.#s.find((e=>!e.disabled&&e.checked));if(i)e=i;else{const i=this.#s.find((e=>!e.disabled));i&&(e=i)}if(e)for(const i of this.#s)i.tabIndex=i===e?0:-1}#u(){for(const e of this.#s)e.required=this.required}};__decorate([property()],GlideCoreRadioGroup.prototype,"description",void 0),__decorate([property({type:Boolean,reflect:!0})],GlideCoreRadioGroup.prototype,"disabled",void 0),__decorate([property()],GlideCoreRadioGroup.prototype,"label",void 0),__decorate([property({attribute:"hide-label",type:Boolean})],GlideCoreRadioGroup.prototype,"hideLabel",void 0),__decorate([property()],GlideCoreRadioGroup.prototype,"name",void 0),__decorate([property()],GlideCoreRadioGroup.prototype,"privateSplit",void 0),__decorate([property({type:Boolean,reflect:!0})],GlideCoreRadioGroup.prototype,"required",void 0),__decorate([property({reflect:!0})],GlideCoreRadioGroup.prototype,"value",void 0),__decorate([state()],GlideCoreRadioGroup.prototype,"isCheckingValidity",void 0),__decorate([state()],GlideCoreRadioGroup.prototype,"isReportValidityOrSubmit",void 0),GlideCoreRadioGroup=__decorate([customElement("glide-core-radio-group")],GlideCoreRadioGroup);export default GlideCoreRadioGroup;
1
+ var __decorate=this&&this.__decorate||function(e,i,t,o){var s,d=arguments.length,a=d<3?i:null===o?o=Object.getOwnPropertyDescriptor(i,t):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,i,t,o);else for(var r=e.length-1;r>=0;r--)(s=e[r])&&(a=(d<3?s(a):d>3?s(i,t,a):s(i,t))||a);return d>3&&a&&Object.defineProperty(i,t,a),a};import"./label.js";import"./tooltip.js";import{LitElement,html}from"lit";import{classMap}from"lit/directives/class-map.js";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property,state}from"lit/decorators.js";import{ifDefined}from"lit/directives/if-defined.js";import{owSlot,owSlotType}from"./library/ow.js";import GlideCoreRadio from"./radio.js";import styles from"./radio-group.styles.js";let GlideCoreRadioGroup=class GlideCoreRadioGroup extends LitElement{static{this.formAssociated=!0}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}checkValidity(){this.isCheckingValidity=!0;const e=this.#e.checkValidity();return this.isCheckingValidity=!1,e}disconnectedCallback(){super.disconnectedCallback(),this.form?.removeEventListener("formdata",this.#i),this.#t=void 0}firstUpdated(){owSlot(this.#o.value),owSlotType(this.#o.value,[GlideCoreRadio]),this.#t=this.#s.find((e=>e.checked)),this.#d()}focus(e){let i=this.#s.find((e=>e.checked));i||(i=this.#s.find((e=>0===e.tabIndex))),i?.focus(e)}get form(){return this.#e.form}get validity(){return this.#e.validity}get willValidate(){return this.#e.willValidate}formAssociatedCallback(){this.form?.addEventListener("formdata",this.#i)}formResetCallback(){if(this.#t&&this.contains(this.#t))for(const e of this.#s)this.#a(e===this.#t,e)}render(){return html`<div class="component" @click="${this.#r}" @keydown="${this.#l}" ${ref(this.#n)}><glide-core-label orientation="horizontal" split="${ifDefined(this.privateSplit??void 0)}" ?disabled="${this.disabled}" ?error="${this.#h}" ?hide="${this.hideLabel}" ?required="${this.required}"><label id="label" data-test="label">${this.label}</label><div class="${classMap({"radio-container":!0,vertical:!0,invalid:this.#h})}" role="radiogroup" slot="control" aria-labelledby="label description" @blur="${this.#c}"><slot ${ref(this.#o)} @slotchange="${this.#p}"></slot></div><slot name="tooltip" slot="tooltip"></slot><slot id="description" name="description" slot="description"></slot></glide-core-label></div>`}reportValidity(){this.isReportValidityOrSubmit=!0;const e=this.#e.reportValidity();return this.requestUpdate(),e}updated(e){this.hasUpdated&&(e.has("value")||e.has("required"))&&(this.#f(),this.#u(!this.#e.validity.valid),this.requestUpdate())}willUpdate(e){if(this.hasUpdated){if(e.has("required")&&this.#R(),e.has("disabled")){for(const e of this.#s)this.#m(this.disabled,e);!this.disabled&&this.#b()}if(e.has("value"))for(const e of this.#s)e.checked=e.value===this.value}}constructor(){super(),this.description="",this.disabled=!1,this.label="",this.hideLabel=!1,this.name="",this.required=!1,this.value="",this.isBlurring=!1,this.isCheckingValidity=!1,this.isReportValidityOrSubmit=!1,this.#n=createRef(),this.#o=createRef(),this.#t=void 0,this.#i=({formData:e})=>{this.name&&this.value.length>0&&!this.disabled&&e.append(this.name,this.value)},this.#e=this.attachInternals(),this.addEventListener("invalid",this.#v)}#n;#o;#t;#e;#C;#i;#d(){const e=this.#s.find((e=>e.checked));this.value=e?.value??this.#t?.value??"",this.#C=e??this.#t,this.required&&this.#R();for(const e of this.#s)this.disabled?this.#m(this.disabled,e):this.#m(e.disabled,e),e.addEventListener("blur",this.#y.bind(this));!this.disabled&&this.#b()}get#h(){const e=!this.disabled&&!this.validity.valid&&this.isReportValidityOrSubmit;return this.#u(e),e}#c(){this.isBlurring=!0,this.reportValidity(),this.isBlurring=!1}#r(e){if(this.disabled)return;if(e.target instanceof GlideCoreRadio&&e.target.disabled&&this.#C&&!this.#C.disabled)return void this.#C?.focus();const i=e.target;if(i instanceof GlideCoreRadio&&i&&!i.disabled){this.#a(!0,i);for(const e of this.#s)e!==i&&this.#a(!1,e)}}#p(){owSlot(this.#o.value),owSlotType(this.#o.value,[GlideCoreRadio]),this.#d()}#v(e){if(e.preventDefault(),!this.isCheckingValidity){if(e?.preventDefault(),this.isCheckingValidity||this.isBlurring)return;this.isReportValidityOrSubmit=!0;this.form?.querySelector(":invalid")===this&&this.focus()}}#l(e){if(!(this.disabled||e.target instanceof GlideCoreRadio&&e.target?.disabled)&&e.target instanceof GlideCoreRadio){const i=e.target;switch(e.key){case"ArrowUp":case"ArrowLeft":{e.preventDefault();let t=i.previousElementSibling;for(;(!t||t instanceof GlideCoreRadio&&t.disabled||!(t instanceof GlideCoreRadio))&&t!==i;)if(null===t){const e=this.#s.at(-1);e&&(t=e)}else t=t.previousElementSibling;t&&t instanceof GlideCoreRadio&&!t.disabled&&t!==i&&(this.#a(!1,i),this.#a(!0,t));break}case"ArrowDown":case"ArrowRight":{e.preventDefault();let t=i.nextElementSibling;for(;(!t||t instanceof GlideCoreRadio&&t.disabled||!(t instanceof GlideCoreRadio))&&t!==i;)if(null===t){const e=this.#s.at(0);e&&(t=e)}else t=t.nextElementSibling;t&&t instanceof GlideCoreRadio&&!t.disabled&&t!==i&&(this.#a(!1,i),this.#a(!0,t));break}case" ":if(e.preventDefault(),!i.disabled&&!i.checked){this.#a(!0,i);for(const e of this.#s)e!==i&&this.#a(!1,e)}}}}#y(e){const i=e.relatedTarget;i&&i instanceof GlideCoreRadio&&this.#s.includes(i)||this.#c()}#f(){const e=this.#s.find((e=>e.checked));this.required&&!e?this.#e.setValidity({valueMissing:!0}," ",this.#n.value):this.#e.setValidity({})}get#s(){return this.#o.value?.assignedElements().filter((e=>e instanceof GlideCoreRadio))??[]}#a(e,i){i.checked=e,i.tabIndex=e?0:-1,e&&(this.#C=i,this.value=i.value,i.focus(),i.dispatchEvent(new Event("change",{bubbles:!0})),i.dispatchEvent(new Event("input",{bubbles:!0})))}#m(e,i){i.disabled=e,e&&(i.tabIndex=-1)}#u(e){for(const i of this.#s)i.invalid=e}#b(){if(this.disabled||this.#s.every((e=>e.disabled)))return;let e=null;const i=this.#s.find((e=>!e.disabled&&e.checked));if(i)e=i;else{const i=this.#s.find((e=>!e.disabled));i&&(e=i)}if(e)for(const i of this.#s)i.tabIndex=i===e?0:-1}#R(){for(const e of this.#s)e.required=this.required}};__decorate([property()],GlideCoreRadioGroup.prototype,"description",void 0),__decorate([property({type:Boolean,reflect:!0})],GlideCoreRadioGroup.prototype,"disabled",void 0),__decorate([property()],GlideCoreRadioGroup.prototype,"label",void 0),__decorate([property({attribute:"hide-label",type:Boolean})],GlideCoreRadioGroup.prototype,"hideLabel",void 0),__decorate([property()],GlideCoreRadioGroup.prototype,"name",void 0),__decorate([property()],GlideCoreRadioGroup.prototype,"privateSplit",void 0),__decorate([property({type:Boolean,reflect:!0})],GlideCoreRadioGroup.prototype,"required",void 0),__decorate([property({reflect:!0})],GlideCoreRadioGroup.prototype,"value",void 0),__decorate([state()],GlideCoreRadioGroup.prototype,"isBlurring",void 0),__decorate([state()],GlideCoreRadioGroup.prototype,"isCheckingValidity",void 0),__decorate([state()],GlideCoreRadioGroup.prototype,"isReportValidityOrSubmit",void 0),GlideCoreRadioGroup=__decorate([customElement("glide-core-radio-group")],GlideCoreRadioGroup);export default GlideCoreRadioGroup;
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-expressions */
1
2
  import './radio-group.js';
2
3
  import './radio.js';
3
4
  import { elementUpdated, expect, fixture, html } from '@open-wc/testing';
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-expressions */
1
2
  import './radio-group.js';
2
3
  import './radio.js';
3
4
  import { elementUpdated, expect, fixture, html, oneEvent, } from '@open-wc/testing';
@@ -1,6 +1,8 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-expressions */
1
2
  import './radio-group.js';
2
3
  import './radio.js';
3
4
  import { expect, fixture, html } from '@open-wc/testing';
5
+ import { sendKeys } from '@web/test-runner-commands';
4
6
  import GlideCoreRadio from './radio.js';
5
7
  import GlideCoreRadioGroup from './radio-group.js';
6
8
  GlideCoreRadio.shadowRootOptions.mode = 'open';
@@ -73,3 +75,21 @@ it('focuses the first tabbable radio when none are checked', async () => {
73
75
  const radio = component.querySelector('glide-core-radio[value="value-2"]');
74
76
  expect(radio).to.have.focus;
75
77
  });
78
+ it('reports validity if blurred', async () => {
79
+ const component = await fixture(html `<glide-core-radio-group label="Checkbox Group" required>
80
+ <glide-core-radio value="value-1" label="One"></glide-core-radio>
81
+ <glide-core-radio value="value-2" label="Two"></glide-core-radio>
82
+ </glide-core-radio-group>`);
83
+ component.focus();
84
+ const radioItems = component.querySelectorAll('glide-core-radio');
85
+ expect(document.activeElement === radioItems[0]).to.be.true;
86
+ expect(component.shadowRoot
87
+ ?.querySelector('glide-core-label')
88
+ ?.hasAttribute('error')).to.be.false;
89
+ await sendKeys({ press: 'Tab' });
90
+ expect(document.activeElement === document.body).to.be.true;
91
+ expect(component.validity.valid).to.equal(false);
92
+ expect(component.shadowRoot
93
+ ?.querySelector('glide-core-label')
94
+ ?.hasAttribute('error')).to.be.true;
95
+ });
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-expressions */
1
2
  import { assert, elementUpdated, expect, fixture, html, } from '@open-wc/testing';
2
3
  import GlideCoreRadio from './radio.js';
3
4
  import GlideCoreRadioGroup from './radio-group.js';
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-expressions */
1
2
  import { elementUpdated, expect, fixture, html } from '@open-wc/testing';
2
3
  import GlideCoreRadio from './radio.js';
3
4
  import GlideCoreRadioGroup from './radio-group.js';
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-expressions */
1
2
  import './split-button.js';
2
3
  import { assert, elementUpdated, expect, fixture, html, } from '@open-wc/testing';
3
4
  import GlideCoreSplitButton from './split-button.js';
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-expressions */
1
2
  import './split-button.js';
2
3
  import './split-container.js';
3
4
  import './split-link.js';
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-expressions */
1
2
  import './split-link.js';
2
3
  import { elementUpdated, expect, fixture, html } from '@open-wc/testing';
3
4
  import GlideCoreSplitLink from './split-link.js';
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-expressions */
1
2
  import './split-link.js';
2
3
  import { expect, fixture, html } from '@open-wc/testing';
3
4
  import { sendKeys } from '@web/test-runner-commands';
package/dist/tab.d.ts CHANGED
@@ -22,8 +22,6 @@ export default class GlideCoreTab extends LitElement {
22
22
  panel: string;
23
23
  /** Sets the active attribute on the tab. */
24
24
  active: boolean;
25
- /** Sets the variant attribute on the tab. */
26
- variant: string;
27
25
  /** Disables the tab. */
28
26
  disabled: boolean;
29
27
  protected firstUpdated(): void;
@@ -18,17 +18,15 @@ export default class GlideCoreTabGroup extends LitElement {
18
18
  #private;
19
19
  static shadowRootOptions: ShadowRootInit;
20
20
  static styles: import("lit").CSSResult[];
21
- /**
22
- * Sets the variant attribute on the tab group.
23
- * Automatically sets this variant on all <glide-core-tab> components inside the default slot
24
- * */
25
- variant: string;
26
21
  /**
27
22
  * The tab element that is currently active
28
23
  * */
29
24
  activeTab?: GlideCoreTab;
25
+ isShowOverflowStartButton: boolean;
26
+ isShowOverflowEndButton: boolean;
30
27
  panelElements: GlideCoreTabPanel[];
31
28
  tabElements: GlideCoreTab[];
29
+ disconnectedCallback(): void;
32
30
  firstUpdated(): void;
33
31
  render(): import("lit").TemplateResult<1>;
34
32
  updated(): void;
package/dist/tab.group.js CHANGED
@@ -1 +1 @@
1
- var __decorate=this&&this.__decorate||function(e,t,o,a){var s,i=arguments.length,r=i<3?t:null===a?a=Object.getOwnPropertyDescriptor(t,o):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(e,t,o,a);else for(var l=e.length-1;l>=0;l--)(s=e[l])&&(r=(i<3?s(r):i>3?s(t,o,r):s(t,o))||r);return i>3&&r&&Object.defineProperty(t,o,r),r};import"./icon-button.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{owSlotType}from"./library/ow.js";import GlideCoreTab from"./tab.js";import GlideCoreTabPanel from"./tab.panel.js";import styles from"./tab.group.styles.js";let GlideCoreTabGroup=class GlideCoreTabGroup extends LitElement{constructor(){super(...arguments),this.variant="primary",this.#e=createRef(),this.#t=createRef(),this.#o=e=>{const t=e.target.closest("glide-core-tab");t&&t instanceof GlideCoreTab&&!t.disabled&&this.#a(t)},this.#s=e=>{const t=e.target.closest("glide-core-tab");if(["Enter"," "].includes(e.key)&&t&&t instanceof GlideCoreTab&&!t.disabled&&(this.#a(t),e.preventDefault()),["ArrowLeft","ArrowRight","ArrowUp","ArrowDown","Home","End"].includes(e.key)){const t=this.tabElements.find((e=>e.matches(":focus")));if("glide-core-tab"===t?.tagName.toLowerCase()){let o=this.tabElements.indexOf(t);switch(e.key){case"Home":o=0;break;case"End":o=this.tabElements.length-1;break;case"vertical"===this.variant?"ArrowUp":"ArrowLeft":o--;break;case"vertical"===this.variant?"ArrowDown":"ArrowRight":o++}o<0&&(o=this.tabElements.length-1),o>this.tabElements.length-1&&(o=0),this.tabElements[o].focus({preventScroll:!0}),e.preventDefault()}}}}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}firstUpdated(){owSlotType(this.#t.value,[GlideCoreTab]),owSlotType(this.#e.value,[GlideCoreTabPanel]),this.#i(),this.#r()}render(){return html`<div class="${classMap({component:!0,vertical:"vertical"===this.variant})}" @click="${this.#o}" @keydown="${this.#s}"><div role="tablist" class="${classMap({"tab-group":!0,[this.variant]:!0})}"><slot name="nav" @slotchange="${this.#l}" ${ref(this.#t)}></slot></div><slot @slotchange="${this.#n}" ${ref(this.#e)}></slot></div>`}updated(){this.#i()}#e;#t;#o;#s;#n(){owSlotType(this.#e.value,[GlideCoreTabPanel])}#l(){owSlotType(this.#t.value,[GlideCoreTab])}#r(){for(const[e,t]of this.tabElements.entries()){let o;this.activeTab||0!==e?o=this.activeTab===t:(this.activeTab=t,o=!0),t.active=o}for(const e of this.panelElements){const t=this.activeTab?.getAttribute("panel"),o=e.getAttribute("name");e.isActive=o===t}}#i(){for(const e of this.tabElements){e.variant=this.variant;for(const t of this.panelElements)e.setAttribute("aria-controls",t.getAttribute("id")),t.setAttribute("aria-labelledby",e.getAttribute("id"))}}#a(e){this.activeTab=e,this.#r(),this.dispatchEvent(new CustomEvent("tab-show",{bubbles:!0,detail:{panel:e.panel}}))}};__decorate([property({reflect:!0})],GlideCoreTabGroup.prototype,"variant",void 0),__decorate([state()],GlideCoreTabGroup.prototype,"activeTab",void 0),__decorate([queryAssignedElements()],GlideCoreTabGroup.prototype,"panelElements",void 0),__decorate([queryAssignedElements({slot:"nav"})],GlideCoreTabGroup.prototype,"tabElements",void 0),GlideCoreTabGroup=__decorate([customElement("glide-core-tab-group")],GlideCoreTabGroup);export default GlideCoreTabGroup;
1
+ var __decorate=this&&this.__decorate||function(t,e,o,i){var s,l=arguments.length,n=l<3?e:null===i?i=Object.getOwnPropertyDescriptor(e,o):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(t,e,o,i);else for(var r=t.length-1;r>=0;r--)(s=t[r])&&(n=(l<3?s(n):l>3?s(e,o,n):s(e,o))||n);return l>3&&n&&Object.defineProperty(e,o,n),n};import"./icon-button.js";import{LitElement,html}from"lit";import{LocalizeController}from"./library/localize.js";import{createRef,ref}from"lit/directives/ref.js";import{customElement,queryAssignedElements,state}from"lit/decorators.js";import{when}from"lit/directives/when.js";import GlideCoreTab from"./tab.js";import GlideCoreTabPanel from"./tab.panel.js";import ow,{owSlotType}from"./library/ow.js";import styles from"./tab.group.styles.js";let GlideCoreTabGroup=class GlideCoreTabGroup extends LitElement{constructor(){super(...arguments),this.isShowOverflowStartButton=!1,this.isShowOverflowEndButton=!1,this.#t=100,this.#e=createRef(),this.#o=new LocalizeController(this),this.#i=createRef(),this.#s=createRef(),this.#l=createRef(),this.#n=null,this.#r=null,this.#a=null,this.#h=createRef(),this.#c=t=>{const e=t.target.closest("glide-core-tab");e&&e instanceof GlideCoreTab&&!e.disabled&&this.#u(e)},this.#f=()=>{this.#d("right",!0)},this.#b=()=>{this.#d("left",!0)},this.#v=t=>{const e=t.target.closest("glide-core-tab");if(["Enter"," "].includes(t.key)&&e&&e instanceof GlideCoreTab&&!e.disabled&&(this.#u(e),t.preventDefault()),["ArrowLeft","ArrowRight","ArrowUp","ArrowDown","Home","End"].includes(t.key)){const e=this.tabElements.find((t=>t.matches(":focus")));if("glide-core-tab"===e?.tagName.toLowerCase()){let o=this.tabElements.indexOf(e);switch(t.key){case"Home":o=0;break;case"End":o=this.tabElements.length-1;break;case"ArrowLeft":o--;break;case"ArrowRight":o++}if(o<0&&(o=this.tabElements.length-1),o>this.tabElements.length-1&&(o=0),this.tabElements[o].focus({preventScroll:!1}),this.#m(),this.isShowOverflowStartButton&&this.#l.value&&"ArrowLeft"===t.key){const t=Number.parseInt(window.getComputedStyle(document.documentElement).fontSize),e=this.#l.value?.getBoundingClientRect(),{right:i}=e,s=this.tabElements[o]?.getBoundingClientRect(),{right:l}=s;i>l-t&&this.#d("left")}if(this.isShowOverflowEndButton&&this.#s.value&&"ArrowRight"===t.key){const t=Number.parseInt(window.getComputedStyle(document.documentElement).fontSize),e=this.#s.value?.getBoundingClientRect(),{left:i}=e,s=this.tabElements[o]?.getBoundingClientRect(),{left:l}=s;i<l+t&&this.#d("right")}t.preventDefault()}}},this.#m=()=>{this.#w(),this.#E()}}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}disconnectedCallback(){this.#n?.disconnect(),this.#n=null}firstUpdated(){owSlotType(this.#i.value,[GlideCoreTab]),owSlotType(this.#e.value,[GlideCoreTabPanel]),this.#p(),this.#g(),this.#T()}render(){return html`<div class="component" @click="${this.#c}" @keydown="${this.#v}"><div class="tab-container"><div class="overflow-button-container" style="height: ${this.#h.value?.clientHeight}px">${when(this.isShowOverflowStartButton,(()=>html`<button style="height: ${this.#h.value?.clientHeight}px" class="overflow" @click="${this.#b}" tabindex="-1" aria-label="${this.#o.term("previousTab")}" data-test="overflow-start-button" ${ref(this.#l)}><svg aria-hidden="true" width="18" height="18" viewBox="0 0 24 24" fill="none"><path d="M15 6L9 12L15 18" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></button>`))}</div><div role="tablist" class="tab-group" ${ref(this.#h)} @scroll="${this.#R}"><slot name="nav" @slotchange="${this.#y}" ${ref(this.#i)}></slot></div><div class="overflow-button-container" style="height: ${this.#h.value?.clientHeight}px">${when(this.isShowOverflowEndButton,(()=>html`<button style="height: ${this.#h.value?.clientHeight}px" class="overflow" @click="${this.#f}" tabindex="-1" aria-label="${this.#o.term("nextTab")}" data-test="overflow-end-button" ${ref(this.#s)}><svg aria-hidden="true" width="18" height="18" 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></button>`))}</div></div><slot @slotchange="${this.#S}" ${ref(this.#e)}></slot></div>`}updated(){this.#p()}#t;#e;#o;#i;#s;#l;#n;#r;#a;#h;#c;#f;#b;#v;#m;#S(){owSlotType(this.#e.value,[GlideCoreTabPanel])}#y(){owSlotType(this.#i.value,[GlideCoreTab]),this.#m()}#R(){this.#a&&clearTimeout(this.#a),this.#a=setTimeout((()=>{this.#m()}),this.#t)}#d(t,e){const o="right"===t?1:-1;ow(this.#h.value,ow.object.instanceOf(HTMLElement));const i=o*this.#h.value?.clientWidth*.5;this.#h.value?.scrollBy({left:i,top:0,behavior:e?"smooth":"auto"})}#g(){for(const[t,e]of this.tabElements.entries()){let o;this.activeTab||0!==t?o=this.activeTab===e:(this.activeTab=e,o=!0),e.active=o}for(const t of this.panelElements){const e=this.activeTab?.getAttribute("panel"),o=t.getAttribute("name");t.isActive=o===e}}#E(){const t=this.#h.value,e=t?.getBoundingClientRect();ow(t,ow.object.instanceOf(HTMLElement));if(e){const{width:o}=e,i=t.scrollLeft+o,s=t.scrollWidth;this.isShowOverflowEndButton=s-i>1}}#w(){ow(this.#h.value,ow.object.instanceOf(HTMLElement)),this.isShowOverflowStartButton=this.#h.value.scrollLeft>0}#T(){this.#n=new ResizeObserver((t=>{t?.at(0)?.target===this.#h.value&&(this.#r&&clearTimeout(this.#r),this.#r=setTimeout((()=>{this.#m()}),this.#t))})),ow(this.#h.value,ow.object.instanceOf(HTMLElement)),this.#n.observe(this.#h.value)}#p(){for(const t of this.tabElements)for(const e of this.panelElements)t.setAttribute("aria-controls",e.getAttribute("id")),e.setAttribute("aria-labelledby",t.getAttribute("id"))}#u(t){this.activeTab=t,this.#g(),this.dispatchEvent(new CustomEvent("tab-show",{bubbles:!0,detail:{panel:t.panel}}))}};__decorate([state()],GlideCoreTabGroup.prototype,"activeTab",void 0),__decorate([state()],GlideCoreTabGroup.prototype,"isShowOverflowStartButton",void 0),__decorate([state()],GlideCoreTabGroup.prototype,"isShowOverflowEndButton",void 0),__decorate([queryAssignedElements()],GlideCoreTabGroup.prototype,"panelElements",void 0),__decorate([queryAssignedElements({slot:"nav"})],GlideCoreTabGroup.prototype,"tabElements",void 0),GlideCoreTabGroup=__decorate([customElement("glide-core-tab-group")],GlideCoreTabGroup);export default GlideCoreTabGroup;
@@ -1,27 +1,41 @@
1
1
  import{css}from"lit";export default[css`
2
2
  .component {
3
+ background-color: transparent;
3
4
  display: flex;
4
5
  flex-direction: column;
5
6
 
6
- &.vertical {
7
- flex-direction: row;
7
+ & .tab-container {
8
+ border-block-end: 1px solid var(--glide-core-border-base-lighter);
9
+ display: flex;
10
+
11
+ & .overflow-button-container {
12
+ flex-shrink: 0;
13
+ inline-size: 1.875rem;
14
+ }
8
15
  }
9
- }
10
16
 
11
- .tab-group {
12
- display: flex;
17
+ & .tab-group {
18
+ display: flex;
19
+ overflow: auto hidden;
20
+ scrollbar-width: none;
21
+ white-space: nowrap;
13
22
 
14
- &.primary {
15
- border-block-end: 1px solid var(--glide-core-border-primary);
16
- }
23
+ /* "-webkit-scrollbar" is needed for Safari */
17
24
 
18
- &.secondary {
19
- border-block-end: 1px solid var(--glide-core-border-base-lighter);
25
+ &::-webkit-scrollbar {
26
+ block-size: 0;
27
+ inline-size: 0;
28
+ }
20
29
  }
21
30
 
22
- &.vertical {
23
- border: 1px solid var(--glide-core-border-base-darker);
24
- flex-direction: column;
31
+ & .overflow {
32
+ background-color: transparent;
33
+ border: none;
34
+ cursor: pointer;
35
+ inline-size: 1.875rem;
36
+ margin: 0;
37
+ outline: none;
38
+ padding: 0;
25
39
  }
26
40
  }
27
41
  `];
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-expressions */
1
2
  import './tab.group.js';
2
3
  import './tab.js';
3
4
  import './tab.panel.js';
@@ -8,6 +9,9 @@ import GlideCoreTabPanel from './tab.panel.js';
8
9
  import expectArgumentError from './library/expect-argument-error.js';
9
10
  GlideCoreTabGroup.shadowRootOptions.mode = 'open';
10
11
  GlideCoreTabPanel.shadowRootOptions.mode = 'open';
12
+ function isPanelHidden(panel) {
13
+ return panel.shadowRoot?.firstElementChild?.classList.contains('hidden');
14
+ }
11
15
  it('registers', async () => {
12
16
  expect(window.customElements.get('glide-core-tab-group')).to.equal(GlideCoreTabGroup);
13
17
  expect(window.customElements.get('glide-core-tab-panel')).to.equal(GlideCoreTabPanel);
@@ -22,39 +26,16 @@ it('renders correct markup and sets correct attributes for the default case', as
22
26
  await expect(tabGroup).to.be.accessible();
23
27
  const [firstTab] = tabGroup.tabElements;
24
28
  expect(tabGroup.activeTab).to.equal(firstTab, 'activeTab defaults to first tab');
25
- expect(tabGroup.variant).to.equal('primary');
26
29
  expect([...tabGroup.shadowRoot.firstElementChild.classList]).to.deep.equal([
27
30
  'component',
28
31
  ]);
29
32
  expect([
30
33
  ...tabGroup.shadowRoot.querySelector('.tab-group').classList,
31
- ]).to.deep.equal(['tab-group', 'primary']);
34
+ ]).to.deep.equal(['tab-group']);
32
35
  const slot = tabGroup.shadowRoot.querySelector('slot:not([name="nav"])');
33
36
  expect(slot).to.exist;
34
37
  expect(slot.assignedElements.length).to.equal(0);
35
38
  });
36
- it('renders a secondary variant', async () => {
37
- const element = await fixture(html `
38
- <glide-core-tab-group variant="secondary">
39
- <glide-core-tab slot="nav" panel="1">Tab 1</glide-core-tab>
40
- <glide-core-tab-panel name="1">Content for Tab 1</glide-core-tab-panel>
41
- </glide-core-tab-group>
42
- `);
43
- expect([
44
- ...element.shadowRoot.querySelector('.tab-group').classList,
45
- ]).to.deep.equal(['tab-group', 'secondary']);
46
- });
47
- it('renders a vertical variant', async () => {
48
- const element = await fixture(html `
49
- <glide-core-tab-group variant="vertical">
50
- <glide-core-tab slot="nav" panel="1">Tab 1</glide-core-tab>
51
- <glide-core-tab-panel name="1">Content for Tab 1</glide-core-tab-panel>
52
- </glide-core-tab-group>
53
- `);
54
- expect([
55
- ...element.shadowRoot.querySelector('.tab-group').classList,
56
- ]).to.deep.equal(['tab-group', 'vertical']);
57
- });
58
39
  it('can switch tabs', async () => {
59
40
  const tabGroup = await fixture(html `
60
41
  <glide-core-tab-group>
@@ -133,37 +114,10 @@ it('can use left/right, home and end keys to focus on tabs', async () => {
133
114
  await sendKeys({ press: 'Enter' });
134
115
  expect(thirdTab.active).to.equal(true);
135
116
  });
136
- it('can use up/down keys to focus on vertical tabs', async () => {
137
- const tabGroup = await fixture(html `
138
- <glide-core-tab-group variant="vertical">
139
- <glide-core-tab slot="nav" panel="1">Tab 1</glide-core-tab>
140
- <glide-core-tab slot="nav" panel="2">Tab 2</glide-core-tab>
141
- <glide-core-tab slot="nav" panel="3">Tab 3</glide-core-tab>
142
-
143
- <glide-core-tab-panel name="1">Content for Tab 1</glide-core-tab-panel>
144
- <glide-core-tab-panel name="2">Content for Tab 2</glide-core-tab-panel>
145
- <glide-core-tab-panel name="3">Content for Tab 3</glide-core-tab-panel>
146
- </glide-core-tab-group>
147
- `);
148
- const [firstTab, secondTab, thirdTab] = tabGroup.tabElements;
149
- firstTab.focus();
150
- await sendKeys({ press: 'ArrowDown' });
151
- await sendKeys({ press: 'Enter' });
152
- expect(secondTab.active).to.equal(true, 'down works');
153
- await sendKeys({ press: 'ArrowUp' });
154
- await sendKeys({ press: 'Enter' });
155
- expect(firstTab.active).to.equal(true, 'up works');
156
- await sendKeys({ press: 'ArrowUp' });
157
- await sendKeys({ press: 'Enter' });
158
- expect(thirdTab.active).to.equal(true, 'up from first goes to last');
159
- await sendKeys({ press: 'ArrowDown' });
160
- await sendKeys({ press: 'Enter' });
161
- expect(firstTab.active).to.equal(true, 'down from last goes to first');
162
- });
163
117
  it('throws an error when an element other than `glide-core-tab` is a child of the `nav` slot', async () => {
164
118
  await expectArgumentError(() => {
165
119
  return fixture(html `
166
- <glide-core-tab-group variant="vertical">
120
+ <glide-core-tab-group>
167
121
  <div slot="nav">Tab 1</div>
168
122
  <glide-core-tab-panel name="1">Content for Tab 1</glide-core-tab-panel>
169
123
  </glide-core-tab-group>
@@ -173,13 +127,10 @@ it('throws an error when an element other than `glide-core-tab` is a child of th
173
127
  it('throws an error when an element other than `glide-core-tab-panel` is a child of the default slot', async () => {
174
128
  await expectArgumentError(() => {
175
129
  return fixture(html `
176
- <glide-core-tab-group variant="vertical">
130
+ <glide-core-tab-group>
177
131
  <glide-core-tab slot="nav" panel="1">Tab 1</glide-core-tab>
178
132
  <div>Default Content</div>
179
133
  </glide-core-tab-group>
180
134
  `);
181
135
  });
182
136
  });
183
- function isPanelHidden(panel) {
184
- return panel.shadowRoot?.firstElementChild?.classList.contains('hidden');
185
- }
@@ -0,0 +1,3 @@
1
+ import './tab.group.js';
2
+ import './tab.js';
3
+ import './tab.panel.js';