tyrell-components 1.0.0-TC52 → 1.0.0-TC53

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 (105) hide show
  1. package/css/tyrell-theme.css +25 -2
  2. package/css/tyrell.css +4 -0
  3. package/dist/tyrell-colors-static.css +1 -316
  4. package/dist/tyrell-theme.css +1 -1443
  5. package/dist/tyrell.css +1 -1390
  6. package/dist/tyrell.js +1 -1
  7. package/lib/base/ty-component.js +196 -196
  8. package/lib/components/button.d.ts +1 -1
  9. package/lib/components/button.js +260 -259
  10. package/lib/components/calendar-month.d.ts +2 -2
  11. package/lib/components/calendar-month.js +426 -416
  12. package/lib/components/calendar-navigation.js +238 -238
  13. package/lib/components/calendar.js +605 -602
  14. package/lib/components/checkbox.d.ts +1 -1
  15. package/lib/components/checkbox.js +273 -272
  16. package/lib/components/copy.d.ts +1 -1
  17. package/lib/components/copy.js +279 -278
  18. package/lib/components/date-picker.d.ts +1 -1
  19. package/lib/components/date-picker.js +1103 -1108
  20. package/lib/components/file-upload.js +404 -404
  21. package/lib/components/icon.js +141 -141
  22. package/lib/components/input.d.ts +1 -1
  23. package/lib/components/input.js +593 -596
  24. package/lib/components/modal.js +319 -319
  25. package/lib/components/option.js +167 -167
  26. package/lib/components/popup.js +233 -233
  27. package/lib/components/radio.d.ts +2 -2
  28. package/lib/components/radio.js +407 -406
  29. package/lib/components/resize-observer.js +67 -67
  30. package/lib/components/scroll-container.js +294 -294
  31. package/lib/components/select.d.ts +1 -1
  32. package/lib/components/select.js +1524 -1532
  33. package/lib/components/selected-tags.js +184 -184
  34. package/lib/components/step.js +62 -62
  35. package/lib/components/switch.d.ts +1 -1
  36. package/lib/components/switch.js +214 -213
  37. package/lib/components/tab.js +62 -62
  38. package/lib/components/tabs.js +507 -507
  39. package/lib/components/tag.d.ts +1 -1
  40. package/lib/components/tag.js +236 -235
  41. package/lib/components/textarea.d.ts +1 -1
  42. package/lib/components/textarea.js +457 -456
  43. package/lib/components/tooltip.js +283 -283
  44. package/lib/components/wizard.js +384 -384
  45. package/lib/icons/heroicons/micro.js +392 -392
  46. package/lib/icons/heroicons/mini.js +382 -382
  47. package/lib/icons/heroicons/outline.js +337 -337
  48. package/lib/icons/heroicons/solid.js +407 -407
  49. package/lib/icons/lucide.js +22843 -22843
  50. package/lib/icons/material/filled.js +9653 -9653
  51. package/lib/icons/material/outlined.js +10271 -10271
  52. package/lib/icons/material/round.js +10495 -10495
  53. package/lib/icons/material/sharp.js +9905 -9905
  54. package/lib/icons/material/two-tone.js +12792 -12792
  55. package/lib/index.js +21 -21
  56. package/lib/styles/button.js +176 -288
  57. package/lib/styles/calendar-month.js +123 -183
  58. package/lib/styles/calendar-navigation.js +60 -79
  59. package/lib/styles/calendar.js +8 -9
  60. package/lib/styles/checkbox.js +45 -72
  61. package/lib/styles/copy.js +67 -91
  62. package/lib/styles/custom-scrollbar.js +80 -100
  63. package/lib/styles/date-picker.js +261 -331
  64. package/lib/styles/field-size.d.ts +6 -0
  65. package/lib/styles/field-size.js +91 -0
  66. package/lib/styles/file-upload.js +139 -169
  67. package/lib/styles/icon.js +92 -156
  68. package/lib/styles/input.js +125 -241
  69. package/lib/styles/modal.js +67 -102
  70. package/lib/styles/option.d.ts +1 -1
  71. package/lib/styles/option.js +47 -67
  72. package/lib/styles/popup.js +34 -65
  73. package/lib/styles/radio.js +69 -96
  74. package/lib/styles/resize-observer.js +2 -5
  75. package/lib/styles/scroll-container.js +100 -130
  76. package/lib/styles/select-base.js +525 -778
  77. package/lib/styles/select.js +140 -228
  78. package/lib/styles/step.js +22 -29
  79. package/lib/styles/switch.js +34 -55
  80. package/lib/styles/tab.js +22 -29
  81. package/lib/styles/tabs.js +171 -252
  82. package/lib/styles/tag.js +135 -188
  83. package/lib/styles/textarea.d.ts +1 -1
  84. package/lib/styles/textarea.js +205 -271
  85. package/lib/styles/tooltip.js +3 -3
  86. package/lib/styles/wizard.js +170 -226
  87. package/lib/types/common.d.ts +2 -0
  88. package/lib/types/common.js +6 -5
  89. package/lib/utils/calendar-utils.js +100 -100
  90. package/lib/utils/custom-scrollbar.js +272 -272
  91. package/lib/utils/flavor-sheet.js +14 -14
  92. package/lib/utils/icon-registry.js +127 -127
  93. package/lib/utils/loader-registry.js +3 -3
  94. package/lib/utils/locale.js +34 -34
  95. package/lib/utils/mobile.js +1 -1
  96. package/lib/utils/number-format.js +54 -54
  97. package/lib/utils/positioning.js +212 -212
  98. package/lib/utils/property-capture.js +36 -36
  99. package/lib/utils/property-manager.js +125 -125
  100. package/lib/utils/resize-observer.js +23 -23
  101. package/lib/utils/scroll-lock.js +57 -57
  102. package/lib/utils/styles.js +17 -17
  103. package/lib/version.d.ts +1 -1
  104. package/lib/version.js +1 -1
  105. package/package.json +4 -4
