@haiilo/catalyst 6.5.0 → 6.5.2

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.
@@ -1,4 +1,4 @@
1
- import { proxyCustomElement, HTMLElement, h, Host } from '@stencil/core/internal/client';
1
+ import { proxyCustomElement, HTMLElement, createEvent, h, Host } from '@stencil/core/internal/client';
2
2
  import { d as defineCustomElement$4 } from './cat-button2.js';
3
3
  import { d as defineCustomElement$3 } from './cat-icon2.js';
4
4
  import { d as defineCustomElement$2 } from './cat-spinner2.js';
@@ -10,21 +10,13 @@ const CatTabs$1 = /*@__PURE__*/ proxyCustomElement(class CatTabs extends HTMLEle
10
10
  super();
11
11
  this.__registerHost();
12
12
  this.__attachShadow();
13
- this.buttons = [];
13
+ this.catChange = createEvent(this, "catChange", 7);
14
14
  this.tabs = [];
15
- this.activeTabId = undefined;
16
15
  this.activeTab = '';
17
16
  this.tabsAlign = 'left';
18
17
  }
19
- onActiveTabIdChanged(newActiveTab) {
20
- const activeTab = this.tabs.find(value => value.id === newActiveTab);
21
- activeTab?.click();
22
- }
23
18
  componentWillLoad() {
24
19
  this.syncTabs();
25
- if (this.tabs.length) {
26
- this.activeTabId = this.activeTab;
27
- }
28
20
  }
