@brightspot/ui 1.10.0 → 1.11.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 (129) hide show
  1. package/dist/components/action-bar/ActionBar.d.ts +163 -0
  2. package/dist/components/action-bar/ActionBar.d.ts.map +1 -0
  3. package/dist/components/action-bar/ActionBar.js +479 -0
  4. package/dist/components/action-bar/ActionBar.js.map +1 -0
  5. package/dist/components/action-bar/ActionItem.d.ts +103 -0
  6. package/dist/components/action-bar/ActionItem.d.ts.map +1 -0
  7. package/dist/components/action-bar/ActionItem.js +237 -0
  8. package/dist/components/action-bar/ActionItem.js.map +1 -0
  9. package/dist/components/dropdown/Dropdown.d.ts +3 -1
  10. package/dist/components/dropdown/Dropdown.d.ts.map +1 -1
  11. package/dist/components/dropdown/Dropdown.js +22 -6
  12. package/dist/components/dropdown/Dropdown.js.map +1 -1
  13. package/dist/components/dropdown/DropdownItem.d.ts +14 -1
  14. package/dist/components/dropdown/DropdownItem.d.ts.map +1 -1
  15. package/dist/components/dropdown/DropdownItem.js +20 -1
  16. package/dist/components/dropdown/DropdownItem.js.map +1 -1
  17. package/dist/components/dropdown/DropdownMenu.d.ts +3 -5
  18. package/dist/components/dropdown/DropdownMenu.d.ts.map +1 -1
  19. package/dist/components/dropdown/DropdownMenu.js +17 -32
  20. package/dist/components/dropdown/DropdownMenu.js.map +1 -1
  21. package/dist/components/pagination/Pagination.d.ts +33 -4
  22. package/dist/components/pagination/Pagination.d.ts.map +1 -1
  23. package/dist/components/pagination/Pagination.js +80 -16
  24. package/dist/components/pagination/Pagination.js.map +1 -1
  25. package/dist/components/tabs/Tab.d.ts +108 -0
  26. package/dist/components/tabs/Tab.d.ts.map +1 -0
  27. package/dist/components/tabs/Tab.js +152 -0
  28. package/dist/components/tabs/Tab.js.map +1 -0
  29. package/dist/components/tabs/Tabs.d.ts +126 -0
  30. package/dist/components/tabs/Tabs.d.ts.map +1 -0
  31. package/dist/components/tabs/Tabs.js +390 -0
  32. package/dist/components/tabs/Tabs.js.map +1 -0
  33. package/dist/custom-elements.json +2635 -1591
  34. package/dist/storybook/assets/ActionBar.stories--nAeDC-G.js +408 -0
  35. package/dist/storybook/assets/ActionItem.stories-BHrGjk-P.js +203 -0
  36. package/dist/storybook/assets/{Avatar.stories-B26mRkkZ.js → Avatar.stories-Da-mRj6_.js} +1 -1
  37. package/dist/storybook/assets/{AvatarGroup.stories-J7lVGsMY.js → AvatarGroup.stories-BQlaC_yl.js} +1 -1
  38. package/dist/storybook/assets/{Badge.stories-BpTIV61M.js → Badge.stories-DnVnOrnF.js} +1 -1
  39. package/dist/storybook/assets/{Button-Dg-fIrzT.js → Button-CFLAI1H9.js} +1 -1
  40. package/dist/storybook/assets/{Button.stories-gPKRVbxk.js → Button.stories-DxaBOjwv.js} +1 -1
  41. package/dist/storybook/assets/{Celebrate.stories-DbY-sKEe.js → Celebrate.stories-CuMm15Nr.js} +1 -1
  42. package/dist/storybook/assets/{CircularProgress.stories-DeH5JYX_.js → CircularProgress.stories-DRN8Mtvj.js} +1 -1
  43. package/dist/storybook/assets/{ClipboardMixin.stories-C-lZ4uuw.js → ClipboardMixin.stories-DR7Ou2Av.js} +1 -1
  44. package/dist/storybook/assets/{Color-6BZIO3FS-Cu6zVIuG.js → Color-6BZIO3FS-Die62Y0Z.js} +1 -1
  45. package/dist/storybook/assets/{Colors.stories-D6XYMrTD.js → Colors.stories-bIq_ssbI.js} +1 -1
  46. package/dist/storybook/assets/{CombinedEffects.stories-jFekKTYg.js → CombinedEffects.stories-CtKzOUZn.js} +1 -1
  47. package/dist/storybook/assets/{ComponentStatesMixin-g50hRCPT.js → ComponentStatesMixin-DMLCk9fE.js} +1 -1
  48. package/dist/storybook/assets/{ComponentStatesMixin.stories-D3Q5pR38.js → ComponentStatesMixin.stories-D8UI9o-d.js} +1 -1
  49. package/dist/storybook/assets/{CopyToClipboard.stories-COZZ1VC2.js → CopyToClipboard.stories-ti6CpJNp.js} +1 -1
  50. package/dist/storybook/assets/{Debounce.stories-Dl10LAnx.js → Debounce.stories-DzZUSvbk.js} +1 -1
  51. package/dist/storybook/assets/{DocsRenderer-LL677BLK-CFLtMbUx.js → DocsRenderer-LL677BLK-CIRGv5IX.js} +3 -3
  52. package/dist/storybook/assets/{Dropdown.stories-Drwq-0Z2.js → Dropdown.stories-Lt4cY0Re.js} +41 -14
  53. package/dist/storybook/assets/{Events.stories-dODeR-g-.js → Events.stories-B1ddcgpT.js} +1 -1
  54. package/dist/storybook/assets/{Heading.stories-CH7_-_q3.js → Heading.stories-DI4w61cf.js} +1 -1
  55. package/dist/storybook/assets/{HueRipple.stories-CH1Y739k.js → HueRipple.stories-DjhoxxEw.js} +1 -1
  56. package/dist/storybook/assets/{Icon.stories-CPjM-jTU.js → Icon.stories-CpziAhae.js} +1 -1
  57. package/dist/storybook/assets/{IconButton.stories-DuzqvcnN.js → IconButton.stories-KjN28hfc.js} +1 -1
  58. package/dist/storybook/assets/{LinearProgress.stories-C7IdnJd3.js → LinearProgress.stories-DcIpdz6R.js} +1 -1
  59. package/dist/storybook/assets/Pagination.stories-BBkLEwoP.js +252 -0
  60. package/dist/storybook/assets/{Popover.stories-Ca1F-wrI.js → Popover.stories-DLv48c2h.js} +1 -1
  61. package/dist/storybook/assets/{ReadyMixin-DNZ5dCsZ.js → ReadyMixin-Cw2Dfbu2.js} +1 -1
  62. package/dist/storybook/assets/RovingTabindexMixin.stories-BWaFx9mu.js +192 -0
  63. package/dist/storybook/assets/{Rtc.stories-BVJc1vCA.js → Rtc.stories-Ve7Bwo_l.js} +1 -1
  64. package/dist/storybook/assets/ScrollShadow.stories-C6XmrRLm.js +17 -0
  65. package/dist/storybook/assets/{Switch.stories-BEEHP8mD.js → Switch.stories-Cf8WM1LG.js} +1 -1
  66. package/dist/storybook/assets/Tab.stories-CEtdEtOx.js +218 -0
  67. package/dist/storybook/assets/Tabs.stories-CIAO1bPO.js +211 -0
  68. package/dist/storybook/assets/{Throttle.stories-C4xsYeAb.js → Throttle.stories-BqxVIb-r.js} +1 -1
  69. package/dist/storybook/assets/{Tooltip.stories-Ccm4AnSv.js → Tooltip.stories-B6fw6875.js} +1 -1
  70. package/dist/storybook/assets/{Welcome.stories-Degjk-M0.js → Welcome.stories-CfJtSM19.js} +1 -1
  71. package/dist/storybook/assets/{Widget.stories-OKnZ9sDs.js → Widget.stories-CiOho7lO.js} +1 -1
  72. package/dist/storybook/assets/{WithTooltip-65CFNBJE-CXL3TyJ2.js → WithTooltip-65CFNBJE-PGcopp73.js} +2 -2
  73. package/dist/storybook/assets/{blocks-DLdUKG_W.js → blocks-dP2DwISI.js} +5 -5
  74. package/dist/storybook/assets/{formatter-EIJCOSYU-29NCxjfM.js → formatter-EIJCOSYU-CZSAC3tg.js} +1 -1
  75. package/dist/storybook/assets/if-defined-B1RdczOE.js +1 -0
  76. package/dist/storybook/assets/{iframe-BqvwP3or.js → iframe-DloIUNZz.js} +161 -161
  77. package/dist/storybook/assets/iframe-bJgLXZKK.css +1 -0
  78. package/dist/storybook/assets/{index-BIyTv1BF.js → index-DKF0ypu5.js} +1 -1
  79. package/dist/storybook/assets/onFind-C0l4Gew0.js +1 -0
  80. package/dist/storybook/assets/{onFind.stories-D64-QZqf.js → onFind.stories-DOTt9puO.js} +1 -1
  81. package/dist/storybook/assets/{onRemove.stories-BICsnIJL.js → onRemove.stories-CQ9ZC5dm.js} +1 -1
  82. package/dist/storybook/assets/{onVisible.stories-DpDZP9_5.js → onVisible.stories-Cbj5_Vz0.js} +1 -1
  83. package/dist/storybook/assets/style-map-DLXysq3r.js +1 -0
  84. package/dist/storybook/assets/{syntaxhighlighter-ED5Y7EFY-Bz_DuQj8.js → syntaxhighlighter-ED5Y7EFY-Bjjbl9ca.js} +1 -1
  85. package/dist/storybook/iframe.html +2 -2
  86. package/dist/storybook/index.json +1 -1
  87. package/dist/storybook/project.json +1 -1
  88. package/dist/tailwind-plugin-action-bar.d.ts +2 -0
  89. package/dist/tailwind-plugin-action-bar.d.ts.map +1 -0
  90. package/dist/tailwind-plugin-action-bar.js +120 -0
  91. package/dist/tailwind-plugin-action-bar.js.map +1 -0
  92. package/dist/tailwind-plugin-action-bar.ts +134 -0
  93. package/dist/tailwind-plugin-badge.js +4 -5
  94. package/dist/tailwind-plugin-badge.js.map +1 -1
  95. package/dist/tailwind-plugin-badge.ts +4 -5
  96. package/dist/tailwind-plugin-button.js +1 -0
  97. package/dist/tailwind-plugin-button.js.map +1 -1
  98. package/dist/tailwind-plugin-button.ts +1 -0
  99. package/dist/tailwind-plugin-pagination.js +13 -23
  100. package/dist/tailwind-plugin-pagination.js.map +1 -1
  101. package/dist/tailwind-plugin-pagination.ts +15 -25
  102. package/dist/tailwind-plugin-tabs.d.ts +2 -0
  103. package/dist/tailwind-plugin-tabs.d.ts.map +1 -0
  104. package/dist/tailwind-plugin-tabs.js +151 -0
  105. package/dist/tailwind-plugin-tabs.js.map +1 -0
  106. package/dist/tailwind-plugin-tabs.ts +162 -0
  107. package/dist/util/EventEmitterMixin.d.ts +16 -0
  108. package/dist/util/EventEmitterMixin.d.ts.map +1 -1
  109. package/dist/util/EventEmitterMixin.js.map +1 -1
  110. package/dist/util/RovingTabindexMixin.d.ts +38 -0
  111. package/dist/util/RovingTabindexMixin.d.ts.map +1 -0
  112. package/dist/util/RovingTabindexMixin.js +83 -0
  113. package/dist/util/RovingTabindexMixin.js.map +1 -0
  114. package/docs/components/ActionBar.md +71 -0
  115. package/docs/components/ActionItem.md +76 -0
  116. package/docs/components/Dropdown.md +7 -7
  117. package/docs/components/DropdownItem.md +9 -5
  118. package/docs/components/DropdownMenu.md +12 -12
  119. package/docs/components/Pagination.md +37 -34
  120. package/docs/components/README.md +4 -0
  121. package/docs/components/Tab.md +73 -0
  122. package/docs/components/Tabs.md +77 -0
  123. package/package.json +1 -1
  124. package/dist/storybook/assets/Pagination.stories-C4cLjS_9.js +0 -272
  125. package/dist/storybook/assets/ScrollShadow.stories-C3W5o9ZW.js +0 -17
  126. package/dist/storybook/assets/if-defined-BZFPaJjl.js +0 -1
  127. package/dist/storybook/assets/iframe-C5bIZMJ5.css +0 -1
  128. package/dist/storybook/assets/onFind-1l3EPW-I.js +0 -1
  129. package/dist/storybook/assets/style-map-CBrSnxRe.js +0 -1