@@ -1,224 +1,225 @@
1
+ import { DEFAULT_SIZE } from "../types/common.js";
1
2
  import { TyComponent } from "../base/ty-component.js";
2
3
  import { ensureStyles } from "../utils/styles.js";
3
4
  import { syncCustomFlavorSheet } from "../utils/flavor-sheet.js";
4
5
  import { switchStyles, switchCustomFlavorCss } from "../styles/switch.js";
5
6
  export class TySwitch extends TyComponent {
6
- constructor() {
7
- super();
8
- this._customFlavorSheet = null;
9
- this._listenersSetup = false;
10
- this._clickHandler = null;
11
- this._keydownHandler = null;
12
- this._focusHandler = null;
13
- this._blurHandler = null;
14
- const shadow = this.shadowRoot;
15
- ensureStyles(shadow, { css: switchStyles, id: "ty-switch" });
16
- }
17
- onConnect() {
18
- this.setupEventListeners();
19
- this._syncCustomFlavor();
20
- }
21
- onDisconnect() {
22
- this.removeEventListeners();
23
- }
24
- onPropertiesChanged(changes) {
25
- if (changes.some((c) => c.name === "flavor")) {
26
- this._syncCustomFlavor();
27
- }
28
- }
29
- _syncCustomFlavor() {
30
- this._customFlavorSheet = syncCustomFlavorSheet(this.shadowRoot, this._customFlavorSheet, this.flavor, ({ base }) => switchCustomFlavorCss(base));
31
- }
32
- getFormValue() {
33
- return this.checked ? this.value : null;
34
- }
35
- buildClassList() {
36
- const classes = [this.size];
37
- if (this.disabled)
38
- classes.push("disabled");
39
- if (this.required)
40
- classes.push("required");
41
- return classes.join(" ");
42
- }
43
- handleSwitchClick(e) {
44
- if (this.disabled)
45
- return;
46
- if (this.isDuplicateActivationClick())
47
- return;
48
- const newValue = !this.checked;
49
- this.checked = newValue;
50
- setTimeout(() => {
51
- const eventDetail = {
52
- value: newValue,
53
- checked: newValue,
54
- formValue: newValue ? this.value : null,
55
- originalEvent: e,
56
- };
57
- this.dispatchEvent(new CustomEvent("input", { detail: eventDetail, bubbles: true, composed: true }));
58
- this.dispatchEvent(new CustomEvent("change", { detail: eventDetail, bubbles: true, composed: true }));
59
- }, 0);
60
- }
61
- handleSwitchKeydown(e) {
62
- if (this.disabled)
63
- return;
64
- if (["Space", " ", "Enter"].includes(e.key)) {
65
- e.preventDefault();
66
- e.stopPropagation();
67
- this.handleSwitchClick(e);
68
- }
69
- }
70
- removeEventListeners() {
71
- if (!this._listenersSetup)
72
- return;
73
- if (this._clickHandler) {
74
- this.removeEventListener("click", this._clickHandler);
75
- this._clickHandler = null;
76
- }
77
- const shadow = this.shadowRoot;
78
- if (!shadow)
79
- return;
80
- const el = shadow.querySelector(".switch-container");
81
- if (!el) {
82
- this._listenersSetup = false;
83
- return;
84
- }
85
- if (this._keydownHandler) {
86
- el.removeEventListener("keydown", this._keydownHandler);
87
- this._keydownHandler = null;
88
- }
89
- if (this._focusHandler) {
90
- el.removeEventListener("focus", this._focusHandler);
91
- this._focusHandler = null;
92
- }
93
- if (this._blurHandler) {
94
- el.removeEventListener("blur", this._blurHandler);
95
- this._blurHandler = null;
96
- }
97
- this._listenersSetup = false;
98
- }
99
- setupEventListeners() {
100
- if (this._listenersSetup)
101
- return;
102
- const shadow = this.shadowRoot;
103
- const el = shadow.querySelector(".switch-container");
104
- if (!el)
105
- return;
106
- this._clickHandler = (e) => this.handleSwitchClick(e);
107
- this._keydownHandler = (e) => this.handleSwitchKeydown(e);
108
- this._focusHandler = () => el.classList.add("focused");
109
- this._blurHandler = () => el.classList.remove("focused");
110
- this.addEventListener("click", this._clickHandler);
111
- el.addEventListener("keydown", this._keydownHandler);
112
- el.addEventListener("focus", this._focusHandler);
113
- el.addEventListener("blur", this._blurHandler);
114
- this._listenersSetup = true;
115
- }
116
- render() {
117
- const shadow = this.shadowRoot;
118
- let switchEl = shadow.querySelector(".switch-container");
119
- const classes = this.buildClassList();
120
- if (!switchEl) {
121
- switchEl = document.createElement("div");
122
- switchEl.className = "switch-container " + classes;
123
- switchEl.tabIndex = this.disabled ? -1 : 0;
124
- switchEl.setAttribute("role", "switch");
125
- switchEl.setAttribute("aria-checked", this.checked ? "true" : "false");
126
- switchEl.setAttribute("aria-disabled", this.disabled ? "true" : "false");
127
- switchEl.setAttribute("aria-required", this.required ? "true" : "false");
128
- const track = document.createElement("div");
129
- track.className = "switch-track";
130
- const thumb = document.createElement("div");
131
- thumb.className = "switch-thumb";
132
- track.appendChild(thumb);
133
- switchEl.appendChild(track);
134
- shadow.appendChild(switchEl);
135
- }
136
- else {
137
- switchEl.className = "switch-container " + classes;
138
- switchEl.tabIndex = this.disabled ? -1 : 0;
139
- switchEl.setAttribute("aria-checked", this.checked ? "true" : "false");
140
- switchEl.setAttribute("aria-disabled", this.disabled ? "true" : "false");
141
- switchEl.setAttribute("aria-required", this.required ? "true" : "false");
142
- }
143
- this.setupEventListeners();
144
- this.applyLabelName(switchEl);
145
- this.updateValidity();
146
- }
147
- updateValidity() {
148
- const anchor = this.shadowRoot?.querySelector(".switch-container");
149
- if (this.disabled) {
150
- this._internals.setValidity({});
151
- return;
152
- }
153
- if (this.required && !this.checked) {
154
- this._internals.setValidity({ valueMissing: true }, "Please turn this on", anchor ?? undefined);
155
- }
156
- else {
157
- this._internals.setValidity({});
158
- }
159
- }
160
- get checked() { return this.getProperty("checked"); }
161
- set checked(value) { this.setProperty("checked", value); }
162
- get value() { return this.getProperty("value"); }
163
- set value(val) { this.setProperty("value", val); }
164
- get name() { return this.getProperty("name"); }
165
- set name(val) { this.setProperty("name", val); }
166
- get disabled() { return this.getProperty("disabled"); }
167
- set disabled(value) { this.setProperty("disabled", value); }
168
- get required() { return this.getProperty("required"); }
169
- set required(value) { this.setProperty("required", value); }
170
- get size() { return this.getProperty("size"); }
171
- set size(value) { this.setProperty("size", value); }
172
- get flavor() { return this.getProperty("flavor"); }
173
- set flavor(value) { this.setProperty("flavor", value); }
174
- get form() { return this._internals.form; }
7
+ constructor() {
8
+ super();
9
+ this._customFlavorSheet = null;
10
+ this._listenersSetup = false;
11
+ this._clickHandler = null;
12
+ this._keydownHandler = null;
13
+ this._focusHandler = null;
14
+ this._blurHandler = null;
15
+ const shadow = this.shadowRoot;
16
+ ensureStyles(shadow, { css: switchStyles, id: "ty-switch" });
17
+ }
18
+ onConnect() {
19
+ this.setupEventListeners();
20
+ this._syncCustomFlavor();
21
+ }
22
+ onDisconnect() {
23
+ this.removeEventListeners();
24
+ }
25
+ onPropertiesChanged(changes) {
26
+ if (changes.some((c) => c.name === "flavor")) {
27
+ this._syncCustomFlavor();
28
+ }
29
+ }
30
+ _syncCustomFlavor() {
31
+ this._customFlavorSheet = syncCustomFlavorSheet(this.shadowRoot, this._customFlavorSheet, this.flavor, ({ base }) => switchCustomFlavorCss(base));
32
+ }
33
+ getFormValue() {
34
+ return this.checked ? this.value : null;
35
+ }
36
+ buildClassList() {
37
+ const classes = [this.size];
38
+ if (this.disabled)
39
+ classes.push("disabled");
40
+ if (this.required)
41
+ classes.push("required");
42
+ return classes.join(" ");
43
+ }
44
+ handleSwitchClick(e) {
45
+ if (this.disabled)
46
+ return;
47
+ if (this.isDuplicateActivationClick())
48
+ return;
49
+ const newValue = !this.checked;
50
+ this.checked = newValue;
51
+ setTimeout(() => {
52
+ const eventDetail = {
53
+ value: newValue,
54
+ checked: newValue,
55
+ formValue: newValue ? this.value : null,
56
+ originalEvent: e,
57
+ };
58
+ this.dispatchEvent(new CustomEvent("input", { detail: eventDetail, bubbles: true, composed: true }));
59
+ this.dispatchEvent(new CustomEvent("change", { detail: eventDetail, bubbles: true, composed: true }));
60
+ }, 0);
61
+ }
62
+ handleSwitchKeydown(e) {
63
+ if (this.disabled)
64
+ return;
65
+ if (["Space", " ", "Enter"].includes(e.key)) {
66
+ e.preventDefault();
67
+ e.stopPropagation();
68
+ this.handleSwitchClick(e);
69
+ }
70
+ }
71
+ removeEventListeners() {
72
+ if (!this._listenersSetup)
73
+ return;
74
+ if (this._clickHandler) {
75
+ this.removeEventListener("click", this._clickHandler);
76
+ this._clickHandler = null;
77
+ }
78
+ const shadow = this.shadowRoot;
79
+ if (!shadow)
80
+ return;
81
+ const el = shadow.querySelector(".switch-container");
82
+ if (!el) {
83
+ this._listenersSetup = false;
84
+ return;
85
+ }
86
+ if (this._keydownHandler) {
87
+ el.removeEventListener("keydown", this._keydownHandler);
88
+ this._keydownHandler = null;
89
+ }
90
+ if (this._focusHandler) {
91
+ el.removeEventListener("focus", this._focusHandler);
92
+ this._focusHandler = null;
93
+ }
94
+ if (this._blurHandler) {
95
+ el.removeEventListener("blur", this._blurHandler);
96
+ this._blurHandler = null;
97
+ }
98
+ this._listenersSetup = false;
99
+ }
100
+ setupEventListeners() {
101
+ if (this._listenersSetup)
102
+ return;
103
+ const shadow = this.shadowRoot;
104
+ const el = shadow.querySelector(".switch-container");
105
+ if (!el)
106
+ return;
107
+ this._clickHandler = (e) => this.handleSwitchClick(e);
108
+ this._keydownHandler = (e) => this.handleSwitchKeydown(e);
109
+ this._focusHandler = () => el.classList.add("focused");
110
+ this._blurHandler = () => el.classList.remove("focused");
111
+ this.addEventListener("click", this._clickHandler);
112
+ el.addEventListener("keydown", this._keydownHandler);
113
+ el.addEventListener("focus", this._focusHandler);
114
+ el.addEventListener("blur", this._blurHandler);
115
+ this._listenersSetup = true;
116
+ }
117
+ render() {
118
+ const shadow = this.shadowRoot;
119
+ let switchEl = shadow.querySelector(".switch-container");
120
+ const classes = this.buildClassList();
121
+ if (!switchEl) {
122
+ switchEl = document.createElement("div");
123
+ switchEl.className = "switch-container " + classes;
124
+ switchEl.tabIndex = this.disabled ? -1 : 0;
125
+ switchEl.setAttribute("role", "switch");
126
+ switchEl.setAttribute("aria-checked", this.checked ? "true" : "false");
127
+ switchEl.setAttribute("aria-disabled", this.disabled ? "true" : "false");
128
+ switchEl.setAttribute("aria-required", this.required ? "true" : "false");
129
+ const track = document.createElement("div");
130
+ track.className = "switch-track";
131
+ const thumb = document.createElement("div");
132
+ thumb.className = "switch-thumb";
133
+ track.appendChild(thumb);
134
+ switchEl.appendChild(track);
135
+ shadow.appendChild(switchEl);
136
+ }
137
+ else {
138
+ switchEl.className = "switch-container " + classes;
139
+ switchEl.tabIndex = this.disabled ? -1 : 0;
140
+ switchEl.setAttribute("aria-checked", this.checked ? "true" : "false");
141
+ switchEl.setAttribute("aria-disabled", this.disabled ? "true" : "false");
142
+ switchEl.setAttribute("aria-required", this.required ? "true" : "false");
143
+ }
144
+ this.setupEventListeners();
145
+ this.applyLabelName(switchEl);
146
+ this.updateValidity();
147
+ }
148
+ updateValidity() {
149
+ const anchor = this.shadowRoot?.querySelector(".switch-container");
150
+ if (this.disabled) {
151
+ this._internals.setValidity({});
152
+ return;
153
+ }
154
+ if (this.required && !this.checked) {
155
+ this._internals.setValidity({ valueMissing: true }, "Please turn this on", anchor ?? undefined);
156
+ }
157
+ else {
158
+ this._internals.setValidity({});
159
+ }
160
+ }
161
+ get checked() { return this.getProperty("checked"); }
162
+ set checked(value) { this.setProperty("checked", value); }
163
+ get value() { return this.getProperty("value"); }
164
+ set value(val) { this.setProperty("value", val); }
165
+ get name() { return this.getProperty("name"); }
166
+ set name(val) { this.setProperty("name", val); }
167
+ get disabled() { return this.getProperty("disabled"); }
168
+ set disabled(value) { this.setProperty("disabled", value); }
169
+ get required() { return this.getProperty("required"); }
170
+ set required(value) { this.setProperty("required", value); }
171
+ get size() { return this.getProperty("size"); }
172
+ set size(value) { this.setProperty("size", value); }
173
+ get flavor() { return this.getProperty("flavor"); }
174
+ set flavor(value) { this.setProperty("flavor", value); }
175
+ get form() { return this._internals.form; }
175
176
  }