29
21
  componentDidLoad() {
30
22
  this.mutationObserver = new MutationObserver(mutations => mutations.some(value => value.target.nodeName === 'CAT-TAB') && this.syncTabs());
@@ -37,9 +29,14 @@ const CatTabs$1 = /*@__PURE__*/ proxyCustomElement(class CatTabs extends HTMLEle
37
29
  disconnectedCallback() {
38
30
  this.mutationObserver?.disconnect();
39
31
  }
32
+ onActiveTabChange(id) {
33
+ const index = this.tabs.findIndex(tab => tab.id === id);
34
+ this.catChange.emit({ id, index });
35
+ }
40
36
  onKeydown(event) {
41
37
  if (['ArrowDown', 'ArrowUp', 'ArrowRight', 'ArrowLeft'].includes(event.key)) {
42
- const targetElements = this.buttons.filter(button => !button.disabled);
38
+ const elements = this.hostElement.shadowRoot?.querySelectorAll('cat-button[role="tab"]');
39
+ const targetElements = Array.from(elements || []).filter(button => !button.disabled);
43
40
  const activeElement = this.hostElement.shadowRoot?.activeElement;
44
41
  const activeIdx = activeElement ? targetElements.indexOf(activeElement) : -1;
45
42
  const activeOff = ['ArrowDown', 'ArrowRight'].includes(event.key) ? 1 : -1;
@@ -48,38 +45,55 @@ const CatTabs$1 = /*@__PURE__*/ proxyCustomElement(class CatTabs extends HTMLEle
48
45
  event.preventDefault();
49
46
  }
50
47
  }
48
+ /**
49
+ * Activates the tab with the given id.
50
+ *
51
+ * @param id The tab id.
52
+ */
53
+ async setActive(id) {
54
+ this.activate(this.tabs.find(tab => tab.id === id));
55
+ }
56
+ /**
57
+ * Activates the tab with the given index.
58
+ *
59
+ * @param index The tab index.
60
+ */
61
+ async setActiveIndex(index) {
62
+ this.activate(this.tabs[index]);
63
+ }
51
64
  render() {
52
65
  return (h(Host, null, this.tabs.map((tab) => {
53
- return (h("cat-button", { ref: el => el && this.updateButtonsRef(el), buttonId: tab.id, role: "tab", part: "tab", class: {
66
+ return (h("cat-button", { buttonId: tab.id, role: "tab", part: "tab", class: {
54
67
  'cat-tab': true,
55
- 'cat-tab-active': Boolean(this.activeTabId && tab.id === this.activeTabId)
56
- }, active: Boolean(this.activeTabId && tab.id === this.activeTabId), color: this.activeTabId && tab.id === this.activeTabId ? 'primary' : 'secondary', variant: "text", icon: tab.icon, iconOnly: tab.iconOnly, iconRight: tab.iconRight, url: tab.url, disabled: tab.deactivated, urlTarget: tab.urlTarget, onCatClick: () => (this.activeTabId = tab.id), nativeAttributes: { ...tab.nativeAttributes }, nativeContentAttributes: { 'data-text': tab.label }, "data-dropdown-no-close": true }, tab.label));
68
+ 'cat-tab-active': tab.id === this.activeTab
69
+ }, active: tab.id === this.activeTab, color: tab.id === this.activeTab ? 'primary' : 'secondary', variant: "text", icon: tab.icon, iconOnly: tab.iconOnly, iconRight: tab.iconRight, url: tab.url, disabled: tab.deactivated, urlTarget: tab.urlTarget, onCatClick: () => this.activate(tab), nativeAttributes: { ...tab.nativeAttributes }, nativeContentAttributes: { 'data-text': tab.label }, "data-dropdown-no-close": true }, tab.label));
57
70
  })));
58
71
  }
59
- updateButtonsRef(button) {
60
- const indexOf = this.buttons.indexOf(button);
61
- if (indexOf >= 0) {
62
- this.buttons[indexOf] = button;
63
- }
64
- else {
65
- this.buttons.push(button);
66
- }
67
- }
68
72
  syncTabs() {
69
73
  this.tabs = Array.from(this.hostElement.querySelectorAll('cat-tab'));
74
+ this.activeTab = this.activeTab || this.tabs.filter(tab => this.canActivate(tab))[0]?.id;
75
+ }
76
+ canActivate(tab) {
77
+ return !!tab && !tab.deactivated && !tab.url && tab.id !== this.activeTab;
78
+ }
79
+ activate(tab) {
80
+ if (this.canActivate(tab)) {
81
+ this.activeTab = tab.id;
82
+ }
70
83
  }
71
84
  get hostElement() { return this; }
72
85
  static get watchers() { return {
73
- "activeTabId": ["onActiveTabIdChanged"]
86
+ "activeTab": ["onActiveTabChange"]
74
87
  }; }
75
88
  static get style() { return catTabsCss; }
76
89
  }, [1, "cat-tabs", {
77
- "activeTab": [1, "active-tab"],
90
+ "activeTab": [513, "active-tab"],
78
91
  "tabsAlign": [1, "tabs-align"],
79
92
  "tabs": [32],
80
- "activeTabId": [32]
93
+ "setActive": [64],
94
+ "setActiveIndex": [64]
81
95
  }, [[0, "keydown", "onKeydown"]], {
82
- "activeTabId": ["onActiveTabIdChanged"]
96
+ "activeTab": ["onActiveTabChange"]
83
97
  }]);
84
98
  function defineCustomElement$1() {
85
99
  if (typeof customElements === "undefined") {
@@ -1 +1 @@
1
- {"file":"cat-tabs.js","mappings":"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","names":["CatTabs"],"sources":["src/components/cat-tabs/cat-tabs.scss?tag=cat-tabs&encapsulation=shadow","src/components/cat-tabs/cat-tabs.tsx"],"sourcesContent":["@use 'variables' as *;\n@use 'mixins' as *;\n\n:host {\n display: flex;\n flex-direction: row;\n box-shadow: inset 0 -1px 0 0 cat-token('color.ui.border.default');\n}\n\n:host([hidden]) {\n display: none;\n}\n\n:host([tabs-align='center']) {\n justify-content: center;\n}\n\n:host([tabs-align='right']) {\n justify-content: end;\n}\n\n:host([tabs-align='justify']) {\n cat-button {\n flex: 1 0 auto;\n }\n}\n\n.cat-tab {\n display: inline-flex;\n flex-direction: column;\n align-items: center;\n justify-content: space-between;\n position: relative;\n transition: none;\n\n &:first-of-type {\n margin-left: -0.75rem;\n }\n\n &:last-of-type {\n margin-right: -0.75rem;\n }\n\n &::after {\n opacity: 0;\n content: '';\n position: absolute;\n background: currentColor;\n left: 0.75rem;\n right: 0.75rem;\n bottom: 0;\n height: 2px;\n }\n\n &:hover::after {\n opacity: 0.25;\n }\n\n &.cat-tab-active {\n font-weight: 700;\n color: cat-token('color.theme.primary.textActive');\n }\n\n &.cat-tab-active::after {\n opacity: 1;\n }\n}\n","import { Component, h, Element, State, Watch, Listen, Host, Prop } from '@stencil/core';\n\n/**\n * Tabs are used to display multiple panels to be contained within a single\n * window, using tabs as a navigational element.\n *\n * @part tab - The header of the tab.\n */\n@Component({\n tag: 'cat-tabs',\n styleUrl: 'cat-tabs.scss',\n shadow: true\n})\nexport class CatTabs {\n private buttons: HTMLCatButtonElement[] = [];\n private mutationObserver?: MutationObserver;\n\n @Element() hostElement!: HTMLElement;\n\n @State() tabs: HTMLCatTabElement[] = [];\n\n @State() activeTabId?: string;\n\n /**\n * The ID of the active tab.\n */\n @Prop() activeTab = '';\n\n /**\n * The alignment of the tabs.\n */\n @Prop() tabsAlign: 'left' | 'center' | 'right' | 'justify' = 'left';\n\n @Watch('activeTabId')\n onActiveTabIdChanged(newActiveTab: string): void {\n const activeTab = this.tabs.find(value => value.id === newActiveTab);\n activeTab?.click();\n }\n\n componentWillLoad(): void {\n this.syncTabs();\n if (this.tabs.length) {\n this.activeTabId = this.activeTab;\n }\n }\n\n componentDidLoad() {\n this.mutationObserver = new MutationObserver(\n mutations => mutations.some(value => value.target.nodeName === 'CAT-TAB') && this.syncTabs()\n );\n\n this.mutationObserver?.observe(this.hostElement, {\n childList: true,\n attributes: true,\n subtree: true\n });\n }\n\n disconnectedCallback() {\n this.mutationObserver?.disconnect();\n }\n\n @Listen('keydown')\n onKeydown(event: KeyboardEvent): void {\n if (['ArrowDown', 'ArrowUp', 'ArrowRight', 'ArrowLeft'].includes(event.key)) {\n const targetElements = this.buttons.filter(button => !button.disabled);\n const activeElement = this.hostElement.shadowRoot?.activeElement as HTMLCatButtonElement;\n const activeIdx = activeElement ? targetElements.indexOf(activeElement) : -1;\n const activeOff = ['ArrowDown', 'ArrowRight'].includes(event.key) ? 1 : -1;\n const targetIdx = activeIdx < 0 ? 0 : (activeIdx + activeOff + targetElements.length) % targetElements.length;\n targetElements[targetIdx].doFocus();\n event.preventDefault();\n }\n }\n\n render() {\n return (\n <Host>\n {this.tabs.map((tab: HTMLCatTabElement) => {\n return (\n <cat-button\n ref={el => el && this.updateButtonsRef(el)}\n buttonId={tab.id}\n role=\"tab\"\n part=\"tab\"\n class={{\n 'cat-tab': true,\n 'cat-tab-active': Boolean(this.activeTabId && tab.id === this.activeTabId)\n }}\n active={Boolean(this.activeTabId && tab.id === this.activeTabId)}\n color={this.activeTabId && tab.id === this.activeTabId ? 'primary' : 'secondary'}\n variant=\"text\"\n icon={tab.icon}\n iconOnly={tab.iconOnly}\n iconRight={tab.iconRight}\n url={tab.url}\n disabled={tab.deactivated}\n urlTarget={tab.urlTarget}\n onCatClick={() => (this.activeTabId = tab.id)}\n nativeAttributes={{ ...tab.nativeAttributes }}\n nativeContentAttributes={{ 'data-text': tab.label }}\n data-dropdown-no-close\n >\n {tab.label}\n </cat-button>\n );\n })}\n </Host>\n );\n }\n\n private updateButtonsRef(button: HTMLCatButtonElement) {\n const indexOf = this.buttons.indexOf(button);\n\n if (indexOf >= 0) {\n this.buttons[indexOf] = button;\n } else {\n this.buttons.push(button);\n }\n }\n\n private syncTabs() {\n this.tabs = Array.from(this.hostElement.querySelectorAll('cat-tab'));\n }\n}\n"],"version":3}
1
+ {"file":"cat-tabs.js","mappings":"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","names":["CatTabs"],"sources":["src/components/cat-tabs/cat-tabs.scss?tag=cat-tabs&encapsulation=shadow","src/components/cat-tabs/cat-tabs.tsx"],"sourcesContent":["@use 'variables' as *;\n@use 'mixins' as *;\n\n:host {\n display: flex;\n flex-direction: row;\n box-shadow: inset 0 -1px 0 0 cat-token('color.ui.border.default');\n}\n\n:host([hidden]) {\n display: none;\n}\n\n:host([tabs-align='center']) {\n justify-content: center;\n}\n\n:host([tabs-align='right']) {\n justify-content: end;\n}\n\n:host([tabs-align='justify']) {\n cat-button {\n flex: 1 0 auto;\n }\n}\n\n.cat-tab {\n display: inline-flex;\n flex-direction: column;\n align-items: center;\n justify-content: space-between;\n position: relative;\n transition: none;\n\n &:first-of-type {\n margin-left: -0.75rem;\n }\n\n &:last-of-type {\n margin-right: -0.75rem;\n }\n\n &::after {\n opacity: 0;\n content: '';\n position: absolute;\n background: currentColor;\n left: 0.75rem;\n right: 0.75rem;\n bottom: 0;\n height: 2px;\n }\n\n &:hover::after {\n opacity: 0.25;\n }\n\n &.cat-tab-active {\n font-weight: 700;\n color: cat-token('color.theme.primary.textActive');\n }\n\n &.cat-tab-active::after {\n opacity: 1;\n }\n}\n","import { Component, Element, Event, EventEmitter, Host, Listen, Method, Prop, State, Watch, h } from '@stencil/core';\n\n/**\n * Tabs are used to display multiple panels to be contained within a single\n * window, using tabs as a navigational element.\n *\n * @part tab - The header of the tab.\n */\n@Component({\n tag: 'cat-tabs',\n styleUrl: 'cat-tabs.scss',\n shadow: true\n})\nexport class CatTabs {\n private mutationObserver?: MutationObserver;\n\n @Element() hostElement!: HTMLElement;\n\n @State() tabs: HTMLCatTabElement[] = [];\n\n /**\n * The ID of the active tab.\n */\n @Prop({ reflect: true }) activeTab = '';\n\n /**\n * The alignment of the tabs.\n */\n @Prop() tabsAlign: 'left' | 'center' | 'right' | 'justify' = 'left';\n\n componentWillLoad(): void {\n this.syncTabs();\n }\n\n componentDidLoad() {\n this.mutationObserver = new MutationObserver(\n mutations => mutations.some(value => value.target.nodeName === 'CAT-TAB') && this.syncTabs()\n );\n this.mutationObserver?.observe(this.hostElement, {\n childList: true,\n attributes: true,\n subtree: true\n });\n }\n\n disconnectedCallback() {\n this.mutationObserver?.disconnect();\n }\n\n @Watch('activeTab')\n onActiveTabChange(id: string) {\n const index = this.tabs.findIndex(tab => tab.id === id);\n this.catChange.emit({ id, index });\n }\n\n @Listen('keydown')\n onKeydown(event: KeyboardEvent): void {\n if (['ArrowDown', 'ArrowUp', 'ArrowRight', 'ArrowLeft'].includes(event.key)) {\n const elements = this.hostElement.shadowRoot?.querySelectorAll<HTMLCatButtonElement>('cat-button[role=\"tab\"]');\n const targetElements = Array.from(elements || []).filter(button => !button.disabled);\n const activeElement = this.hostElement.shadowRoot?.activeElement as HTMLCatButtonElement;\n const activeIdx = activeElement ? targetElements.indexOf(activeElement) : -1;\n const activeOff = ['ArrowDown', 'ArrowRight'].includes(event.key) ? 1 : -1;\n const targetIdx = activeIdx < 0 ? 0 : (activeIdx + activeOff + targetElements.length) % targetElements.length;\n targetElements[targetIdx].doFocus();\n event.preventDefault();\n }\n }\n\n /**\n * Activates the tab with the given id.\n *\n * @param id The tab id.\n */\n @Method()\n async setActive(id: string): Promise<void> {\n this.activate(this.tabs.find(tab => tab.id === id));\n }\n\n /**\n * Activates the tab with the given index.\n *\n * @param index The tab index.\n */\n @Method()\n async setActiveIndex(index: number): Promise<void> {\n this.activate(this.tabs[index]);\n }\n\n /**\n * Emitted when active tab is changed.\n */\n @Event() catChange!: EventEmitter<{ id: string; index: number }>;\n\n render() {\n return (\n <Host>\n {this.tabs.map((tab: HTMLCatTabElement) => {\n return (\n <cat-button\n buttonId={tab.id}\n role=\"tab\"\n part=\"tab\"\n class={{\n 'cat-tab': true,\n 'cat-tab-active': tab.id === this.activeTab\n }}\n active={tab.id === this.activeTab}\n color={tab.id === this.activeTab ? 'primary' : 'secondary'}\n variant=\"text\"\n icon={tab.icon}\n iconOnly={tab.iconOnly}\n iconRight={tab.iconRight}\n url={tab.url}\n disabled={tab.deactivated}\n urlTarget={tab.urlTarget}\n onCatClick={() => this.activate(tab)}\n nativeAttributes={{ ...tab.nativeAttributes }}\n nativeContentAttributes={{ 'data-text': tab.label }}\n data-dropdown-no-close\n >\n {tab.label}\n </cat-button>\n );\n })}\n </Host>\n );\n }\n\n private syncTabs() {\n this.tabs = Array.from(this.hostElement.querySelectorAll('cat-tab'));\n this.activeTab = this.activeTab || this.tabs.filter(tab => this.canActivate(tab))[0]?.id;\n }\n\n private canActivate(tab?: HTMLCatTabElement): tab is HTMLCatTabElement {\n return !!tab && !tab.deactivated && !tab.url && tab.id !== this.activeTab;\n }\n\n private activate(tab?: HTMLCatTabElement) {\n if (this.canActivate(tab)) {\n this.activeTab = tab.id;\n }\n }\n}\n"],"version":3}
@@ -7815,21 +7815,22 @@ const CatRadioGroup = class {
7815
7815
  this.updateTabIndex();
7816
7816
  }
7817
7817
  onDisabledChanged(disabled) {
7818
- this.catRadioGroup.forEach(catRadio => (catRadio.disabled = disabled));
7818
+ this.catRadioGroup.forEach(catRadio => (catRadio.disabled = catRadio.disabled || disabled));
7819
7819
  }
7820
7820
  onLabelLeftChanged(labelLeft) {
7821
- this.catRadioGroup.forEach(catRadio => {
7822
- if (labelLeft) {
7823
- catRadio.labelLeft = labelLeft;
7824
- }
7825
- });
7821
+ this.catRadioGroup.forEach(catRadio => (catRadio.labelLeft = catRadio.labelLeft || labelLeft));
7826
7822
  }
7827
7823
  componentDidLoad() {
7828
- this.catRadioGroup = Array.from(this.hostElement.querySelectorAll(`cat-radio`));
7829
- this.onNameChanged(this.name);
7830
- this.onValueChanged(this.value);
7831
- this.onDisabledChanged(this.disabled);
7832
- this.onLabelLeftChanged(this.labelLeft);
7824
+ this.init();
7825
+ this.mutationObserver = new MutationObserver(mutations => mutations.some(value => value.target.nodeName === 'CAT-RADIO') && this.init());
7826
+ this.mutationObserver?.observe(this.hostElement, {
7827
+ childList: true,
7828
+ attributes: true,
7829
+ subtree: true
7830
+ });
7831
+ }
7832
+ disconnectedCallback() {
7833
+ this.mutationObserver?.disconnect();
7833
7834
  }
7834
7835
  onKeydown(event) {
7835
7836
  if (['ArrowDown', 'ArrowUp', 'ArrowRight', 'ArrowLeft'].includes(event.key) && this.catRadioGroup.length) {
@@ -7864,6 +7865,13 @@ const CatRadioGroup = class {
7864
7865
  render() {
7865
7866
  return (h("div", { role: "radiogroup", "aria-label": this.a11yLabel }, h("slot", null)));
7866
7867
  }
7868
+ init() {
7869
+ this.catRadioGroup = Array.from(this.hostElement.querySelectorAll(`cat-radio`));
7870
+ this.onNameChanged(this.name);
7871
+ this.onValueChanged(this.value);
7872
+ this.onDisabledChanged(this.disabled);
7873
+ this.onLabelLeftChanged(this.labelLeft);
7874
+ }
7867
7875
  updateTabIndex() {
7868
7876
  if (this.catRadioGroup.length) {
7869
7877
  this.catRadioGroup.forEach(value => value.shadowRoot?.querySelector('input')?.setAttribute('tabindex', '-1'));
@@ -10205,21 +10213,13 @@ const catTabsCss = ":host{display:flex;flex-direction:row;box-shadow:inset 0 -1p
10205
10213
  const CatTabs = class {
10206
10214
  constructor(hostRef) {
10207
10215
  registerInstance(this, hostRef);
10208
- this.buttons = [];
10216
+ this.catChange = createEvent(this, "catChange", 7);
10209
10217
  this.tabs = [];
10210
- this.activeTabId = undefined;
10211
10218
  this.activeTab = '';
10212
10219
  this.tabsAlign = 'left';
10213
10220
  }
10214
- onActiveTabIdChanged(newActiveTab) {
10215
- const activeTab = this.tabs.find(value => value.id === newActiveTab);
10216
- activeTab?.click();
10217
- }
10218
10221
  componentWillLoad() {
10219
10222
  this.syncTabs();
10220
- if (this.tabs.length) {
10221
- this.activeTabId = this.activeTab;
10222
- }
10223
10223
  }
10224
10224
  componentDidLoad() {
10225
10225
  this.mutationObserver = new MutationObserver(mutations => mutations.some(value => value.target.nodeName === 'CAT-TAB') && this.syncTabs());
@@ -10232,9 +10232,14 @@ const CatTabs = class {
10232
10232
  disconnectedCallback() {
10233
10233
  this.mutationObserver?.disconnect();
10234
10234
  }
10235
+ onActiveTabChange(id) {
10236
+ const index = this.tabs.findIndex(tab => tab.id === id);
10237
+ this.catChange.emit({ id, index });
10238
+ }
10235
10239
  onKeydown(event) {
10236
10240
  if (['ArrowDown', 'ArrowUp', 'ArrowRight', 'ArrowLeft'].includes(event.key)) {
10237
- const targetElements = this.buttons.filter(button => !button.disabled);
10241
+ const elements = this.hostElement.shadowRoot?.querySelectorAll('cat-button[role="tab"]');
10242
+ const targetElements = Array.from(elements || []).filter(button => !button.disabled);
10238
10243
  const activeElement = this.hostElement.shadowRoot?.activeElement;
10239
10244
  const activeIdx = activeElement ? targetElements.indexOf(activeElement) : -1;
10240
10245
  const activeOff = ['ArrowDown', 'ArrowRight'].includes(event.key) ? 1 : -1;
@@ -10243,29 +10248,45 @@ const CatTabs = class {
10243
10248
  event.preventDefault();
10244
10249
  }
10245
10250
  }
10251
+ /**
10252
+ * Activates the tab with the given id.
10253
+ *
10254
+ * @param id The tab id.
10255
+ */
10256
+ async setActive(id) {
10257
+ this.activate(this.tabs.find(tab => tab.id === id));
10258
+ }
10259
+ /**
10260
+ * Activates the tab with the given index.
10261
+ *
10262
+ * @param index The tab index.
10263
+ */
10264
+ async setActiveIndex(index) {
10265
+ this.activate(this.tabs[index]);
10266
+ }
10246
10267
  render() {
10247
10268
  return (h(Host, null, this.tabs.map((tab) => {
10248
- return (h("cat-button", { ref: el => el && this.updateButtonsRef(el), buttonId: tab.id, role: "tab", part: "tab", class: {
10269
+ return (h("cat-button", { buttonId: tab.id, role: "tab", part: "tab", class: {
10249
10270
  'cat-tab': true,
10250
- 'cat-tab-active': Boolean(this.activeTabId && tab.id === this.activeTabId)
10251
- }, active: Boolean(this.activeTabId && tab.id === this.activeTabId), color: this.activeTabId && tab.id === this.activeTabId ? 'primary' : 'secondary', variant: "text", icon: tab.icon, iconOnly: tab.iconOnly, iconRight: tab.iconRight, url: tab.url, disabled: tab.deactivated, urlTarget: tab.urlTarget, onCatClick: () => (this.activeTabId = tab.id), nativeAttributes: { ...tab.nativeAttributes }, nativeContentAttributes: { 'data-text': tab.label }, "data-dropdown-no-close": true }, tab.label));
10271
+ 'cat-tab-active': tab.id === this.activeTab
10272
+ }, active: tab.id === this.activeTab, color: tab.id === this.activeTab ? 'primary' : 'secondary', variant: "text", icon: tab.icon, iconOnly: tab.iconOnly, iconRight: tab.iconRight, url: tab.url, disabled: tab.deactivated, urlTarget: tab.urlTarget, onCatClick: () => this.activate(tab), nativeAttributes: { ...tab.nativeAttributes }, nativeContentAttributes: { 'data-text': tab.label }, "data-dropdown-no-close": true }, tab.label));
10252
10273
  })));
10253
10274
  }
10254
- updateButtonsRef(button) {
10255
- const indexOf = this.buttons.indexOf(button);
10256
- if (indexOf >= 0) {
10257
- this.buttons[indexOf] = button;
10258
- }
10259
- else {
10260
- this.buttons.push(button);
10261
- }
10262
- }
10263
10275
  syncTabs() {
10264
10276
  this.tabs = Array.from(this.hostElement.querySelectorAll('cat-tab'));
10277
+ this.activeTab = this.activeTab || this.tabs.filter(tab => this.canActivate(tab))[0]?.id;
10278
+ }
10279
+ canActivate(tab) {
10280
+ return !!tab && !tab.deactivated && !tab.url && tab.id !== this.activeTab;
10281
+ }
10282
+ activate(tab) {
10283
+ if (this.canActivate(tab)) {
10284
+ this.activeTab = tab.id;
10285
+ }
10265
10286
  }
10266
10287
  get hostElement() { return getElement(this); }
10267
10288
  static get watchers() { return {
10268
- "activeTabId": ["onActiveTabIdChanged"]
10289
+ "activeTab": ["onActiveTabChange"]
10269
10290
  }; }
10270
10291
  };
10271
10292
  CatTabs.style = catTabsCss;