@crowdstrike/glide-core 0.9.1 → 0.9.3

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 (130) hide show
  1. package/dist/accordion.stories.d.ts +2 -4
  2. package/dist/accordion.styles.js +2 -4
  3. package/dist/button-group.button.styles.js +3 -8
  4. package/dist/button-group.stories.d.ts +2 -6
  5. package/dist/button-group.styles.js +2 -2
  6. package/dist/button.d.ts +12 -1
  7. package/dist/button.js +1 -1
  8. package/dist/button.stories.d.ts +2 -12
  9. package/dist/button.styles.js +2 -4
  10. package/dist/button.test.basics.js +47 -165
  11. package/dist/button.test.events.js +86 -10
  12. package/dist/checkbox-group.stories.d.ts +2 -3
  13. package/dist/checkbox.js +1 -1
  14. package/dist/checkbox.stories.d.ts +2 -6
  15. package/dist/checkbox.styles.js +43 -6
  16. package/dist/checkbox.test.form.js +16 -0
  17. package/dist/checkbox.test.interactions.js +8 -0
  18. package/dist/drawer.js +1 -1
  19. package/dist/drawer.stories.d.ts +1 -1
  20. package/dist/dropdown.d.ts +4 -2
  21. package/dist/dropdown.js +1 -1
  22. package/dist/dropdown.option.js +1 -1
  23. package/dist/dropdown.option.styles.js +2 -0
  24. package/dist/dropdown.stories.d.ts +4 -10
  25. package/dist/dropdown.styles.js +47 -29
  26. package/dist/dropdown.test.focus.filterable.js +20 -0
  27. package/dist/dropdown.test.focus.js +1 -0
  28. package/dist/dropdown.test.form.js +23 -112
  29. package/dist/dropdown.test.interactions.filterable.js +121 -17
  30. package/dist/dropdown.test.interactions.multiple.js +15 -22
  31. package/dist/dropdown.test.interactions.single.js +44 -22
  32. package/dist/form-controls-layout.stories.d.ts +1 -1
  33. package/dist/icon-button.d.ts +1 -1
  34. package/dist/icon-button.stories.d.ts +1 -3
  35. package/dist/icon-button.styles.js +2 -4
  36. package/dist/icons/checked.d.ts +5 -0
  37. package/dist/icons/checked.js +1 -1
  38. package/dist/input.d.ts +1 -1
  39. package/dist/input.js +1 -1
  40. package/dist/input.stories.d.ts +2 -13
  41. package/dist/input.styles.d.ts +1 -1
  42. package/dist/input.styles.js +93 -93
  43. package/dist/input.test.basics.js +45 -45
  44. package/dist/input.test.form.js +17 -0
  45. package/dist/label.styles.js +6 -11
  46. package/dist/library/localize.test.js +45 -0
  47. package/dist/menu.button.styles.js +1 -0
  48. package/dist/menu.js +1 -1
  49. package/dist/menu.link.styles.js +1 -0
  50. package/dist/menu.stories.d.ts +1 -1
  51. package/dist/menu.styles.js +3 -1
  52. package/dist/menu.test.events.js +1 -97
  53. package/dist/menu.test.focus.js +26 -3
  54. package/dist/menu.test.interactions.js +3 -0
  55. package/dist/modal.d.ts +0 -7
  56. package/dist/modal.icon-button.test.basics.js +9 -9
  57. package/dist/modal.stories.d.ts +3 -5
  58. package/dist/modal.styles.js +2 -4
  59. package/dist/modal.tertiary-icon.test.basics.js +14 -14
  60. package/dist/modal.test.accessibility.js +16 -27
  61. package/dist/modal.test.basics.js +64 -68
  62. package/dist/modal.test.close.js +12 -16
  63. package/dist/modal.test.events.js +32 -44
  64. package/dist/modal.test.lock-scroll.js +15 -25
  65. package/dist/modal.test.methods.js +8 -12
  66. package/dist/modal.test.scrollbars.js +2 -4
  67. package/dist/radio-group.js +1 -1
  68. package/dist/radio-group.stories.d.ts +2 -3
  69. package/dist/radio-group.test.basics.js +3 -3
  70. package/dist/radio-group.test.events.js +6 -6
  71. package/dist/radio-group.test.form.js +19 -0
  72. package/dist/radio.styles.js +2 -6
  73. package/dist/split-button.stories.d.ts +3 -8
  74. package/dist/split-button.styles.js +2 -4
  75. package/dist/split-container.styles.js +2 -4
  76. package/dist/status-indicator.stories.d.ts +1 -13
  77. package/dist/styles/focus-outline.d.ts +1 -1
  78. package/dist/styles/focus-outline.js +7 -1
  79. package/dist/styles/opacity-and-scale-animation.d.ts +2 -0
  80. package/dist/styles/opacity-and-scale-animation.js +24 -0
  81. package/dist/styles/variables.css +1 -1
  82. package/dist/styles/visually-hidden.d.ts +1 -1
  83. package/dist/styles/visually-hidden.js +14 -1
  84. package/dist/tab.group.d.ts +6 -6
  85. package/dist/tab.group.js +1 -1
  86. package/dist/tab.group.styles.js +46 -5
  87. package/dist/tab.group.test.basics.js +9 -2
  88. package/dist/tab.group.test.interactions.js +70 -93
  89. package/dist/tab.js +1 -1
  90. package/dist/tab.panel.styles.js +3 -9
  91. package/dist/tab.styles.js +6 -13
  92. package/dist/tab.test.basics.js +15 -17
  93. package/dist/tabs.stories.d.ts +2 -2
  94. package/dist/tag.js +1 -1
  95. package/dist/tag.stories.d.ts +2 -4
  96. package/dist/tag.styles.js +2 -4
  97. package/dist/tag.test.basics.js +28 -27
  98. package/dist/tag.test.events.js +3 -3
  99. package/dist/tag.test.focus.js +4 -4
  100. package/dist/textarea.d.ts +1 -1
  101. package/dist/textarea.stories.d.ts +1 -8
  102. package/dist/textarea.styles.d.ts +1 -1
  103. package/dist/textarea.styles.js +63 -67
  104. package/dist/textarea.test.basics.js +52 -52
  105. package/dist/toasts.d.ts +5 -0
  106. package/dist/toasts.stories.d.ts +1 -1
  107. package/dist/toasts.styles.js +1 -1
  108. package/dist/toggle.stories.d.ts +1 -4
  109. package/dist/toggle.styles.js +2 -1
  110. package/dist/toggle.test.interactions.js +11 -0
  111. package/dist/tooltip.js +1 -1
  112. package/dist/tooltip.styles.js +16 -30
  113. package/dist/tooltip.test.interactions.js +6 -6
  114. package/dist/translations/en.js +1 -1
  115. package/dist/translations/fr.d.ts +3 -1
  116. package/dist/translations/fr.js +1 -1
  117. package/dist/translations/ja.d.ts +3 -1
  118. package/dist/translations/ja.js +1 -1
  119. package/dist/tree.item.styles.js +11 -3
  120. package/dist/tree.item.test.basics.js +0 -30
  121. package/dist/tree.stories.d.ts +0 -9
  122. package/package.json +1 -3
  123. package/dist/button.test.form.d.ts +0 -1
  124. package/dist/button.test.form.js +0 -50
  125. package/dist/input.test.translations.js +0 -38
  126. package/dist/tag.test.translations.d.ts +0 -1
  127. package/dist/tag.test.translations.js +0 -25
  128. package/dist/textarea.test.translations.d.ts +0 -1
  129. package/dist/textarea.test.translations.js +0 -34
  130. /package/dist/{input.test.translations.d.ts → library/localize.test.d.ts} +0 -0