176
177
  TySwitch.formAssociated = true;
177
178
  TySwitch.properties = {
178
- checked: {
179
- type: "boolean",
180
- visual: true,
181
- formValue: true,
182
- emitChange: true,
183
- default: false,
184
- },
185
- value: {
186
- type: "string",
187
- default: "on",
188
- },
189
- name: {
190
- type: "string",
191
- default: "",
192
- },
193
- disabled: {
194
- type: "boolean",
195
- visual: true,
196
- default: false,
197
- },
198
- required: {
199
- type: "boolean",
200
- visual: true,
201
- default: false,
202
- },
203
- size: {
204
- type: "string",
205
- visual: true,
206
- default: "md",
207
- validate: (v) => ["xs", "sm", "md", "lg", "xl"].includes(v),
208
- coerce: (v) => {
209
- if (!["xs", "sm", "md", "lg", "xl"].includes(v)) {
210
- console.warn(`[ty-switch] Invalid size '${v}'. Using 'md'.`);
211
- return "md";
212
- }
213
- return v;
214
- },
215
- },
216
- flavor: {
217
- type: "string",
218
- visual: true,
219
- default: "primary",
220
- },
179
+ checked: {
180
+ type: "boolean",
181
+ visual: true,
182
+ formValue: true,
183
+ emitChange: true,
184
+ default: false,
185
+ },
186
+ value: {
187
+ type: "string",
188
+ default: "on",
189
+ },
190
+ name: {
191
+ type: "string",
192
+ default: "",
193
+ },
194
+ disabled: {
195
+ type: "boolean",
196
+ visual: true,
197
+ default: false,
198
+ },
199
+ required: {
200
+ type: "boolean",
201
+ visual: true,
202
+ default: false,
203
+ },
204
+ size: {
205
+ type: "string",
206
+ visual: true,
207
+ default: DEFAULT_SIZE,
208
+ validate: (v) => ["xs", "sm", "md", "lg", "xl"].includes(v),
209
+ coerce: (v) => {
210
+ if (!["xs", "sm", "md", "lg", "xl"].includes(v)) {
211
+ console.warn(`[ty-switch] Invalid size '${v}'. Using '${DEFAULT_SIZE}'.`);
212
+ return DEFAULT_SIZE;
213
+ }
214
+ return v;
215
+ },
216
+ },
217
+ flavor: {
218
+ type: "string",
219
+ visual: true,
220
+ default: "primary",
221
+ },
221
222
  };