@@ -0,0 +1,152 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { LitElement, html, nothing } from 'lit';
8
+ import { property } from 'lit/decorators.js';
9
+ import { styleMap } from 'lit/directives/style-map.js';
10
+ import { EventEmitterMixin } from '../../util/EventEmitterMixin.js';
11
+ import { ReadyMixin } from '../../util/ReadyMixin.js';
12
+ import '../badge/Badge.js';
13
+ import '../icon/Icon.js';
14
+ /**
15
+ * An individual tab within a tab group.
16
+ *
17
+ * Renders a button with role="tab" that participates in keyboard navigation
18
+ * and selection state managed by the parent `btu-tabs` container.
19
+ *
20
+ * @element btu-tab
21
+ *
22
+ * @fires {CustomEvent} btu-tab-ready - Fired after first render
23
+ * @fires {CustomEvent<{name: string}>} btu-tab-change - Fired when a non-disabled tab with a name is clicked
24
+ *
25
+ * @cssprop --badge-color-background - Background color of the count indicator badge (default: gray-50)
26
+ * @cssprop --badge-color-foreground - Text color of the count indicator badge (default: gray-700)
27
+ *
28
+ * @example
29
+ * ```html
30
+ * <btu-tabs>
31
+ * <btu-tab name="main" label="Main"></btu-tab>
32
+ * <btu-tab name="seo" label="SEO"></btu-tab>
33
+ * <btu-tab name="styles" label="Styles" disabled></btu-tab>
34
+ * </btu-tabs>
35
+ * ```
36
+ */
37
+ export default class Tab extends EventEmitterMixin(ReadyMixin(LitElement)) {
38
+ constructor() {
39
+ super(...arguments);
40
+ /**
41
+ * Whether the tab is disabled and non-interactive.
42
+ * @attr
43
+ */
44
+ this.disabled = false;
45
+ /**
46
+ * Placement of the icon relative to the label.
47
+ * @attr icon-position
48
+ */
49
+ this.iconPosition = 'leading';
50
+ /**
51
+ * When true, hides the label visually while maintaining accessibility.
52
+ * @attr icon-only
53
+ */
54
+ this.iconOnly = false;
55
+ /**
56
+ * When true, displays an error badge on the tab.
57
+ * @attr
58
+ */
59
+ this.error = false;
60
+ /** @internal Active state set by parent btu-tabs */
61
+ this._active = false;
62
+ /** @internal Roving tabindex value set by parent btu-tabs */
63
+ this._tabindex = -1;
64
+ /** @internal Set by parent btu-tabs */
65
+ this.size = 'md';
66
+ /** @internal */
67
+ this.initialClasses = [];
68
+ }
69
+ static get tagName() {
70
+ return 'BTU-TAB';
71
+ }
72
+ connectedCallback() {
73
+ super.connectedCallback();
74
+ if (this.className) {
75
+ this.initialClasses = this.className.split(' ').filter(c => c.trim());
76
+ }
77
+ }
78
+ createRenderRoot() {
79
+ return this;
80
+ }
81
+ willUpdate() {
82
+ this.className = [...this.initialClasses, 'btu-tab'].filter(Boolean).join(' ');
83
+ }
84
+ firstUpdated() {
85
+ this.emit('btu-tab-ready');
86
+ }
87
+ /** @internal */
88
+ handleClick() {
89
+ if (this.disabled || !this.name)
90
+ return;
91
+ this.emit('btu-tab-change', { name: this.name });
92
+ }
93
+ render() {
94
+ const iconTemplate = this.iconName
95
+ ? html `<btu-icon symbol="${this.iconName}" size="${this.size === 'lg' ? 'md' : 'sm'}"></btu-icon>`
96
+ : nothing;
97
+ const labelTemplate = this.iconOnly && this.iconName ? nothing : html `<span>${this.label}</span>`;
98
+ const badgeTemplate = this.badge != null ? html `<btu-badge size="sm">${this.badge}</btu-badge>` : nothing;
99
+ const errorDot = this.error ? html `<btu-badge size="sm" variant="error">!</btu-badge>` : nothing;
100
+ const indicator = this._active && !this.disabled
101
+ ? html `<span
102
+ class="btu-tab-indicator"
103
+ style=${styleMap(this.error ? { background: 'oklch(var(--btu-theme-error-600))' } : {})}
104
+ ></span>`
105
+ : nothing;
106
+ return html `<button
107
+ type="button"
108
+ role="tab"
109
+ class="btu-tab-button btu-tab-button-${this.size}"
110
+ aria-selected="${this._active}"
111
+ aria-disabled="${this.disabled || nothing}"
112
+ aria-description="${this.description || nothing}"
113
+ aria-label="${this.iconOnly && this.label ? this.label : nothing}"
114
+ tabindex="${this._tabindex}"
115
+ @click=${this.handleClick}
116
+ >
117
+ ${this.iconPosition === 'leading' ? iconTemplate : nothing} ${labelTemplate}
118
+ ${this.iconPosition === 'trailing' ? iconTemplate : nothing} ${badgeTemplate} ${errorDot} ${indicator}
119
+ </button>`;
120
+ }
121
+ }
122
+ __decorate([
123
+ property({ type: String, attribute: 'name', reflect: true })
124
+ ], Tab.prototype, "name", void 0);
125
+ __decorate([
126
+ property({ type: String })
127
+ ], Tab.prototype, "label", void 0);
128
+ __decorate([
129
+ property({ type: String })
130
+ ], Tab.prototype, "description", void 0);
131
+ __decorate([
132
+ property({ type: Boolean, reflect: true })
133
+ ], Tab.prototype, "disabled", void 0);
134
+ __decorate([
135
+ property({ type: String, attribute: 'icon-name' })
136
+ ], Tab.prototype, "iconName", void 0);
137
+ __decorate([
138
+ property({ type: String, attribute: 'icon-position' })
139
+ ], Tab.prototype, "iconPosition", void 0);
140
+ __decorate([
141
+ property({ type: Boolean, attribute: 'icon-only' })
142
+ ], Tab.prototype, "iconOnly", void 0);
143
+ __decorate([
144
+ property({ type: Boolean, attribute: 'error' })
145
+ ], Tab.prototype, "error", void 0);
146
+ __decorate([
147
+ property({ attribute: 'badge' })
148
+ ], Tab.prototype, "badge", void 0);
149
+ if (!customElements.get('btu-tab')) {
150
+ customElements.define('btu-tab', Tab);
151
+ }
152
+ //# sourceMappingURL=Tab.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Tab.js","sourceRoot":"","sources":["../../../src/components/tabs/Tab.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,126 @@
1
+ import { LitElement } from 'lit';
2
+ import '../badge/Badge.js';
3
+ import '../dropdown/Dropdown.js';
4
+ import '../dropdown/DropdownItem.js';
5
+ import '../dropdown/DropdownMenu.js';
6
+ import '../icon/Icon.js';
7
+ export interface TabsProps {
8
+ size?: 'xs' | 'sm' | 'md' | 'lg';
9
+ activeTab?: string;
10
+ variant?: 'full' | 'menu';
11
+ }
12
+ declare const Tabs_base: (new (...args: any[]) => import("../../util/RovingTabindexMixin.js").RovingTabindexInterface) & (new (...args: any[]) => import("../../util/EventEmitterMixin.js").EventEmitterMixinInterface) & (new (...args: any[]) => import("../../util/ReadyMixin.js").ReadyMixinInterface) & typeof LitElement;
13
+ /**
14
+ * A container component for managing a group of tabs.
15
+ *
16
+ * Provides selection state management, size propagation to child tabs,
17
+ * and keyboard navigation following the WAI-ARIA Tabs pattern.
18
+ *
19
+ * When a tab becomes active, direct sibling elements that share the same
20
+ * `name` value are shown; other siblings with a `name` attribute are
21
+ * hidden. Only direct siblings are managed — nested tab groups control their
22
+ * own panels independently.
23
+ *
24
+ * @element btu-tabs
25
+ *
26
+ * @fires {CustomEvent} btu-tabs-ready - Fired after first render and initialization
27
+ * @fires {CustomEvent<{name: string}>} btu-tabs-show - Fired when a tab becomes active
28
+ * @fires {CustomEvent<{name: string}>} btu-tabs-hide - Fired when a tab is deactivated
29
+ * @fires {CustomEvent<{name: string}>} btu-tab-change - Fired when a tab is selected (bubbles from btu-tab)
30
+ * @fires {CustomEvent} btu-tab-ready - Fired when a child tab finishes initialization (bubbles from btu-tab)
31
+ *
32
+ * @cssprop --tabs-active-color - Text and icon color of the active tab (default: gray-700)
33
+ * @cssprop --tabs-active-indicator-color - Color of the active tab underline indicator (default: primary-500 → primary-700 → primary-900 gradient)
34
+ * @cssprop --tabs-border-color - Color of the bottom border divider (default: gray-200)
35
+ * @cssprop --tabs-color - Text and icon color for all tabs (default: gray-500; active/hover tabs use gray-700)
36
+ * @cssprop --tabs-background - Background color for all tab buttons (default: transparent)
37
+ * @cssprop --tabs-container-background - Background color of the tabs container (default: theme white)
38
+ * @cssprop --tabs-hover-background - Background color of a tab on hover (default: gray-100)
39
+ * @cssprop --tabs-hover-color - Text and icon color of a tab on hover (default: gray-700)
40
+ * @cssprop --tabs-gap - Spacing between tabs (default: 1rem)
41
+ *
42
+ * @example
43
+ * ```html
44
+ * <div>
45
+ * <btu-tabs size="md" active-tab="main">
46
+ * <btu-tab name="main" label="Main"></btu-tab>
47
+ * <btu-tab name="seo" label="SEO"></btu-tab>
48
+ * <btu-tab name="overrides" label="Overrides"></btu-tab>
49
+ * </btu-tabs>
50
+ * <div name="main" role="tabpanel">Main content</div>
51
+ * <div name="seo" role="tabpanel">SEO content</div>
52
+ * <div name="overrides" role="tabpanel">Overrides content</div>
53
+ * </div>
54
+ * ```
55
+ */
56
+ export default class Tabs extends Tabs_base {
57
+ static get tagName(): string;
58
+ /**
59
+ * Size variant applied to all child tabs.
60
+ * @attr
61
+ */
62
+ size: 'xs' | 'sm' | 'md' | 'lg';
63
+ /**
64
+ * The `name` value of the currently active tab.
65
+ * @attr active-tab
66
+ */
67
+ activeTab?: string;
68
+ /**
69
+ * Layout variant.
70
+ * - 'full': tabs scroll horizontally when they overflow (default)
71
+ * - 'menu': all tabs are hidden; the active tab label and a chevron dropdown are shown instead
72
+ * @attr variant
73
+ */
74
+ variant: 'full' | 'menu';
75
+ /** @internal */
76
+ private initialClasses;
77
+ /** @internal Bound event handler for cleanup */
78
+ private boundHandleTabChange;
79
+ /** @internal Bound event handler for cleanup */
80
+ private boundHandleKeyDown;
81
+ /** @internal */
82
+ _getRovingTargets(): HTMLElement[];
83
+ /** @internal Menu variant state */
84
+ private rafId;
85
+ private menuWrapper;
86
+ private menuDropdown;
87
+ private menuLabel;
88
+ private menuIcon;
89
+ private menuErrorBadge;
90
+ connectedCallback(): void;
91
+ disconnectedCallback(): void;
92
+ createRenderRoot(): this;
93
+ willUpdate(): void;
94
+ firstUpdated(): void;
95
+ updated(changedProperties: Map<string, unknown>): void;
96
+ /** @internal Tear down a variant's DOM and state before switching to another */
97
+ private teardownVariant;
98
+ /** @internal */
99
+ private syncTabs;
100
+ /** @internal Show/hide panel elements that are direct siblings with a matching name value */
101
+ private syncPanels;
102
+ /** @internal */
103
+ private getTabs;
104
+ /** @internal */
105
+ private activateTab;
106
+ /** @internal */
107
+ private handleTabChange;
108
+ /** @internal Keyboard navigation following WAI-ARIA Tabs pattern */
109
+ private handleKeyDown;
110
+ /** @internal */
111
+ private tabSizeToDropdownSize;
112
+ /** @internal */
113
+ private initMenu;
114
+ /** @internal */
115
+ private updateMenuItems;
116
+ /** @internal */
117
+ private syncMenuState;
118
+ render(): import("lit-html").TemplateResult<1>;
119
+ }
120
+ declare global {
121
+ interface HTMLElementTagNameMap {
122
+ 'btu-tabs': Tabs;
123
+ }
124
+ }
125
+ export {};
126
+ //# sourceMappingURL=Tabs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Tabs.d.ts","sourceRoot":"","sources":["../../../src/components/tabs/Tabs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAQ,MAAM,KAAK,CAAA;AAKtC,OAAO,mBAAmB,CAAA;AAC1B,OAAO,yBAAyB,CAAA;AAEhC,OAAO,6BAA6B,CAAA;AAEpC,OAAO,6BAA6B,CAAA;AAEpC,OAAO,iBAAiB,CAAA;AAGxB,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;IAChC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CAC1B;;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,SAA8D;IAC9F,MAAM,KAAK,OAAO,WAEjB;IAED;;;OAGG;IAEH,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAO;IAEtC;;;OAGG;IAEH,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB;;;;;OAKG;IAEH,OAAO,EAAE,MAAM,GAAG,MAAM,CAAS;IAEjC,gBAAgB;IAChB,OAAO,CAAC,cAAc,CAAe;IAErC,gDAAgD;IAChD,OAAO,CAAC,oBAAoB,CAAkC;IAC9D,gDAAgD;IAChD,OAAO,CAAC,kBAAkB,CAAgC;IAE1D,gBAAgB;IAChB,iBAAiB,IAAI,WAAW,EAAE;IAUlC,mCAAmC;IACnC,OAAO,CAAC,KAAK,CAAsB;IACnC,OAAO,CAAC,WAAW,CAA2B;IAC9C,OAAO,CAAC,YAAY,CAAwB;IAC5C,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,QAAQ,CAA2B;IAC3C,OAAO,CAAC,cAAc,CAA2B;IAEjD,iBAAiB,IAAI,IAAI;IAUzB,oBAAoB,IAAI,IAAI;IAU5B,gBAAgB;IAIhB,UAAU,IAAI,IAAI;IAWlB,YAAY,IAAI,IAAI;IAcpB,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAoBtD,gFAAgF;IAChF,OAAO,CAAC,eAAe;IAYvB,gBAAgB;IAChB,OAAO,CAAC,QAAQ;IAYhB,6FAA6F;IAC7F,OAAO,CAAC,UAAU;IAWlB,gBAAgB;IAChB,OAAO,CAAC,OAAO;IAIf,gBAAgB;IAChB,OAAO,CAAC,WAAW;IAsBnB,gBAAgB;IAChB,OAAO,CAAC,eAAe;IAIvB,oEAAoE;IACpE,OAAO,CAAC,aAAa;IAuBrB,gBAAgB;IAChB,OAAO,CAAC,qBAAqB;IAM7B,gBAAgB;IAChB,OAAO,CAAC,QAAQ;IA+DhB,gBAAgB;IAChB,OAAO,CAAC,eAAe;IAsBvB,gBAAgB;IAChB,OAAO,CAAC,aAAa;IA4BrB,MAAM;CAGP;AAMD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,UAAU,EAAE,IAAI,CAAA;KACjB;CACF"}
@@ -0,0 +1,390 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { LitElement, html } from 'lit';
8
+ import { property } from 'lit/decorators.js';
9
+ import { EventEmitterMixin } from '../../util/EventEmitterMixin.js';
10
+ import { ReadyMixin } from '../../util/ReadyMixin.js';
11
+ import { RovingTabindexMixin } from '../../util/RovingTabindexMixin.js';
12
+ import '../badge/Badge.js';
13
+ import '../dropdown/Dropdown.js';
14
+ import '../dropdown/DropdownItem.js';
15
+ import '../dropdown/DropdownMenu.js';
16
+ import '../icon/Icon.js';
17
+ /**
18
+ * A container component for managing a group of tabs.
19
+ *
20
+ * Provides selection state management, size propagation to child tabs,
21
+ * and keyboard navigation following the WAI-ARIA Tabs pattern.
22
+ *
23
+ * When a tab becomes active, direct sibling elements that share the same
24
+ * `name` value are shown; other siblings with a `name` attribute are
25
+ * hidden. Only direct siblings are managed — nested tab groups control their
26
+ * own panels independently.
27
+ *
28
+ * @element btu-tabs
29
+ *
30
+ * @fires {CustomEvent} btu-tabs-ready - Fired after first render and initialization
31
+ * @fires {CustomEvent<{name: string}>} btu-tabs-show - Fired when a tab becomes active
32
+ * @fires {CustomEvent<{name: string}>} btu-tabs-hide - Fired when a tab is deactivated
33
+ * @fires {CustomEvent<{name: string}>} btu-tab-change - Fired when a tab is selected (bubbles from btu-tab)
34
+ * @fires {CustomEvent} btu-tab-ready - Fired when a child tab finishes initialization (bubbles from btu-tab)
35
+ *
36
+ * @cssprop --tabs-active-color - Text and icon color of the active tab (default: gray-700)
37
+ * @cssprop --tabs-active-indicator-color - Color of the active tab underline indicator (default: primary-500 → primary-700 → primary-900 gradient)
38
+ * @cssprop --tabs-border-color - Color of the bottom border divider (default: gray-200)
39
+ * @cssprop --tabs-color - Text and icon color for all tabs (default: gray-500; active/hover tabs use gray-700)
40
+ * @cssprop --tabs-background - Background color for all tab buttons (default: transparent)
41
+ * @cssprop --tabs-container-background - Background color of the tabs container (default: theme white)
42
+ * @cssprop --tabs-hover-background - Background color of a tab on hover (default: gray-100)
43
+ * @cssprop --tabs-hover-color - Text and icon color of a tab on hover (default: gray-700)
44
+ * @cssprop --tabs-gap - Spacing between tabs (default: 1rem)
45
+ *
46
+ * @example
47
+ * ```html
48
+ * <div>
49
+ * <btu-tabs size="md" active-tab="main">
50
+ * <btu-tab name="main" label="Main"></btu-tab>
51
+ * <btu-tab name="seo" label="SEO"></btu-tab>
52
+ * <btu-tab name="overrides" label="Overrides"></btu-tab>
53
+ * </btu-tabs>
54
+ * <div name="main" role="tabpanel">Main content</div>
55
+ * <div name="seo" role="tabpanel">SEO content</div>
56
+ * <div name="overrides" role="tabpanel">Overrides content</div>
57
+ * </div>
58
+ * ```
59
+ */
60
+ export default class Tabs extends RovingTabindexMixin(EventEmitterMixin(ReadyMixin(LitElement))) {
61
+ constructor() {
62
+ super(...arguments);
63
+ /**
64
+ * Size variant applied to all child tabs.
65
+ * @attr
66
+ */
67
+ this.size = 'md';
68
+ /**
69
+ * Layout variant.
70
+ * - 'full': tabs scroll horizontally when they overflow (default)
71
+ * - 'menu': all tabs are hidden; the active tab label and a chevron dropdown are shown instead
72
+ * @attr variant
73
+ */
74
+ this.variant = 'full';
75
+ /** @internal */
76
+ this.initialClasses = [];
77
+ /** @internal Bound event handler for cleanup */
78
+ this.boundHandleTabChange = this.handleTabChange.bind(this);
79
+ /** @internal Bound event handler for cleanup */
80
+ this.boundHandleKeyDown = this.handleKeyDown.bind(this);
81
+ /** @internal Menu variant state */
82
+ this.rafId = null;
83
+ this.menuWrapper = null;
84
+ this.menuDropdown = null;
85
+ this.menuLabel = null;
86
+ this.menuIcon = null;
87
+ this.menuErrorBadge = null;
88
+ }
89
+ static get tagName() {
90
+ return 'BTU-TABS';
91
+ }
92
+ /** @internal */
93
+ _getRovingTargets() {
94
+ const buttons = [];
95
+ for (const tab of this.getTabs()) {
96
+ if (tab.style.display === 'none')
97
+ continue;
98
+ const btn = tab.querySelector('button');
99
+ if (btn)
100
+ buttons.push(btn);
101
+ }
102
+ return buttons;
103
+ }
104
+ connectedCallback() {
105
+ super.connectedCallback();
106
+ if (this.className) {
107
+ this.initialClasses = this.className.split(' ').filter(c => c.trim());
108
+ }
109
+ this.setAttribute('role', 'tablist');
110
+ this.addEventListener('btu-tab-change', this.boundHandleTabChange);
111
+ this.addEventListener('keydown', this.boundHandleKeyDown);
112
+ }
113
+ disconnectedCallback() {
114
+ super.disconnectedCallback();
115
+ if (this.rafId) {
116
+ cancelAnimationFrame(this.rafId);
117
+ this.rafId = null;
118
+ }
119
+ this.removeEventListener('btu-tab-change', this.boundHandleTabChange);
120
+ this.removeEventListener('keydown', this.boundHandleKeyDown);
121
+ }
122
+ createRenderRoot() {
123
+ return this;
124
+ }
125
+ willUpdate() {
126
+ this.className = [
127
+ ...this.initialClasses,
128
+ 'btu-tabs',
129
+ `btu-tabs-${this.size}`,
130
+ this.variant === 'menu' ? 'btu-tabs-menu-mode' : '',
131
+ ]
132
+ .filter(Boolean)
133
+ .join(' ');
134
+ }
135
+ firstUpdated() {
136
+ if (!this.activeTab) {
137
+ const firstEnabled = this.getTabs().find(t => !t.disabled);
138
+ if (firstEnabled)
139
+ this.activeTab = firstEnabled.name;
140
+ }
141
+ this.syncTabs();
142
+ this.syncPanels();
143
+ if (this.variant === 'menu') {
144
+ this.initMenu();
145
+ }
146
+ else {
147
+ this.emit('btu-tabs-ready');
148
+ }
149
+ }
150
+ updated(changedProperties) {
151
+ if (changedProperties.has('activeTab') && !this.activeTab) {
152
+ const firstEnabled = this.getTabs().find(t => !t.disabled);
153
+ if (firstEnabled)
154
+ this.activeTab = firstEnabled.name;
155
+ }
156
+ if (changedProperties.has('activeTab') || changedProperties.has('size')) {
157
+ this.syncTabs();
158
+ }
159
+ if (changedProperties.has('activeTab')) {
160
+ this.syncPanels();
161
+ }
162
+ if (changedProperties.has('size') && this.menuDropdown) {
163
+ this.menuDropdown.size = this.tabSizeToDropdownSize(this.size);
164
+ }
165
+ if (changedProperties.has('variant') && changedProperties.get('variant') !== undefined) {
166
+ this.teardownVariant(changedProperties.get('variant'));
167
+ if (this.variant === 'menu')
168
+ this.initMenu();
169
+ }
170
+ }
171
+ /** @internal Tear down a variant's DOM and state before switching to another */
172
+ teardownVariant(previous) {
173
+ if (previous === 'menu') {
174
+ this.menuWrapper?.remove();
175
+ this.menuWrapper = null;
176
+ this.menuDropdown = null;
177
+ this.menuLabel = null;
178
+ this.menuIcon = null;
179
+ this.menuErrorBadge = null;
180
+ this.getTabs().forEach(tab => tab.style.removeProperty('display'));
181
+ }
182
+ }
183
+ /** @internal */
184
+ syncTabs() {
185
+ this.getTabs().forEach(tab => {
186
+ tab.size = this.size;
187
+ tab._active = tab.name === this.activeTab;
188
+ tab._tabindex = tab.name === this.activeTab ? 0 : -1;
189
+ tab.requestUpdate();
190
+ });
191
+ if (this.variant === 'menu') {
192
+ this.syncMenuState();
193
+ }
194
+ }
195
+ /** @internal Show/hide panel elements that are direct siblings with a matching name value */
196
+ syncPanels() {
197
+ if (!this.activeTab || !this.parentElement)
198
+ return;
199
+ Array.from(this.parentElement.children).forEach(child => {
200
+ if (child === this || !(child instanceof HTMLElement))
201
+ return;
202
+ // data-tab is a deprecated fallback for compat — use name instead
203
+ const panelName = child.getAttribute('name') ?? child.dataset.tab;
204
+ if (!panelName)
205
+ return;
206
+ child.hidden = panelName !== this.activeTab;
207
+ });
208
+ }
209
+ /** @internal */
210
+ getTabs() {
211
+ return Array.from(this.querySelectorAll('btu-tab'));
212
+ }
213
+ /** @internal */
214
+ activateTab(name) {
215
+ const newTab = this.getTabs().find(t => t.name === name);
216
+ if (!newTab || newTab.disabled) {
217
+ const available = this.getTabs()
218
+ .map(t => t.name)
219
+ .filter(Boolean);
220
+ console.warn(`[btu-tabs] Tab "${name}" not found or is disabled. Available tabs: ${available.join(', ')}`);
221
+ return;
222
+ }
223
+ if (name === this.activeTab)
224
+ return;
225
+ const oldName = this.activeTab;
226
+ if (oldName) {
227
+ this.emit('btu-tabs-hide', { name: oldName });
228
+ }
229
+ this.activeTab = name;
230
+ this.emit('btu-tabs-show', { name });
231
+ this.syncTabs();
232
+ this.syncPanels();
233
+ }
234
+ /** @internal */
235
+ handleTabChange(event) {
236
+ this.activateTab(event.detail.name);
237
+ }
238
+ /** @internal Keyboard navigation following WAI-ARIA Tabs pattern */
239
+ handleKeyDown(event) {
240
+ switch (event.key) {
241
+ case 'ArrowRight':
242
+ event.preventDefault();
243
+ this._rovingNext();
244
+ break;
245
+ case 'ArrowLeft':
246
+ event.preventDefault();
247
+ this._rovingPrev();
248
+ break;
249
+ case 'Home':
250
+ event.preventDefault();
251
+ this._rovingFirst();
252
+ break;
253
+ case 'End':
254
+ event.preventDefault();
255
+ this._rovingLast();
256
+ break;
257
+ }
258
+ }
259
+ // ─── Menu variant ────────────────────────────────────────────────────────────
260
+ /** @internal */
261
+ tabSizeToDropdownSize(size) {
262
+ if (size === 'xs' || size === 'sm')
263
+ return 'small';
264
+ if (size === 'lg')
265
+ return 'large';
266
+ return 'medium';
267
+ }
268
+ /** @internal */
269
+ initMenu() {
270
+ // Hide all tab buttons — they're only accessible via the dropdown
271
+ this.getTabs().forEach(tab => (tab.style.display = 'none'));
272
+ const activeTab = this.getTabs().find(t => t.name === this.activeTab);
273
+ this.menuWrapper = document.createElement('div');
274
+ const wrapper = this.menuWrapper;
275
+ wrapper.className = 'btu-tab-menu-wrapper';
276
+ this.menuIcon = document.createElement('btu-icon');
277
+ this.menuIcon.setAttribute('size', this.size === 'lg' ? 'md' : 'sm');
278
+ this.menuIcon.setAttribute('symbol', activeTab?.iconName ?? '');
279
+ this.menuIcon.hidden = !activeTab?.iconName;
280
+ this.menuLabel = document.createElement('span');
281
+ this.menuLabel.className = 'btu-tab-menu-label';
282
+ this.menuLabel.textContent = activeTab?.label ?? '';
283
+ if (activeTab?.iconPosition === 'trailing') {
284
+ wrapper.appendChild(this.menuLabel);
285
+ wrapper.appendChild(this.menuIcon);
286
+ }
287
+ else {
288
+ wrapper.appendChild(this.menuIcon);
289
+ wrapper.appendChild(this.menuLabel);
290
+ }
291
+ this.menuErrorBadge = document.createElement('btu-badge');
292
+ this.menuErrorBadge.setAttribute('size', 'sm');
293
+ this.menuErrorBadge.setAttribute('variant', 'error');
294
+ this.menuErrorBadge.textContent = '!';
295
+ this.menuErrorBadge.hidden = !activeTab?.error;
296
+ wrapper.appendChild(this.menuErrorBadge);
297
+ const dropdownMenu = document.createElement('btu-dropdown-menu');
298
+ this.menuDropdown = document.createElement('btu-dropdown');
299
+ this.menuDropdown.label = 'Tabs';
300
+ this.menuDropdown.iconOnly = true;
301
+ this.menuDropdown.noChevron = false;
302
+ this.menuDropdown.variant = 'tertiary';
303
+ this.menuDropdown.placement = 'bottom-start';
304
+ this.menuDropdown.size = this.tabSizeToDropdownSize(this.size);
305
+ this.menuDropdown.appendChild(dropdownMenu);
306
+ this.menuDropdown.addEventListener('btu-dropdown-item-select', (e) => {
307
+ e.stopPropagation();
308
+ const item = e.target.closest('btu-dropdown-item');
309
+ const name = item?.dataset.name;
310
+ if (name)
311
+ this.activateTab(name);
312
+ });
313
+ wrapper.appendChild(this.menuDropdown);
314
+ this.appendChild(wrapper);
315
+ // Defer population to allow btu-dropdown to finish its firstUpdated lifecycle
316
+ this.rafId = requestAnimationFrame(() => {
317
+ this.rafId = null;
318
+ this.updateMenuItems();
319
+ this.emit('btu-tabs-ready');
320
+ });
321
+ }
322
+ /** @internal */
323
+ updateMenuItems() {
324
+ if (!this.isConnected)
325
+ return;
326
+ const menu = this.menuDropdown?.querySelector('btu-dropdown-menu');
327
+ if (!menu)
328
+ return;
329
+ menu.innerHTML = '';
330
+ const tabs = this.getTabs();
331
+ const hasIcons = tabs.some(t => !!t.iconName);
332
+ tabs.forEach(tab => {
333
+ const item = document.createElement('btu-dropdown-item');
334
+ item.dataset.name = tab.name ?? '';
335
+ item.label = tab.label ?? tab.name ?? '';
336
+ item.selected = tab.name === this.activeTab;
337
+ item.disabled = tab.disabled;
338
+ item.error = tab.error;
339
+ if (tab.iconName)
340
+ item.iconSymbol = tab.iconName;
341
+ menu.appendChild(item);
342
+ item._configure({ checkbox: false, icon: hasIcons, iconSymbol: '', favorites: false, shortcuts: false });
343
+ });
344
+ }
345
+ /** @internal */
346
+ syncMenuState() {
347
+ const activeTab = this.getTabs().find(t => t.name === this.activeTab);
348
+ if (this.menuLabel) {
349
+ this.menuLabel.textContent = activeTab?.label ?? '';
350
+ }
351
+ if (this.menuIcon) {
352
+ const symbol = activeTab?.iconName ?? '';
353
+ this.menuIcon.setAttribute('symbol', symbol);
354
+ this.menuIcon.setAttribute('size', this.size === 'lg' ? 'md' : 'sm');
355
+ this.menuIcon.hidden = !symbol;
356
+ // Reposition if icon-position changed
357
+ const wrapper = this.menuIcon.parentElement;
358
+ if (wrapper && this.menuLabel) {
359
+ if (activeTab?.iconPosition === 'trailing') {
360
+ wrapper.insertBefore(this.menuIcon, this.menuErrorBadge);
361
+ }
362
+ else {
363
+ wrapper.insertBefore(this.menuIcon, this.menuLabel);
364
+ }
365
+ }
366
+ }
367
+ if (this.menuErrorBadge) {
368
+ this.menuErrorBadge.hidden = !activeTab?.error;
369
+ }
370
+ this.menuDropdown?.querySelectorAll('btu-dropdown-item').forEach(item => {
371
+ item.selected = item.dataset.name === this.activeTab;
372
+ });
373
+ }
374
+ render() {
375
+ return html ``;
376
+ }
377
+ }
378
+ __decorate([
379
+ property({ type: String })
380
+ ], Tabs.prototype, "size", void 0);
381
+ __decorate([
382
+ property({ type: String, attribute: 'active-tab' })
383
+ ], Tabs.prototype, "activeTab", void 0);
384
+ __decorate([
385
+ property({ type: String })
386
+ ], Tabs.prototype, "variant", void 0);
387
+ if (!customElements.get('btu-tabs')) {
388
+ customElements.define('btu-tabs', Tabs);
389
+ }
390
+ //# sourceMappingURL=Tabs.js.map