@@ -178,7 +178,7 @@ it('does not move focus if there is only one button when pressing arrow keys', a
178
178
  expect(radio).to.have.focus;
179
179
  });
180
180
  it('changes the "checked" attribute when clicking', async () => {
181
- const element = await fixture(html `<glide-core-radio-group name="name">
181
+ const component = await fixture(html `<glide-core-radio-group name="name">
182
182
  <glide-core-radio value="value-1" checked label="One"></glide-core-radio>
183
183
  <glide-core-radio value="value-2" label="Two"></glide-core-radio>
184
184
  <glide-core-radio value="value-3" label="Three"></glide-core-radio>
@@ -186,33 +186,33 @@ it('changes the "checked" attribute when clicking', async () => {
186
186
  const radios = document.querySelectorAll('glide-core-radio');
187
187
  expect(radios.length).to.equal(3);
188
188
  radios[2].click();
189
- await elementUpdated(element);
189
+ await elementUpdated(component);
190
190
  expect(radios[2]).to.have.focus;
191
191
  expect(radios[2]).to.have.attribute('checked');
192
192
  expect(radios[0]).to.not.have.attribute('checked');
193
193
  });
194
194
  it('does not change focus nor the "checked" attribute when clicking a disabled radio', async () => {
195
- const element = await fixture(html `<glide-core-radio-group name="name">
195
+ const component = await fixture(html `<glide-core-radio-group name="name">
196
196
  <glide-core-radio value="value-1" checked label="One"></glide-core-radio>
197
197
  <glide-core-radio value="value-2" disabled label="Two"></glide-core-radio>
198
198
  </glide-core-radio-group>`);
199
199
  const radios = document.querySelectorAll('glide-core-radio');
200
200
  expect(radios.length).to.equal(2);
201
201
  radios[1].click();
202
- await elementUpdated(element);
202
+ await elementUpdated(component);
203
203
  expect(radios[0]).to.have.focus;
204
204
  expect(radios[0]).to.have.attribute('checked');
205
205
  expect(radios[1]).to.not.have.attribute('checked');
206
206
  });
207
207
  it('does not change focus nor the "checked" attribute when clicking a disabled group', async () => {
208
- const element = await fixture(html `<glide-core-radio-group name="name" disabled>
208
+ const component = await fixture(html `<glide-core-radio-group name="name" disabled>
209
209
  <glide-core-radio value="value-1" checked label="One"></glide-core-radio>
210
210
  <glide-core-radio value="value-2" label="Two"></glide-core-radio>
211
211
  </glide-core-radio-group>`);
212
212
  const radios = document.querySelectorAll('glide-core-radio');
213
213
  expect(radios.length).to.equal(2);
214
214
  radios[1].click();
215
- await elementUpdated(element);
215
+ await elementUpdated(component);
216
216
  expect(radios[0]).to.not.have.focus;
217
217
  expect(radios[0]).to.have.attribute('checked');
218
218
  expect(radios[1]).to.not.have.attribute('checked');
@@ -1,7 +1,9 @@
1
1
  /* eslint-disable @typescript-eslint/no-unused-expressions */
2
2
  import { assert, elementUpdated, expect, fixture, html, } from '@open-wc/testing';
3
+ import { sendKeys } from '@web/test-runner-commands';
3
4
  import GlideCoreRadio from './radio.js';
4
5
  import GlideCoreRadioGroup from './radio-group.js';
6
+ import sinon from 'sinon';
5
7
  GlideCoreRadio.shadowRootOptions.mode = 'open';
6
8
  GlideCoreRadioGroup.shadowRootOptions.mode = 'open';
7
9
  it('exposes standard form control properties and methods', async () => {
@@ -103,3 +105,20 @@ it('has no `formData` value when a radio is checked but without a "value"', asyn
103
105
  const formData = new FormData(form);
104
106
  expect(formData.get('name')).to.be.null;
105
107
  });
108
+ it('submits its form on Enter', async () => {
109
+ const form = document.createElement('form');
110
+ const component = await fixture(html `<glide-core-radio-group label="label">
111
+ <glide-core-radio value="value-1" label="One"></glide-core-radio>
112
+ <glide-core-radio value="value-2" label="Two"></glide-core-radio>
113
+ </glide-core-radio-group>`, {
114
+ parentNode: form,
115
+ });
116
+ const spy = sinon.spy();
117
+ form.addEventListener('submit', (event) => {
118
+ event.preventDefault();
119
+ spy();
120
+ });
121
+ component.focus();
122
+ await sendKeys({ press: 'Enter' });
123
+ expect(spy.callCount).to.equal(1);
124
+ });
@@ -1,4 +1,6 @@
1
1
  import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export default[css`
2
+ ${focusOutline(":host(:focus-visible) .component .radio-circle")}
3
+ `,css`
2
4
  @keyframes animate-radio {
3
5
  from {
4
6
  opacity: 0;
@@ -26,12 +28,6 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export
26
28
  outline: none;
27
29
  }
28
30
 
29
- /* Using nesting creates an issue on Safari with :host */
30
- /* stylelint-disable-next-line csstools/use-nesting */
31
- :host(:focus-visible) .component .radio-circle {
32
- ${focusOutline};
33
- }
34
-
35
31
  .component {
36
32
  align-items: center;
37
33
  color: var(--glide-core-text-body-1);
@@ -7,11 +7,6 @@ import './split-link.js';
7
7
  import type { Meta, StoryObj } from '@storybook/web-components';
8
8
  declare const meta: Meta;
9
9
  export default meta;
10
- export declare const Primary: StoryObj;
11
- export declare const PrimaryWithPrefixIcon: StoryObj;
12
- export declare const PrimaryWithSizeSmall: StoryObj;
13
- export declare const PrimaryWithLink: StoryObj;
14
- export declare const Secondary: StoryObj;
15
- export declare const SecondaryWithPrefixIcon: StoryObj;
16
- export declare const SecondaryWithSizeSmall: StoryObj;
17
- export declare const SecondaryWithLink: StoryObj;
10
+ export declare const SplitButton: StoryObj;
11
+ export declare const WithIcon: StoryObj;
12
+ export declare const WithSplitLink: StoryObj;
@@ -1,4 +1,6 @@
1
1
  import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export default[css`
2
+ ${focusOutline(".component:focus-visible")}
3
+ `,css`
2
4
  .component {
3
5
  align-items: center;
4
6
  border-color: transparent;
@@ -25,10 +27,6 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export
25
27
  outline: none;
26
28
  }
27
29
 
28
- &:focus-visible {
29
- ${focusOutline};
30
- }
31
-
32
30
  &.disabled {
33
31
  opacity: 1;
34
32
  pointer-events: none;
@@ -1,4 +1,6 @@
1
1
  import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export default[css`
2
+ ${focusOutline(".menu-button:focus-visible")}
3
+ `,css`
2
4
  .component {
3
5
  display: inline-flex;
4
6
  position: relative;
@@ -55,10 +57,6 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export
55
57
  outline: none;
56
58
  }
57
59
 
58
- &:focus-visible {
59
- ${focusOutline};
60
- }
61
-
62
60
  &:disabled {
63
61
  cursor: default;
64
62
  opacity: 1;
@@ -2,16 +2,4 @@ import './status-indicator.js';
2
2
  import type { Meta, StoryObj } from '@storybook/web-components';
3
3
  declare const meta: Meta;
4
4
  export default meta;
5
- export declare const Failed: StoryObj;
6
- export declare const Idle: StoryObj;
7
- export declare const InProgress: StoryObj;
8
- export declare const Queued: StoryObj;
9
- export declare const Scheduled: StoryObj;
10
- export declare const Success: StoryObj;
11
- export declare const WarningCritical: StoryObj;
12
- export declare const WarningHigh: StoryObj;
13
- export declare const WarningInformational: StoryObj;
14
- export declare const WarningLow: StoryObj;
15
- export declare const WarningMedium: StoryObj;
16
- export declare const WarningZero: StoryObj;
17
- export declare const CustomSize: StoryObj;
5
+ export declare const StatusIndicator: StoryObj;
@@ -1,2 +1,2 @@
1
- declare const _default: import("lit").CSSResult;
1
+ declare const _default: (selector: string) => import("lit").CSSResult;
2
2
  export default _default;
@@ -1 +1,7 @@
1
- import{unsafeCSS}from"lit";export default unsafeCSS("\n outline: 2px solid var(--glide-core-border-focus);\n outline-offset: 1px;\n");
1
+ import{css,unsafeCSS}from"lit";export default e=>css`
2
+ /* stylelint-disable selector-type-case, selector-type-no-unknown */
3
+ ${unsafeCSS(e)} {
4
+ outline: 2px solid var(--glide-core-border-focus) !important;
5
+ outline-offset: 1px;
6
+ }
7
+ `;
@@ -0,0 +1,2 @@
1
+ declare const _default: (selector: string) => import("lit").CSSResult;
2
+ export default _default;
@@ -0,0 +1,24 @@
1
+ import{css,unsafeCSS}from"lit";export default e=>css`
2
+ /* stylelint-disable selector-type-case, selector-type-no-unknown */
3
+ @keyframes opacity-and-scale {
4
+ from {
5
+ opacity: 0;
6
+ transform: scale(0.95);
7
+ }
8
+
9
+ to {
10
+ opacity: 1;
11
+ transform: scale(1);
12
+ }
13
+ }
14
+
15
+ ${unsafeCSS(e)} {
16
+ animation: opacity-and-scale 250ms cubic-bezier(0.25, 0, 0.3, 1);
17
+ }
18
+
19
+ @media (prefers-reduced-motion: reduce) {
20
+ ${unsafeCSS(e)} {
21
+ animation: none !important;
22
+ }
23
+ }
24
+ `;
@@ -1 +1 @@
1
- :root,:host{color-scheme:normal;--glide-core-border-radius-lg: .75rem;--glide-core-border-radius-md: .5rem;--glide-core-border-radius-none: 0rem;--glide-core-border-radius-round: 7.5rem;--glide-core-border-radius-sm: .25rem;--glide-core-border-radius-xs: .125rem;--glide-core-border-width-lg: .25rem;--glide-core-border-width-md: .125rem;--glide-core-border-width-none: 0rem;--glide-core-border-width-sm: .0625rem;--glide-core-spacing-lg: 1.5rem;--glide-core-spacing-md: 1rem;--glide-core-spacing-sm: .75rem;--glide-core-spacing-xl: 2rem;--glide-core-spacing-xs: .5rem;--glide-core-spacing-xxl: 3rem;--glide-core-spacing-xxs: .25rem;--glide-core-spacing-xxxl: 4rem;--glide-core-spacing-xxxs: .125rem;--glide-core-spacing-zero: 0rem}:root,:host,.theme-light{color-scheme:light;--glide-core-border-action: #0073e6;--glide-core-border-action-disabled: #d7e7ff;--glide-core-border-action-hover: #eef5ff;--glide-core-border-base: #c9c9c9;--glide-core-border-base-dark: #6d6d6d;--glide-core-border-base-darker: #424242;--glide-core-border-base-light: #e3e3e3;--glide-core-border-base-lighter: #f0f0f0;--glide-core-border-base-lightest: #ffffff;--glide-core-border-disabled: #8a8a8a;--glide-core-border-focus: #0073e6;--glide-core-border-focus-light: #eef5ff;--glide-core-border-primary: #054fb9;--glide-core-border-primary-hover: #0461cf;--glide-core-icon-active: #0073e6;--glide-core-icon-default: #212121;--glide-core-icon-default2: #212121;--glide-core-icon-display: #212121;--glide-core-icon-display-light: #6d6d6d;--glide-core-icon-hover: #8babf1;--glide-core-icon-primary: #054fb9;--glide-core-icon-primary-hover: #0461cf;--glide-core-icon-secondary-disabled: #d7e7ff;--glide-core-icon-selected: #ffffff;--glide-core-icon-selected-disabled: #eef5ff;--glide-core-icon-selected2: #ffffff;--glide-core-icon-tertiary-disabled: #8a8a8a;--glide-core-status-error: #db2d24;--glide-core-status-expired: #ff3b30;--glide-core-status-failed: #ff3b30;--glide-core-status-in-progress: #ffcc00;--glide-core-status-queued: #5ac8fa;--glide-core-status-scheduled: #af52de;--glide-core-status-success: #34c759;--glide-core-status-unknown: #6d6d6d;--glide-core-status-warning-critical: #ff3b30;--glide-core-status-warning-high: #ff9500;--glide-core-status-warning-informational: #0073e6;--glide-core-status-warning-low: #607d8b;--glide-core-status-warning-medium: #ffcc00;--glide-core-surface-active: #ffffff;--glide-core-surface-attention: #fffbeb;--glide-core-surface-base: #f0f0f0;--glide-core-surface-base-dark: #212121;--glide-core-surface-base-gray: #0000001a;--glide-core-surface-base-gray-dark: #00000066;--glide-core-surface-base-gray-light: #00000012;--glide-core-surface-base-light: #ffffff8c;--glide-core-surface-base-lighter: #ffffffbf;--glide-core-surface-base-lightest: #ffffffcc;--glide-core-surface-base-xlightest: #ffffffe5;--glide-core-surface-disabled: #f0f0f0;--glide-core-surface-dot-step: #8babf1;--glide-core-surface-error: #fff0ef;--glide-core-surface-focus: #0073e6;--glide-core-surface-hover: #d7e7ff;--glide-core-surface-informational: #eef5ff;--glide-core-surface-modal: #ffffff;--glide-core-surface-page: #ffffff;--glide-core-surface-primary: #0073e6;--glide-core-surface-primary-disabled: #1d7afc26;--glide-core-surface-secondary: #eef5ff;--glide-core-surface-secondary-disabled: #eef5ff;--glide-core-surface-selected: #0073e6;--glide-core-surface-selected-disabled: #8a8a8a;--glide-core-surface-selected-hover: #054fb9;--glide-core-surface-success: #f1fdf4;--glide-core-surface-unselected-disabled: #e3e3e3;--glide-core-surface-warning: #fff6e9;--glide-core-surface-white-1percent: #ffffff03;--glide-core-text-body-1: #212121;--glide-core-text-body-2: #212121;--glide-core-text-body-light: #424242;--glide-core-text-body-lighter: #c9c9c9;--glide-core-text-disabled: #f0f0f0;--glide-core-text-header-1: #424242;--glide-core-text-header-2: #6d6d6d;--glide-core-text-link: #0461cf;--glide-core-text-link-dark-surface: #8babf1;--glide-core-text-link-table: #0461cf;--glide-core-text-placeholder: #6d6d6d;--glide-core-text-primary: #054fb9;--glide-core-text-primary-hover: #0461cf;--glide-core-text-secondary: #0073e6;--glide-core-text-secondary-disabled: #d7e7ff;--glide-core-text-selected: #ffffff;--glide-core-text-selected-2: #ffffff;--glide-core-text-syntax-blue: #0000ff;--glide-core-text-syntax-dark: #151515;--glide-core-text-syntax-green: #116644;--glide-core-text-syntax-purple: #770088;--glide-core-text-syntax-red-dark: #95150e;--glide-core-text-syntax-red-light: #ee4400;--glide-core-text-tertiary: #212121;--glide-core-text-tertiary-disabled: #8a8a8a}:host,.theme-dark{color-scheme:dark;--glide-core-border-action: #0073e6;--glide-core-border-action-disabled: #eef5ff;--glide-core-border-action-hover: #eef5ff;--glide-core-border-base: #6d6d6d;--glide-core-border-base-dark: #c9c9c9;--glide-core-border-base-darker: #e3e3e3;--glide-core-border-base-light: #212121;--glide-core-border-base-lighter: #212121;--glide-core-border-base-lightest: #424242;--glide-core-border-disabled: #8a8a8a;--glide-core-border-focus: #0073e6;--glide-core-border-focus-light: #eef5ff;--glide-core-border-primary: #ffffff;--glide-core-border-primary-hover: #0461cf;--glide-core-icon-active: #0073e6;--glide-core-icon-default: #ffffff;--glide-core-icon-default2: #212121;--glide-core-icon-display: #ffffff;--glide-core-icon-display-light: #d7e7ff;--glide-core-icon-hover: #eef5ff;--glide-core-icon-primary: #ffffff;--glide-core-icon-primary-hover: #d7e7ff;--glide-core-icon-secondary-disabled: #d7e7ff;--glide-core-icon-selected: #ffffff;--glide-core-icon-selected-disabled: #eef5ff;--glide-core-icon-selected2: #424242;--glide-core-icon-tertiary-disabled: #6d6d6d;--glide-core-status-error: #ff3b30;--glide-core-status-expired: #ff3b30;--glide-core-status-failed: #ff3b30;--glide-core-status-in-progress: #ffcc00;--glide-core-status-queued: #5ac8fa;--glide-core-status-scheduled: #af52de;--glide-core-status-success: #34c759;--glide-core-status-unknown: #6d6d6d;--glide-core-status-warning-critical: #ff3b30;--glide-core-status-warning-high: #ff9500;--glide-core-status-warning-informational: #0073e6;--glide-core-status-warning-low: #607d8b;--glide-core-status-warning-medium: #ffcc00;--glide-core-surface-active: #ffffff;--glide-core-surface-attention: #fffbeb;--glide-core-surface-base: #424242;--glide-core-surface-base-dark: #212121;--glide-core-surface-base-gray: #ffffff8c;--glide-core-surface-base-gray-dark: #ffffff8c;--glide-core-surface-base-gray-light: #00000066;--glide-core-surface-base-light: #0000008c;--glide-core-surface-base-lighter: #000000bf;--glide-core-surface-base-lightest: #000000cc;--glide-core-surface-base-xlightest: #000000e5;--glide-core-surface-disabled: #424242;--glide-core-surface-dot-step: #8babf1;--glide-core-surface-error: #fff0ef;--glide-core-surface-focus: #0073e6;--glide-core-surface-hover: #0461cf;--glide-core-surface-informational: #eef5ff;--glide-core-surface-modal: #151515;--glide-core-surface-page: #212121;--glide-core-surface-primary: #0073e6;--glide-core-surface-primary-disabled: #6d6d6d;--glide-core-surface-secondary: #f0f0f0;--glide-core-surface-secondary-disabled: #f0f0f0;--glide-core-surface-selected: #0073e6;--glide-core-surface-selected-disabled: #8a8a8a;--glide-core-surface-selected-hover: #054fb9;--glide-core-surface-success: #f1fdf4;--glide-core-surface-unselected-disabled: #e3e3e3;--glide-core-surface-warning: #fff6e9;--glide-core-surface-white-1percent: #ffffff;--glide-core-text-body-1: #ffffff;--glide-core-text-body-2: #212121;--glide-core-text-body-light: #ffffff;--glide-core-text-body-lighter: #c9c9c9;--glide-core-text-disabled: #f0f0f0;--glide-core-text-header-1: #ffffff;--glide-core-text-header-2: #d7e7ff;--glide-core-text-link: #8babf1;--glide-core-text-link-dark-surface: #8babf1;--glide-core-text-link-table: #d0e8f2;--glide-core-text-placeholder: #d7e7ff;--glide-core-text-primary: #ffffff;--glide-core-text-primary-hover: #d7e7ff;--glide-core-text-secondary: #8babf1;--glide-core-text-secondary-disabled: #d7e7ff;--glide-core-text-selected: #ffffff;--glide-core-text-selected-2: #424242;--glide-core-text-syntax-blue: #0000ff;--glide-core-text-syntax-dark: #ffffff;--glide-core-text-syntax-green: #116644;--glide-core-text-syntax-purple: #770088;--glide-core-text-syntax-red-dark: #95150e;--glide-core-text-syntax-red-light: #ee4400;--glide-core-text-tertiary: #ffffff;--glide-core-text-tertiary-disabled: #6d6d6d}:root{--glide-core-body-md-font-family: var(--glide-core-font-sans);--glide-core-body-md-font-size: 1rem;--glide-core-body-md-font-style: normal;--glide-core-body-md-font-weight: 400;--glide-core-body-md-line-height: normal;--glide-core-body-sm-font-family: var(--glide-core-font-sans);--glide-core-body-sm-font-size: .875rem;--glide-core-body-sm-font-variant: normal;--glide-core-body-sm-font-weight: 400;--glide-core-body-sm-line-height: 1.3;--glide-core-body-xs-font-family: var(--glide-core-font-sans);--glide-core-body-xs-font-size: .75rem;--glide-core-body-xs-font-variant: normal;--glide-core-body-xs-font-weight: 400;--glide-core-body-xs-line-height: 1.3;--glide-core-color-dark-blue: #054fb9;--glide-core-color-white: #ffffff;--glide-core-font-sans: "Nunito";--glide-core-font-weight-bold: 700;--glide-core-font-weight-semi-bold: 600;--glide-core-glow-sm: 0px 0px 2px 0px #2c97eee5;--glide-core-heading-xs-font-size: 1.25rem;--glide-core-heading-xs-font-weight: var(--glide-core-font-weight-semi-bold);--glide-core-heading-xxs-font-family: var(--glide-core-font-sans);--glide-core-heading-xxs-font-size: 1rem;--glide-core-heading-xxs-font-style: normal;--glide-core-heading-xxs-font-variant: normal;--glide-core-heading-xxs-font-weight: var(--glide-core-font-weight-bold);--glide-core-heading-xxxs-font-family: var(--glide-core-font-sans);--glide-core-heading-xxxs-font-size: .875rem;--glide-core-heading-xxxs-font-style: normal;--glide-core-heading-xxxs-font-variant: normal;--glide-core-heading-xxxs-font-weight: var(--glide-core-font-weight-bold);--glide-core-heading-xxxs-line-height: 1.7;--glide-core-shadow-lg: 0px 4px 14px 0px #00000040;--glide-core-shadow-sm: 0px 2.275px 8.342px 0px rgba(181, 181, 181, .25);--glide-core-shadow-xl: 0px 4px 60px 0px #adadad}
1
+ :root,:host{color-scheme:normal;--glide-core-border-radius-lg: .75rem;--glide-core-border-radius-md: .5rem;--glide-core-border-radius-none: 0rem;--glide-core-border-radius-round: 7.5rem;--glide-core-border-radius-sm: .25rem;--glide-core-border-radius-xs: .125rem;--glide-core-border-width-lg: .25rem;--glide-core-border-width-md: .125rem;--glide-core-border-width-none: 0rem;--glide-core-border-width-sm: .0625rem;--glide-core-spacing-lg: 1.5rem;--glide-core-spacing-md: 1rem;--glide-core-spacing-sm: .75rem;--glide-core-spacing-xl: 2rem;--glide-core-spacing-xs: .5rem;--glide-core-spacing-xxl: 3rem;--glide-core-spacing-xxs: .25rem;--glide-core-spacing-xxxl: 4rem;--glide-core-spacing-xxxs: .125rem;--glide-core-spacing-zero: 0rem}:root,:host,.theme-light{color-scheme:light;--glide-core-border-action: #0073e6;--glide-core-border-action-disabled: #d7e7ff;--glide-core-border-action-hover: #eef5ff;--glide-core-border-base: #c9c9c9;--glide-core-border-base-dark: #6d6d6d;--glide-core-border-base-darker: #424242;--glide-core-border-base-light: #e3e3e3;--glide-core-border-base-lighter: #f0f0f0;--glide-core-border-base-lightest: #ffffff;--glide-core-border-disabled: #8a8a8a;--glide-core-border-focus: #0073e6;--glide-core-border-focus-light: #eef5ff;--glide-core-border-primary: #054fb9;--glide-core-border-primary-hover: #0461cf;--glide-core-icon-active: #0073e6;--glide-core-icon-default: #212121;--glide-core-icon-default2: #212121;--glide-core-icon-display: #212121;--glide-core-icon-display-light: #6d6d6d;--glide-core-icon-hover: #8babf1;--glide-core-icon-primary: #054fb9;--glide-core-icon-primary-hover: #0461cf;--glide-core-icon-secondary-disabled: #d7e7ff;--glide-core-icon-selected: #ffffff;--glide-core-icon-selected-disabled: #eef5ff;--glide-core-icon-selected2: #ffffff;--glide-core-icon-tertiary-disabled: #8a8a8a;--glide-core-status-error: #db2d24;--glide-core-status-expired: #ff3b30;--glide-core-status-failed: #ff3b30;--glide-core-status-in-progress: #ffcc00;--glide-core-status-queued: #5ac8fa;--glide-core-status-scheduled: #af52de;--glide-core-status-success: #34c759;--glide-core-status-unknown: #6d6d6d;--glide-core-status-warning-critical: #ff3b30;--glide-core-status-warning-high: #ff9500;--glide-core-status-warning-informational: #0073e6;--glide-core-status-warning-low: #607d8b;--glide-core-status-warning-medium: #ffcc00;--glide-core-surface-active: #ffffff;--glide-core-surface-attention: #fffbeb;--glide-core-surface-base: #f0f0f0;--glide-core-surface-base-dark: #212121;--glide-core-surface-base-gray: #0000001a;--glide-core-surface-base-gray-dark: #00000066;--glide-core-surface-base-gray-light: #00000012;--glide-core-surface-base-gray-lighter: #00000008;--glide-core-surface-base-light: #ffffff8c;--glide-core-surface-base-lighter: #ffffffbf;--glide-core-surface-base-lightest: #ffffffcc;--glide-core-surface-base-xlightest: #ffffffe5;--glide-core-surface-disabled: #f0f0f0;--glide-core-surface-dot-step: #8babf1;--glide-core-surface-error: #fff0ef;--glide-core-surface-focus: #0073e6;--glide-core-surface-hover: #d7e7ff;--glide-core-surface-informational: #eef5ff;--glide-core-surface-modal: #ffffff;--glide-core-surface-page: #ffffff;--glide-core-surface-primary: #0073e6;--glide-core-surface-primary-disabled: #1d7afc26;--glide-core-surface-secondary: #eef5ff;--glide-core-surface-secondary-disabled: #eef5ff;--glide-core-surface-selected: #0073e6;--glide-core-surface-selected-disabled: #8a8a8a;--glide-core-surface-selected-hover: #054fb9;--glide-core-surface-success: #f1fdf4;--glide-core-surface-unselected-disabled: #e3e3e3;--glide-core-surface-warning: #fff6e9;--glide-core-surface-white-1percent: #ffffff03;--glide-core-text-body-1: #212121;--glide-core-text-body-2: #212121;--glide-core-text-body-light: #424242;--glide-core-text-body-lighter: #c9c9c9;--glide-core-text-disabled: #f0f0f0;--glide-core-text-header-1: #424242;--glide-core-text-header-2: #6d6d6d;--glide-core-text-link: #0461cf;--glide-core-text-link-dark-surface: #8babf1;--glide-core-text-link-table: #0461cf;--glide-core-text-placeholder: #6d6d6d;--glide-core-text-primary: #054fb9;--glide-core-text-primary-hover: #0461cf;--glide-core-text-secondary: #0073e6;--glide-core-text-secondary-disabled: #d7e7ff;--glide-core-text-selected: #ffffff;--glide-core-text-selected-2: #ffffff;--glide-core-text-syntax-blue: #0000ff;--glide-core-text-syntax-dark: #151515;--glide-core-text-syntax-green: #116644;--glide-core-text-syntax-purple: #770088;--glide-core-text-syntax-red-dark: #95150e;--glide-core-text-syntax-red-light: #ee4400;--glide-core-text-tertiary: #212121;--glide-core-text-tertiary-disabled: #8a8a8a}:host,.theme-dark{color-scheme:dark;--glide-core-border-action: #0073e6;--glide-core-border-action-disabled: #eef5ff;--glide-core-border-action-hover: #eef5ff;--glide-core-border-base: #6d6d6d;--glide-core-border-base-dark: #c9c9c9;--glide-core-border-base-darker: #e3e3e3;--glide-core-border-base-light: #212121;--glide-core-border-base-lighter: #212121;--glide-core-border-base-lightest: #424242;--glide-core-border-disabled: #8a8a8a;--glide-core-border-focus: #0073e6;--glide-core-border-focus-light: #eef5ff;--glide-core-border-primary: #ffffff;--glide-core-border-primary-hover: #0461cf;--glide-core-icon-active: #0073e6;--glide-core-icon-default: #ffffff;--glide-core-icon-default2: #212121;--glide-core-icon-display: #ffffff;--glide-core-icon-display-light: #d7e7ff;--glide-core-icon-hover: #eef5ff;--glide-core-icon-primary: #ffffff;--glide-core-icon-primary-hover: #d7e7ff;--glide-core-icon-secondary-disabled: #d7e7ff;--glide-core-icon-selected: #ffffff;--glide-core-icon-selected-disabled: #eef5ff;--glide-core-icon-selected2: #424242;--glide-core-icon-tertiary-disabled: #6d6d6d;--glide-core-status-error: #ff3b30;--glide-core-status-expired: #ff3b30;--glide-core-status-failed: #ff3b30;--glide-core-status-in-progress: #ffcc00;--glide-core-status-queued: #5ac8fa;--glide-core-status-scheduled: #af52de;--glide-core-status-success: #34c759;--glide-core-status-unknown: #6d6d6d;--glide-core-status-warning-critical: #ff3b30;--glide-core-status-warning-high: #ff9500;--glide-core-status-warning-informational: #0073e6;--glide-core-status-warning-low: #607d8b;--glide-core-status-warning-medium: #ffcc00;--glide-core-surface-active: #ffffff;--glide-core-surface-attention: #fffbeb;--glide-core-surface-base: #424242;--glide-core-surface-base-dark: #212121;--glide-core-surface-base-gray: #ffffff8c;--glide-core-surface-base-gray-dark: #ffffff8c;--glide-core-surface-base-gray-light: #00000066;--glide-core-surface-base-gray-lighter: #ffffff1a;--glide-core-surface-base-light: #0000008c;--glide-core-surface-base-lighter: #000000bf;--glide-core-surface-base-lightest: #000000cc;--glide-core-surface-base-xlightest: #000000e5;--glide-core-surface-disabled: #424242;--glide-core-surface-dot-step: #8babf1;--glide-core-surface-error: #fff0ef;--glide-core-surface-focus: #0073e6;--glide-core-surface-hover: #0461cf;--glide-core-surface-informational: #eef5ff;--glide-core-surface-modal: #151515;--glide-core-surface-page: #212121;--glide-core-surface-primary: #0073e6;--glide-core-surface-primary-disabled: #6d6d6d;--glide-core-surface-secondary: #f0f0f0;--glide-core-surface-secondary-disabled: #f0f0f0;--glide-core-surface-selected: #0073e6;--glide-core-surface-selected-disabled: #8a8a8a;--glide-core-surface-selected-hover: #054fb9;--glide-core-surface-success: #f1fdf4;--glide-core-surface-unselected-disabled: #e3e3e3;--glide-core-surface-warning: #fff6e9;--glide-core-surface-white-1percent: #000000e5;--glide-core-text-body-1: #ffffff;--glide-core-text-body-2: #212121;--glide-core-text-body-light: #ffffff;--glide-core-text-body-lighter: #c9c9c9;--glide-core-text-disabled: #f0f0f0;--glide-core-text-header-1: #ffffff;--glide-core-text-header-2: #d7e7ff;--glide-core-text-link: #8babf1;--glide-core-text-link-dark-surface: #8babf1;--glide-core-text-link-table: #d0e8f2;--glide-core-text-placeholder: #d7e7ff;--glide-core-text-primary: #ffffff;--glide-core-text-primary-hover: #d7e7ff;--glide-core-text-secondary: #8babf1;--glide-core-text-secondary-disabled: #d7e7ff;--glide-core-text-selected: #ffffff;--glide-core-text-selected-2: #424242;--glide-core-text-syntax-blue: #0000ff;--glide-core-text-syntax-dark: #ffffff;--glide-core-text-syntax-green: #116644;--glide-core-text-syntax-purple: #770088;--glide-core-text-syntax-red-dark: #95150e;--glide-core-text-syntax-red-light: #ee4400;--glide-core-text-tertiary: #ffffff;--glide-core-text-tertiary-disabled: #6d6d6d}:root{--glide-core-body-md-font-family: var(--glide-core-font-sans);--glide-core-body-md-font-size: 1rem;--glide-core-body-md-font-style: normal;--glide-core-body-md-font-weight: 400;--glide-core-body-md-line-height: normal;--glide-core-body-sm-font-family: var(--glide-core-font-sans);--glide-core-body-sm-font-size: .875rem;--glide-core-body-sm-font-variant: normal;--glide-core-body-sm-font-weight: 400;--glide-core-body-sm-line-height: 1.3;--glide-core-body-xs-font-family: var(--glide-core-font-sans);--glide-core-body-xs-font-size: .75rem;--glide-core-body-xs-font-variant: normal;--glide-core-body-xs-font-weight: 400;--glide-core-body-xs-line-height: 1.3;--glide-core-color-dark-blue: #054fb9;--glide-core-color-white: #ffffff;--glide-core-font-sans: "Nunito";--glide-core-font-weight-bold: 700;--glide-core-font-weight-semi-bold: 600;--glide-core-glow-sm: 0px 0px 2px 0px #2c97eee5;--glide-core-heading-xs-font-size: 1.25rem;--glide-core-heading-xs-font-weight: var(--glide-core-font-weight-semi-bold);--glide-core-heading-xxs-font-family: var(--glide-core-font-sans);--glide-core-heading-xxs-font-size: 1rem;--glide-core-heading-xxs-font-style: normal;--glide-core-heading-xxs-font-variant: normal;--glide-core-heading-xxs-font-weight: var(--glide-core-font-weight-bold);--glide-core-heading-xxxs-font-family: var(--glide-core-font-sans);--glide-core-heading-xxxs-font-size: .875rem;--glide-core-heading-xxxs-font-style: normal;--glide-core-heading-xxxs-font-variant: normal;--glide-core-heading-xxxs-font-weight: var(--glide-core-font-weight-bold);--glide-core-heading-xxxs-line-height: 1.7;--glide-core-shadow-lg: 0px 4px 14px 0px #00000040;--glide-core-shadow-sm: 0px 2.275px 8.342px 0px rgba(181, 181, 181, .25);--glide-core-shadow-xl: 0px 4px 60px 0px #adadad}
@@ -1,2 +1,2 @@
1
- declare const _default: import("lit").CSSResult;
1
+ declare const _default: (selector: string) => import("lit").CSSResult;
2
2
  export default _default;
@@ -1 +1,14 @@
1
- import{unsafeCSS}from"lit";export default unsafeCSS("\n border-width: 0;\n clip: rect(0, 0, 0, 0);\n height: 1px;\n margin: -1px;\n overflow: hidden;\n padding: 0;\n position: absolute;\n white-space: nowrap;\n width: 1px;\n");
1
+ import{css,unsafeCSS}from"lit";export default e=>css`
2
+ /* stylelint-disable selector-type-case, selector-type-no-unknown */
3
+ ${unsafeCSS(e)} {
4
+ block-size: 1px;
5
+ border-width: 0;
6
+ clip: rect(0, 0, 0, 0);
7
+ inline-size: 1px;
8
+ margin: -1px;
9
+ overflow: hidden;
10
+ padding: 0;
11
+ position: absolute;
12
+ white-space: nowrap;
13
+ }
14
+ `;
@@ -18,12 +18,12 @@ export default class GlideCoreTabGroup extends LitElement {
18
18
  #private;
19
19
  static shadowRootOptions: ShadowRootInit;
20
20
  static styles: import("lit").CSSResult[];
21
- /**
22
- * The tab element that is currently active
23
- * */
24
- activeTab?: GlideCoreTab;
25
- isShowOverflowStartButton: boolean;
26
- isShowOverflowEndButton: boolean;
21
+ get activeTab(): GlideCoreTab | null;
22
+ set activeTab(tab: GlideCoreTab | null);
23
+ isAfterFirstUpdated: boolean;
24
+ isDisableOverflowStartButton: boolean;
25
+ isDisableOverflowEndButton: boolean;
26
+ isShowOverflowButtons: boolean;
27
27
  panelElements: GlideCoreTabPanel[];
28
28
  tabElements: GlideCoreTab[];
29
29
  disconnectedCallback(): void;
package/dist/tab.group.js CHANGED
@@ -1 +1 @@
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.#b("right",!0)},this.#d=()=>{this.#b("left",!0)},this.#v=()=>{for(const[,t]of this.tabElements.entries())t.tabIndex=t===this.activeTab?0:-1},this.#m=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++}o<0&&(o=this.tabElements.length-1),o>this.tabElements.length-1&&(o=0),this.tabElements[o].focus({preventScroll:!1});for(const[,t]of this.tabElements.entries())t.tabIndex=this.tabElements[o]===t?0:-1;if(this.#w(),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.#b("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.#b("right")}t.preventDefault()}}},this.#w=()=>{this.#E(),this.#p()}}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.#T(),this.#g(),this.#R()}render(){return html`<div class="component" @click="${this.#c}" @keydown="${this.#m}"><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.#d}" 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.#y}" @focusout="${this.#v}"><slot name="nav" @slotchange="${this.#S}" ${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.#C}" ${ref(this.#e)}></slot></div>`}updated(){this.#T()}#t;#e;#o;#i;#s;#l;#n;#r;#a;#h;#c;#f;#d;#v;#m;#w;#C(){owSlotType(this.#e.value,[GlideCoreTabPanel])}#S(){owSlotType(this.#i.value,[GlideCoreTab]),this.#w()}#y(){this.#a&&clearTimeout(this.#a),this.#a=setTimeout((()=>{this.#w()}),this.#t)}#b(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())this.activeTab||0!==t?(e.active=this.activeTab===e,e.tabIndex=this.activeTab===e?0:-1):(this.activeTab=e,this.activeTab.active=!0,this.activeTab.tabIndex=0);for(const t of this.panelElements){const e=this.activeTab?.getAttribute("panel"),o=t.getAttribute("name");t.isActive=o===e,t.tabIndex=o===e?0:-1}}#p(){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}}#E(){ow(this.#h.value,ow.object.instanceOf(HTMLElement)),this.isShowOverflowStartButton=this.#h.value.scrollLeft>0}#R(){this.#n=new ResizeObserver((t=>{t?.at(0)?.target===this.#h.value&&(this.#r&&clearTimeout(this.#r),this.#r=setTimeout((()=>{this.#w()}),this.#t))})),ow(this.#h.value,ow.object.instanceOf(HTMLElement)),this.#n.observe(this.#h.value)}#T(){for(const t of this.tabElements){const e=this.panelElements.filter((e=>e.name===t.panel))?.at(0);ow(e,ow.object.instanceOf(GlideCoreTabPanel)),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
+ var __decorate=this&&this.__decorate||function(t,e,i,s){var o,l=arguments.length,a=l<3?e:null===s?s=Object.getOwnPropertyDescriptor(e,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(t,e,i,s);else for(var r=t.length-1;r>=0;r--)(o=t[r])&&(a=(l<3?o(a):l>3?o(e,i,a):o(e,i))||a);return l>3&&a&&Object.defineProperty(e,i,a),a};import"./icon-button.js";import{LitElement,html}from"lit";import{LocalizeController}from"./library/localize.js";import{classMap}from"lit/directives/class-map.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.isAfterFirstUpdated=!1,this.isDisableOverflowStartButton=!1,this.isDisableOverflowEndButton=!1,this.isShowOverflowButtons=!1,this.#t=createRef(),this.#e=null,this.#i=100,this.#s=createRef(),this.#o=new LocalizeController(this),this.#l=createRef(),this.#a=1,this.#r=createRef(),this.#n=createRef(),this.#c=null,this.#h=null,this.#b=null,this.#u=null,this.#d=createRef()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}get activeTab(){return this.#e}set activeTab(t){this.#c=this.#e,this.#e=t}disconnectedCallback(){this.#h?.disconnect(),this.#h=null}firstUpdated(){owSlotType(this.#l.value,[GlideCoreTab]),owSlotType(this.#s.value,[GlideCoreTabPanel]),this.#f()}render(){return html`<div class="component" @click="${this.#v}" @keydown="${this.#m}" ${ref(this.#t)}><div class="tab-container">${when(this.isShowOverflowButtons,(()=>html`<button style="height: ${this.#d.value?.clientHeight}px" class="${classMap({overflow:!0,disabled:this.isDisableOverflowStartButton})}" @click="${this.#p}" tabindex="-1" aria-label="${this.#o.term("previousTab")}" data-test="overflow-start-button" ${ref(this.#n)} ?disabled="${this.isDisableOverflowStartButton}"><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 role="tablist" class="${classMap({"tab-group":!0,animated:this.isAfterFirstUpdated})}" ${ref(this.#d)} @scroll="${this.#w}" @focusout="${this.#T}" tabindex="-1"><slot name="nav" @slotchange="${this.#E}" ${ref(this.#l)}></slot></div>${when(this.isShowOverflowButtons,(()=>html`<button style="height: ${this.#d.value?.clientHeight}px" class="${classMap({overflow:!0,disabled:this.isDisableOverflowEndButton})}" @click="${this.#R}" tabindex="-1" aria-label="${this.#o.term("nextTab")}" data-test="overflow-end-button" ${ref(this.#r)} ?disabled="${this.isDisableOverflowEndButton}"><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><slot @slotchange="${this.#g}" ${ref(this.#s)}></slot></div>`}updated(){this.#S()}#t;#e;#i;#s;#o;#l;#a;#r;#n;#c;#h;#b;#u;#d;#v(t){const e=t.target.closest("glide-core-tab");e&&e instanceof GlideCoreTab&&!e.disabled&&this.#y(e)}#R(){this.#O("right")}#p(){this.#O("left")}#g(){owSlotType(this.#s.value,[GlideCoreTabPanel])}#T(){for(const[,t]of this.tabElements.entries())t.tabIndex=t===this.activeTab?0:-1}#m(t){const e=t.target.closest("glide-core-tab");if(["Enter"," "].includes(t.key)&&e&&e instanceof GlideCoreTab&&!e.disabled&&(this.#y(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 i=this.tabElements.indexOf(e);switch(t.key){case"Home":i=0;break;case"End":i=this.tabElements.length-1;break;case"ArrowLeft":i--;break;case"ArrowRight":i++}i<0&&(i=this.tabElements.length-1),i>this.tabElements.length-1&&(i=0),this.tabElements[i].focus({preventScroll:!1});for(const[,t]of this.tabElements.entries())t.tabIndex=this.tabElements[i]===t?0:-1;this.#B(),t.preventDefault()}}}#E(){owSlotType(this.#l.value,[GlideCoreTab]),this.#S(),this.#C(),this.#L(),this.#B()}#w(){this.#u&&clearTimeout(this.#u),this.#u=setTimeout((()=>{this.#B()}),this.#i)}#O(t){const e="right"===t?1:-1;ow(this.#d.value,ow.object.instanceOf(HTMLElement));const i=e*this.#d.value?.clientWidth*.5;this.#d.value?.scrollBy({left:i,top:0})}#C(){for(const[t,e]of this.tabElements.entries())this.activeTab||0!==t?(e.active=this.activeTab===e,e.tabIndex=this.activeTab===e?0:-1):(this.activeTab=e,this.activeTab.active=!0,this.activeTab.tabIndex=0);for(const t of this.panelElements){const e=this.activeTab?.getAttribute("panel"),i=t.getAttribute("name");t.isActive=i===e,t.tabIndex=i===e?0:-1}if(this.activeTab!==this.#c&&this.activeTab&&this.tabElements.length>0&&this.#t.value){const t=Number.parseInt(window.getComputedStyle(this.activeTab).getPropertyValue("padding-inline-"+(this.activeTab===this.tabElements.at(0)?"start":"end"))),e=this.activeTab===this.tabElements.at(0)?t:this.activeTab.offsetLeft-this.tabElements[0].offsetLeft;this.#t.value.style.setProperty("--active-tab-indicator-translate",`${e}px`);const i=this.activeTab===this.tabElements.at(0)||this.activeTab===this.tabElements.at(-1)?t:0;this.#t.value.style.setProperty("--active-tab-indicator-width",this.activeTab.clientWidth-i+"px")}}#A(){const t=this.#d.value,e=t?.getBoundingClientRect();if(ow(t,ow.object.instanceOf(HTMLElement)),e){const{width:i}=e,s=t.scrollLeft+i,o=t.scrollWidth;this.isDisableOverflowEndButton=o-s<=this.#a}}#B(){const t=this.#d.value,e=t?.getBoundingClientRect();if(t&&e){const{width:i}=e;this.isShowOverflowButtons=t.scrollWidth-i>this.#a}this.#G(),this.#A()}#G(){ow(this.#d.value,ow.object.instanceOf(HTMLElement)),this.isDisableOverflowStartButton=this.#d.value.scrollLeft<=0}#L(){if(this.activeTab&&this.#t.value){const t=Number.parseInt(window.getComputedStyle(this.activeTab).getPropertyValue("padding-inline-start")),{width:e}=this.activeTab.getBoundingClientRect();this.#t.value.style.setProperty("--active-tab-indicator-width",e-t+"px"),this.#t.value.style.setProperty("--active-tab-indicator-translate",`${t}px`),this.isAfterFirstUpdated=!0}}#f(){this.#h=new ResizeObserver((t=>{t?.at(0)?.target===this.#d.value&&(this.#b&&clearTimeout(this.#b),this.#b=setTimeout((()=>{this.#B()}),this.#i))})),ow(this.#d.value,ow.object.instanceOf(HTMLElement)),this.#h.observe(this.#d.value)}#S(){for(const t of this.tabElements){const e=this.panelElements.filter((e=>e.name===t.panel))?.at(0);e?.getAttribute("id")&&(t.setAttribute("aria-controls",e.getAttribute("id")),e.setAttribute("aria-labelledby",t.getAttribute("id")))}}#y(t){this.activeTab=t,this.#C(),this.dispatchEvent(new CustomEvent("tab-show",{bubbles:!0,detail:{panel:t.panel}}))}};__decorate([state()],GlideCoreTabGroup.prototype,"activeTab",null),__decorate([state()],GlideCoreTabGroup.prototype,"isAfterFirstUpdated",void 0),__decorate([state()],GlideCoreTabGroup.prototype,"isDisableOverflowStartButton",void 0),__decorate([state()],GlideCoreTabGroup.prototype,"isDisableOverflowEndButton",void 0),__decorate([state()],GlideCoreTabGroup.prototype,"isShowOverflowButtons",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;
@@ -6,17 +6,16 @@ import{css}from"lit";export default[css`
6
6
 
7
7
  & .tab-container {
8
8
  border-block-end: 1px solid var(--glide-core-border-base-lighter);
9
+ box-sizing: border-box;
9
10
  display: flex;
10
-
11
- & .overflow-button-container {
12
- flex-shrink: 0;
13
- inline-size: 1.875rem;
14
- }
15
11
  }
16
12
 
17
13
  & .tab-group {
18
14
  display: flex;
15
+ gap: var(--glide-core-spacing-xl);
19
16
  overflow: auto hidden;
17
+ position: relative;
18
+ scroll-behavior: smooth;
20
19
  scrollbar-width: none;
21
20
  white-space: nowrap;
22
21
 
@@ -26,16 +25,58 @@ import{css}from"lit";export default[css`
26
25
  block-size: 0;
27
26
  inline-size: 0;
28
27
  }
28
+
29
+ &::after {
30
+ background: var(--glide-core-border-focus);
31
+ block-size: 0.125rem;
32
+ content: '';
33
+ inline-size: var(--active-tab-indicator-width);
34
+ inset-block-end: 0;
35
+ inset-inline: 0;
36
+ position: absolute;
37
+ transform-origin: left;
38
+ translate: var(--active-tab-indicator-translate, 0) 0;
39
+ }
40
+
41
+ &.animated::after {
42
+ transition:
43
+ inline-size 250ms,
44
+ translate 250ms;
45
+ }
29
46
  }
30
47
 
31
48
  & .overflow {
32
49
  background-color: transparent;
33
50
  border: none;
51
+ color: var(--glide-core-icon-default);
34
52
  cursor: pointer;
53
+ flex-shrink: 0;
35
54
  inline-size: 1.875rem;
36
55
  margin: 0;
37
56
  outline: none;
38
57
  padding: 0;
58
+
59
+ &.disabled {
60
+ color: var(--glide-core-icon-tertiary-disabled);
61
+ }
62
+ }
63
+ }
64
+
65
+ ::slotted([slot='nav']:first-of-type) {
66
+ padding-inline-start: 0.1875rem;
67
+ }
68
+
69
+ ::slotted([slot='nav']:last-of-type) {
70
+ padding-inline-end: 0.1875rem;
71
+ }
72
+
73
+ @media (prefers-reduced-motion: reduce) {
74
+ .component .tab-group {
75
+ scroll-behavior: auto;
76
+
77
+ &.animated::after {
78
+ transition: none;
79
+ }
39
80
  }
40
81
  }
41
82
  `];
@@ -2,11 +2,12 @@
2
2
  import './tab.group.js';
3
3
  import './tab.js';
4
4
  import './tab.panel.js';
5
- import { expect, fixture, html, oneEvent } from '@open-wc/testing';
5
+ import { expect, fixture, html, oneEvent, waitUntil } from '@open-wc/testing';
6
6
  import { sendKeys } from '@web/test-runner-commands';
7
7
  import GlideCoreTabGroup from './tab.group.js';
8
8
  import GlideCoreTabPanel from './tab.panel.js';
9
9
  import expectArgumentError from './library/expect-argument-error.js';
10
+ import sinon from 'sinon';
10
11
  GlideCoreTabGroup.shadowRootOptions.mode = 'open';
11
12
  GlideCoreTabPanel.shadowRootOptions.mode = 'open';
12
13
  function isPanelHidden(panel) {
@@ -31,7 +32,7 @@ it('renders correct markup and sets correct attributes for the default case', as
31
32
  ]);
32
33
  expect([
33
34
  ...tabGroup.shadowRoot.querySelector('.tab-group').classList,
34
- ]).to.deep.equal(['tab-group']);
35
+ ]).to.deep.equal(['tab-group', 'animated']);
35
36
  const slot = tabGroup.shadowRoot.querySelector('slot:not([name="nav"])');
36
37
  expect(slot).to.exist;
37
38
  expect(slot.assignedElements.length).to.equal(0);
@@ -125,6 +126,10 @@ it('throws an error when an element other than `glide-core-tab` is a child of th
125
126
  });
126
127
  });
127
128
  it('throws an error when an element other than `glide-core-tab-panel` is a child of the default slot', async () => {
129
+ const spy = sinon.spy();
130
+ window.addEventListener('unhandledrejection', spy);
131
+ // https://github.com/CrowdStrike/glide-core/pull/335#issuecomment-2327451869
132
+ const stub = sinon.stub(console, 'error');
128
133
  await expectArgumentError(() => {
129
134
  return fixture(html `
130
135
  <glide-core-tab-group>
@@ -133,4 +138,6 @@ it('throws an error when an element other than `glide-core-tab-panel` is a child
133
138
  </glide-core-tab-group>
134
139
  `);
135
140
  });
141
+ await waitUntil(() => spy.callCount === 1);
142
+ stub.restore();
136
143
  });