222
223
  if (!customElements.get("ty-switch")) {
223
- customElements.define("ty-switch", TySwitch);
224
+ customElements.define("ty-switch", TySwitch);
224
225
  }
@@ -2,68 +2,68 @@ import { ensureStyles } from '../utils/styles.js';
2
2
  import { tabStyles } from '../styles/tab.js';
3
3
  import { CustomScrollbar, isCustomScrollbarEnabled } from '../utils/custom-scrollbar.js';
4
4
  export class TyTab extends HTMLElement {
5
- static get observedAttributes() {
6
- return ['id', 'label', 'disabled'];
7
- }
8
- constructor() {
9
- super();
10
- this._scrollbar = null;
11
- this.attachShadow({ mode: 'open' });
12
- }
13
- connectedCallback() {
14
- this._render();
15
- }
16
- disconnectedCallback() {
17
- this._destroyScrollbar();
18
- }
19
- attributeChangedCallback(_name, _oldValue, _newValue) {
20
- this._render();
21
- }
22
- _render() {
23
- const shadowRoot = this.shadowRoot;
24
- if (!shadowRoot)
25
- return;
26
- const id = this.getAttribute('id');
27
- if (!shadowRoot.querySelector('.tab-wrapper')) {
28
- ensureStyles(shadowRoot, { css: tabStyles, id: 'ty-tab' });
29
- shadowRoot.innerHTML = `
30
- <div class="tab-wrapper"
31
- role="tabpanel"
32
- ${id ? `id="panel-${id}"` : ''}
33
- ${id ? `aria-labelledby="tab-${id}"` : ''}
34
- >
35
- <div class="tab-panel">
36
- <slot></slot>
37
- </div>
38
- </div>
39
- `;
40
- this._setupScrollbar();
41
- }
42
- }
43
- _setupScrollbar() {
44
- const panel = this.shadowRoot?.querySelector('.tab-panel');
45
- const wrapper = this.shadowRoot?.querySelector('.tab-wrapper');
46
- if (!panel || !wrapper)
47
- return;
48
- if (!isCustomScrollbarEnabled())
49
- return;
50
- panel.classList.add('ty-custom-scroll');
51
- this._scrollbar = new CustomScrollbar(panel, { vertical: true });
52
- if (this._scrollbar.trackY) {
53
- wrapper.appendChild(this._scrollbar.trackY);
54
- }
55
- }
56
- _destroyScrollbar() {
57
- if (this._scrollbar) {
58
- this._scrollbar.trackY?.remove();
59
- this._scrollbar.destroy();
60
- this._scrollbar = null;
61
- }
62
- }
63
- resetScroll() {
64
- this._scrollbar?.scrollToTop(false);
65
- }
5
+ static get observedAttributes() {
6
+ return ['id', 'label', 'disabled'];
7
+ }
8
+ constructor() {
9
+ super();
10
+ this._scrollbar = null;
11
+ this.attachShadow({ mode: 'open' });
12
+ }
13
+ connectedCallback() {
14
+ this._render();
15
+ }
16
+ disconnectedCallback() {
17
+ this._destroyScrollbar();
18
+ }
19
+ attributeChangedCallback(_name, _oldValue, _newValue) {
20
+ this._render();
21
+ }
22
+ _render() {
23
+ const shadowRoot = this.shadowRoot;
24
+ if (!shadowRoot)
25
+ return;
26
+ const id = this.getAttribute('id');
27
+ if (!shadowRoot.querySelector('.tab-wrapper')) {
28
+ ensureStyles(shadowRoot, { css: tabStyles, id: 'ty-tab' });
29
+ shadowRoot.innerHTML = `
30
+ <div class="tab-wrapper"
31
+ role="tabpanel"
32
+ ${id ? `id="panel-${id}"` : ''}
33
+ ${id ? `aria-labelledby="tab-${id}"` : ''}
34
+ >
35
+ <div class="tab-panel">
36
+ <slot></slot>
37
+ </div>
38
+ </div>
39
+ `;
40
+ this._setupScrollbar();
41
+ }
42
+ }
43
+ _setupScrollbar() {
44
+ const panel = this.shadowRoot?.querySelector('.tab-panel');
45
+ const wrapper = this.shadowRoot?.querySelector('.tab-wrapper');
46
+ if (!panel || !wrapper)
47
+ return;
48
+ if (!isCustomScrollbarEnabled())
49
+ return;
50
+ panel.classList.add('ty-custom-scroll');
51
+ this._scrollbar = new CustomScrollbar(panel, { vertical: true });
52
+ if (this._scrollbar.trackY) {
53
+ wrapper.appendChild(this._scrollbar.trackY);
54
+ }
55
+ }
56
+ _destroyScrollbar() {
57
+ if (this._scrollbar) {
58
+ this._scrollbar.trackY?.remove();
59
+ this._scrollbar.destroy();
60
+ this._scrollbar = null;
61
+ }
62
+ }
63
+ resetScroll() {
64
+ this._scrollbar?.scrollToTop(false);
65
+ }
66
66
  }
67
67
  if (!customElements.get('ty-tab')) {
68
- customElements.define('ty-tab', TyTab);
68
+ customElements.define('ty-tab', TyTab);
69
69
  }