tyrell-components 1.0.0-RC6
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.
- package/LICENSE +21 -0
- package/README.md +221 -0
- package/css/tyrell.css +1783 -0
- package/dist/tyrell.css +1783 -0
- package/dist/tyrell.js +2 -0
- package/lib/base/ty-component.d.ts +133 -0
- package/lib/base/ty-component.d.ts.map +1 -0
- package/lib/base/ty-component.js +297 -0
- package/lib/base/ty-component.js.map +1 -0
- package/lib/components/button.d.ts +126 -0
- package/lib/components/button.d.ts.map +1 -0
- package/lib/components/button.js +244 -0
- package/lib/components/button.js.map +1 -0
- package/lib/components/calendar-month.d.ts +132 -0
- package/lib/components/calendar-month.d.ts.map +1 -0
- package/lib/components/calendar-month.js +440 -0
- package/lib/components/calendar-month.js.map +1 -0
- package/lib/components/calendar-navigation.d.ts +137 -0
- package/lib/components/calendar-navigation.d.ts.map +1 -0
- package/lib/components/calendar-navigation.js +366 -0
- package/lib/components/calendar-navigation.js.map +1 -0
- package/lib/components/calendar.d.ts +166 -0
- package/lib/components/calendar.d.ts.map +1 -0
- package/lib/components/calendar.js +774 -0
- package/lib/components/calendar.js.map +1 -0
- package/lib/components/checkbox.d.ts +189 -0
- package/lib/components/checkbox.d.ts.map +1 -0
- package/lib/components/checkbox.js +400 -0
- package/lib/components/checkbox.js.map +1 -0
- package/lib/components/copy.d.ts +180 -0
- package/lib/components/copy.d.ts.map +1 -0
- package/lib/components/copy.js +393 -0
- package/lib/components/copy.js.map +1 -0
- package/lib/components/date-picker.d.ts +379 -0
- package/lib/components/date-picker.d.ts.map +1 -0
- package/lib/components/date-picker.js +1586 -0
- package/lib/components/date-picker.js.map +1 -0
- package/lib/components/dropdown.d.ts +402 -0
- package/lib/components/dropdown.d.ts.map +1 -0
- package/lib/components/dropdown.js +1552 -0
- package/lib/components/dropdown.js.map +1 -0
- package/lib/components/icon.d.ts +118 -0
- package/lib/components/icon.d.ts.map +1 -0
- package/lib/components/icon.js +245 -0
- package/lib/components/icon.js.map +1 -0
- package/lib/components/input.d.ts +270 -0
- package/lib/components/input.d.ts.map +1 -0
- package/lib/components/input.js +721 -0
- package/lib/components/input.js.map +1 -0
- package/lib/components/modal.d.ts +58 -0
- package/lib/components/modal.d.ts.map +1 -0
- package/lib/components/modal.js +473 -0
- package/lib/components/modal.js.map +1 -0
- package/lib/components/multiselect.d.ts +397 -0
- package/lib/components/multiselect.d.ts.map +1 -0
- package/lib/components/multiselect.js +1580 -0
- package/lib/components/multiselect.js.map +1 -0
- package/lib/components/option.d.ts +66 -0
- package/lib/components/option.d.ts.map +1 -0
- package/lib/components/option.js +314 -0
- package/lib/components/option.js.map +1 -0
- package/lib/components/popup.d.ts +43 -0
- package/lib/components/popup.d.ts.map +1 -0
- package/lib/components/popup.js +380 -0
- package/lib/components/popup.js.map +1 -0
- package/lib/components/radio.d.ts +198 -0
- package/lib/components/radio.d.ts.map +1 -0
- package/lib/components/radio.js +437 -0
- package/lib/components/radio.js.map +1 -0
- package/lib/components/resize-observer.d.ts +48 -0
- package/lib/components/resize-observer.d.ts.map +1 -0
- package/lib/components/resize-observer.js +108 -0
- package/lib/components/resize-observer.js.map +1 -0
- package/lib/components/scroll-container.d.ts +51 -0
- package/lib/components/scroll-container.d.ts.map +1 -0
- package/lib/components/scroll-container.js +239 -0
- package/lib/components/scroll-container.js.map +1 -0
- package/lib/components/step.d.ts +26 -0
- package/lib/components/step.d.ts.map +1 -0
- package/lib/components/step.js +75 -0
- package/lib/components/step.js.map +1 -0
- package/lib/components/switch.d.ts +111 -0
- package/lib/components/switch.d.ts.map +1 -0
- package/lib/components/switch.js +240 -0
- package/lib/components/switch.js.map +1 -0
- package/lib/components/tab.d.ts +23 -0
- package/lib/components/tab.d.ts.map +1 -0
- package/lib/components/tab.js +76 -0
- package/lib/components/tab.js.map +1 -0
- package/lib/components/tabs.d.ts +93 -0
- package/lib/components/tabs.d.ts.map +1 -0
- package/lib/components/tabs.js +653 -0
- package/lib/components/tabs.js.map +1 -0
- package/lib/components/tag.d.ts +144 -0
- package/lib/components/tag.d.ts.map +1 -0
- package/lib/components/tag.js +316 -0
- package/lib/components/tag.js.map +1 -0
- package/lib/components/textarea.d.ts +241 -0
- package/lib/components/textarea.d.ts.map +1 -0
- package/lib/components/textarea.js +585 -0
- package/lib/components/textarea.js.map +1 -0
- package/lib/components/tooltip.d.ts +40 -0
- package/lib/components/tooltip.d.ts.map +1 -0
- package/lib/components/tooltip.js +439 -0
- package/lib/components/tooltip.js.map +1 -0
- package/lib/components/wizard.d.ts +86 -0
- package/lib/components/wizard.d.ts.map +1 -0
- package/lib/components/wizard.js +636 -0
- package/lib/components/wizard.js.map +1 -0
- package/lib/icons/fontawesome/brands.d.ts +557 -0
- package/lib/icons/fontawesome/brands.d.ts.map +1 -0
- package/lib/icons/fontawesome/brands.js +557 -0
- package/lib/icons/fontawesome/brands.js.map +1 -0
- package/lib/icons/fontawesome/regular.d.ts +281 -0
- package/lib/icons/fontawesome/regular.d.ts.map +1 -0
- package/lib/icons/fontawesome/regular.js +281 -0
- package/lib/icons/fontawesome/regular.js.map +1 -0
- package/lib/icons/fontawesome/solid.d.ts +1992 -0
- package/lib/icons/fontawesome/solid.d.ts.map +1 -0
- package/lib/icons/fontawesome/solid.js +1992 -0
- package/lib/icons/fontawesome/solid.js.map +1 -0
- package/lib/icons/heroicons/micro.d.ts +324 -0
- package/lib/icons/heroicons/micro.d.ts.map +1 -0
- package/lib/icons/heroicons/micro.js +1032 -0
- package/lib/icons/heroicons/micro.js.map +1 -0
- package/lib/icons/heroicons/mini.d.ts +332 -0
- package/lib/icons/heroicons/mini.d.ts.map +1 -0
- package/lib/icons/heroicons/mini.js +1038 -0
- package/lib/icons/heroicons/mini.js.map +1 -0
- package/lib/icons/heroicons/outline.d.ts +332 -0
- package/lib/icons/heroicons/outline.d.ts.map +1 -0
- package/lib/icons/heroicons/outline.js +993 -0
- package/lib/icons/heroicons/outline.js.map +1 -0
- package/lib/icons/heroicons/solid.d.ts +332 -0
- package/lib/icons/heroicons/solid.d.ts.map +1 -0
- package/lib/icons/heroicons/solid.js +1063 -0
- package/lib/icons/heroicons/solid.js.map +1 -0
- package/lib/icons/lucide.d.ts +1872 -0
- package/lib/icons/lucide.d.ts.map +1 -0
- package/lib/icons/lucide.js +28212 -0
- package/lib/icons/lucide.js.map +1 -0
- package/lib/icons/material/filled.d.ts +2180 -0
- package/lib/icons/material/filled.d.ts.map +1 -0
- package/lib/icons/material/filled.js +14003 -0
- package/lib/icons/material/filled.js.map +1 -0
- package/lib/icons/material/outlined.d.ts +2142 -0
- package/lib/icons/material/outlined.d.ts.map +1 -0
- package/lib/icons/material/outlined.js +14545 -0
- package/lib/icons/material/outlined.js.map +1 -0
- package/lib/icons/material/round.d.ts +2147 -0
- package/lib/icons/material/round.d.ts.map +1 -0
- package/lib/icons/material/round.js +14779 -0
- package/lib/icons/material/round.js.map +1 -0
- package/lib/icons/material/sharp.d.ts +2147 -0
- package/lib/icons/material/sharp.d.ts.map +1 -0
- package/lib/icons/material/sharp.js +14189 -0
- package/lib/icons/material/sharp.js.map +1 -0
- package/lib/icons/material/two-tone.d.ts +2185 -0
- package/lib/icons/material/two-tone.d.ts.map +1 -0
- package/lib/icons/material/two-tone.js +17152 -0
- package/lib/icons/material/two-tone.js.map +1 -0
- package/lib/index.d.ts +78 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +71 -0
- package/lib/index.js.map +1 -0
- package/lib/styles/button.d.ts +14 -0
- package/lib/styles/button.d.ts.map +1 -0
- package/lib/styles/button.js +457 -0
- package/lib/styles/button.js.map +1 -0
- package/lib/styles/calendar-month.d.ts +6 -0
- package/lib/styles/calendar-month.d.ts.map +1 -0
- package/lib/styles/calendar-month.js +275 -0
- package/lib/styles/calendar-month.js.map +1 -0
- package/lib/styles/calendar-navigation.d.ts +6 -0
- package/lib/styles/calendar-navigation.d.ts.map +1 -0
- package/lib/styles/calendar-navigation.js +143 -0
- package/lib/styles/calendar-navigation.js.map +1 -0
- package/lib/styles/calendar.d.ts +6 -0
- package/lib/styles/calendar.d.ts.map +1 -0
- package/lib/styles/calendar.js +28 -0
- package/lib/styles/calendar.js.map +1 -0
- package/lib/styles/checkbox.d.ts +9 -0
- package/lib/styles/checkbox.d.ts.map +1 -0
- package/lib/styles/checkbox.js +19 -0
- package/lib/styles/checkbox.js.map +1 -0
- package/lib/styles/copy.d.ts +7 -0
- package/lib/styles/copy.d.ts.map +1 -0
- package/lib/styles/copy.js +94 -0
- package/lib/styles/copy.js.map +1 -0
- package/lib/styles/custom-scrollbar.d.ts +6 -0
- package/lib/styles/custom-scrollbar.d.ts.map +1 -0
- package/lib/styles/custom-scrollbar.js +157 -0
- package/lib/styles/custom-scrollbar.js.map +1 -0
- package/lib/styles/date-picker.d.ts +6 -0
- package/lib/styles/date-picker.d.ts.map +1 -0
- package/lib/styles/date-picker.js +435 -0
- package/lib/styles/date-picker.js.map +1 -0
- package/lib/styles/dropdown.d.ts +12 -0
- package/lib/styles/dropdown.d.ts.map +1 -0
- package/lib/styles/dropdown.js +983 -0
- package/lib/styles/dropdown.js.map +1 -0
- package/lib/styles/icon.d.ts +6 -0
- package/lib/styles/icon.d.ts.map +1 -0
- package/lib/styles/icon.js +241 -0
- package/lib/styles/icon.js.map +1 -0
- package/lib/styles/input.d.ts +7 -0
- package/lib/styles/input.d.ts.map +1 -0
- package/lib/styles/input.js +685 -0
- package/lib/styles/input.js.map +1 -0
- package/lib/styles/modal.d.ts +8 -0
- package/lib/styles/modal.d.ts.map +1 -0
- package/lib/styles/modal.js +134 -0
- package/lib/styles/modal.js.map +1 -0
- package/lib/styles/multiselect.d.ts +6 -0
- package/lib/styles/multiselect.d.ts.map +1 -0
- package/lib/styles/multiselect.js +774 -0
- package/lib/styles/multiselect.js.map +1 -0
- package/lib/styles/option.d.ts +6 -0
- package/lib/styles/option.d.ts.map +1 -0
- package/lib/styles/option.js +116 -0
- package/lib/styles/option.js.map +1 -0
- package/lib/styles/popup.d.ts +8 -0
- package/lib/styles/popup.d.ts.map +1 -0
- package/lib/styles/popup.js +95 -0
- package/lib/styles/popup.js.map +1 -0
- package/lib/styles/radio.d.ts +8 -0
- package/lib/styles/radio.d.ts.map +1 -0
- package/lib/styles/radio.js +160 -0
- package/lib/styles/radio.js.map +1 -0
- package/lib/styles/resize-observer.d.ts +6 -0
- package/lib/styles/resize-observer.d.ts.map +1 -0
- package/lib/styles/resize-observer.js +18 -0
- package/lib/styles/resize-observer.js.map +1 -0
- package/lib/styles/scroll-container.d.ts +6 -0
- package/lib/styles/scroll-container.d.ts.map +1 -0
- package/lib/styles/scroll-container.js +198 -0
- package/lib/styles/scroll-container.js.map +1 -0
- package/lib/styles/step.d.ts +5 -0
- package/lib/styles/step.d.ts.map +1 -0
- package/lib/styles/step.js +50 -0
- package/lib/styles/step.js.map +1 -0
- package/lib/styles/switch.d.ts +9 -0
- package/lib/styles/switch.d.ts.map +1 -0
- package/lib/styles/switch.js +100 -0
- package/lib/styles/switch.js.map +1 -0
- package/lib/styles/tab.d.ts +5 -0
- package/lib/styles/tab.d.ts.map +1 -0
- package/lib/styles/tab.js +51 -0
- package/lib/styles/tab.js.map +1 -0
- package/lib/styles/tabs.d.ts +13 -0
- package/lib/styles/tabs.d.ts.map +1 -0
- package/lib/styles/tabs.js +184 -0
- package/lib/styles/tabs.js.map +1 -0
- package/lib/styles/tag.d.ts +6 -0
- package/lib/styles/tag.d.ts.map +1 -0
- package/lib/styles/tag.js +420 -0
- package/lib/styles/tag.js.map +1 -0
- package/lib/styles/textarea.d.ts +6 -0
- package/lib/styles/textarea.d.ts.map +1 -0
- package/lib/styles/textarea.js +350 -0
- package/lib/styles/textarea.js.map +1 -0
- package/lib/styles/tooltip.d.ts +9 -0
- package/lib/styles/tooltip.d.ts.map +1 -0
- package/lib/styles/tooltip.js +136 -0
- package/lib/styles/tooltip.js.map +1 -0
- package/lib/styles/wizard.d.ts +25 -0
- package/lib/styles/wizard.d.ts.map +1 -0
- package/lib/styles/wizard.js +325 -0
- package/lib/styles/wizard.js.map +1 -0
- package/lib/types/common.d.ts +143 -0
- package/lib/types/common.d.ts.map +1 -0
- package/lib/types/common.js +5 -0
- package/lib/types/common.js.map +1 -0
- package/lib/utils/calendar-utils.d.ts +176 -0
- package/lib/utils/calendar-utils.d.ts.map +1 -0
- package/lib/utils/calendar-utils.js +370 -0
- package/lib/utils/calendar-utils.js.map +1 -0
- package/lib/utils/custom-scrollbar.d.ts +82 -0
- package/lib/utils/custom-scrollbar.d.ts.map +1 -0
- package/lib/utils/custom-scrollbar.js +320 -0
- package/lib/utils/custom-scrollbar.js.map +1 -0
- package/lib/utils/icon-registry.d.ts +78 -0
- package/lib/utils/icon-registry.d.ts.map +1 -0
- package/lib/utils/icon-registry.js +304 -0
- package/lib/utils/icon-registry.js.map +1 -0
- package/lib/utils/locale.d.ts +136 -0
- package/lib/utils/locale.d.ts.map +1 -0
- package/lib/utils/locale.js +213 -0
- package/lib/utils/locale.js.map +1 -0
- package/lib/utils/mobile.d.ts +14 -0
- package/lib/utils/mobile.d.ts.map +1 -0
- package/lib/utils/mobile.js +21 -0
- package/lib/utils/mobile.js.map +1 -0
- package/lib/utils/number-format.d.ts +83 -0
- package/lib/utils/number-format.d.ts.map +1 -0
- package/lib/utils/number-format.js +143 -0
- package/lib/utils/number-format.js.map +1 -0
- package/lib/utils/parse-boolean.d.ts +39 -0
- package/lib/utils/parse-boolean.d.ts.map +1 -0
- package/lib/utils/parse-boolean.js +58 -0
- package/lib/utils/parse-boolean.js.map +1 -0
- package/lib/utils/positioning.d.ts +143 -0
- package/lib/utils/positioning.d.ts.map +1 -0
- package/lib/utils/positioning.js +308 -0
- package/lib/utils/positioning.js.map +1 -0
- package/lib/utils/property-capture.d.ts +132 -0
- package/lib/utils/property-capture.d.ts.map +1 -0
- package/lib/utils/property-capture.js +152 -0
- package/lib/utils/property-capture.js.map +1 -0
- package/lib/utils/property-manager.d.ts +90 -0
- package/lib/utils/property-manager.d.ts.map +1 -0
- package/lib/utils/property-manager.js +197 -0
- package/lib/utils/property-manager.js.map +1 -0
- package/lib/utils/resize-observer.d.ts +42 -0
- package/lib/utils/resize-observer.d.ts.map +1 -0
- package/lib/utils/resize-observer.js +71 -0
- package/lib/utils/resize-observer.js.map +1 -0
- package/lib/utils/scroll-lock.d.ts +79 -0
- package/lib/utils/scroll-lock.d.ts.map +1 -0
- package/lib/utils/scroll-lock.js +197 -0
- package/lib/utils/scroll-lock.js.map +1 -0
- package/lib/utils/styles.d.ts +27 -0
- package/lib/utils/styles.d.ts.map +1 -0
- package/lib/utils/styles.js +53 -0
- package/lib/utils/styles.js.map +1 -0
- package/lib/version.d.ts +8 -0
- package/lib/version.d.ts.map +1 -0
- package/lib/version.js +11 -0
- package/lib/version.js.map +1 -0
- package/package.json +159 -0
|
@@ -0,0 +1,653 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tabs Component
|
|
3
|
+
*
|
|
4
|
+
* A carousel-based tabs component with smooth animations and fixed container dimensions.
|
|
5
|
+
* Features horizontal sliding transitions, smart positioning marker, and independent panel scrolling.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Carousel animation with smooth sliding transitions
|
|
9
|
+
* - Fixed dimensions prevent layout shift between tabs
|
|
10
|
+
* - Animated marker that follows active tab button
|
|
11
|
+
* - Rich label support via slots (icons, badges, custom content)
|
|
12
|
+
* - Custom marker slot for complete active tab styling control
|
|
13
|
+
* - Independent panel scrolling with scroll position reset
|
|
14
|
+
* - ResizeObserver for responsive percentage widths
|
|
15
|
+
* - Smart rendering - only updates DOM when necessary
|
|
16
|
+
* - Accessibility with ARIA roles and attributes
|
|
17
|
+
* - Top/bottom placement for tab buttons
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* <!-- Basic tabs with text labels -->
|
|
21
|
+
* <ty-tabs width="800px" height="600px" active="general">
|
|
22
|
+
* <ty-tab id="general" label="General Settings">
|
|
23
|
+
* <div class="p-6">General content...</div>
|
|
24
|
+
* </ty-tab>
|
|
25
|
+
* <ty-tab id="advanced" label="Advanced Settings">
|
|
26
|
+
* <div class="p-6">Advanced content...</div>
|
|
27
|
+
* </ty-tab>
|
|
28
|
+
* </ty-tabs>
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* <!-- Rich labels with icons and badges -->
|
|
32
|
+
* <ty-tabs width="800px" height="600px">
|
|
33
|
+
* <!-- Rich label as direct child -->
|
|
34
|
+
* <span slot="label-profile" class="flex items-center gap-2">
|
|
35
|
+
* <ty-icon name="user" size="sm"></ty-icon>
|
|
36
|
+
* Profile
|
|
37
|
+
* </span>
|
|
38
|
+
*
|
|
39
|
+
* <span slot="label-notifications" class="flex items-center gap-2">
|
|
40
|
+
* <ty-icon name="bell" size="sm"></ty-icon>
|
|
41
|
+
* Notifications
|
|
42
|
+
* <span class="ty-bg-danger ty-text-danger++ px-2 py-0.5 rounded-full text-xs">5</span>
|
|
43
|
+
* </span>
|
|
44
|
+
*
|
|
45
|
+
* <!-- Tab panels -->
|
|
46
|
+
* <ty-tab id="profile">...</ty-tab>
|
|
47
|
+
* <ty-tab id="notifications">...</ty-tab>
|
|
48
|
+
* </ty-tabs>
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* <!-- Custom marker styling -->
|
|
52
|
+
* <ty-tabs width="100%" height="400px">
|
|
53
|
+
* <!-- Gradient marker slot -->
|
|
54
|
+
* <div slot="marker" style="
|
|
55
|
+
* background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
56
|
+
* border-radius: 0.5rem;
|
|
57
|
+
* box-shadow: 0 2px 8px rgba(0,0,0,0.15);
|
|
58
|
+
* "></div>
|
|
59
|
+
*
|
|
60
|
+
* <ty-tab id="tab1" label="Dashboard">...</ty-tab>
|
|
61
|
+
* <ty-tab id="tab2" label="Analytics">...</ty-tab>
|
|
62
|
+
* </ty-tabs>
|
|
63
|
+
*/
|
|
64
|
+
import { ensureStyles } from '../utils/styles.js';
|
|
65
|
+
import { tabsStyles } from '../styles/tabs.js';
|
|
66
|
+
// ============================================================================
|
|
67
|
+
// WeakMaps for State Management
|
|
68
|
+
// ============================================================================
|
|
69
|
+
const eventHandlers = new WeakMap();
|
|
70
|
+
const resizeObservers = new WeakMap();
|
|
71
|
+
// ============================================================================
|
|
72
|
+
// Helper Functions - Attribute Parsing
|
|
73
|
+
// ============================================================================
|
|
74
|
+
/**
|
|
75
|
+
* Extract tabs configuration from element attributes
|
|
76
|
+
*/
|
|
77
|
+
function getTabsAttributes(el) {
|
|
78
|
+
return {
|
|
79
|
+
width: el.getAttribute('width') || '100%',
|
|
80
|
+
height: el.getAttribute('height') || '400px',
|
|
81
|
+
active: el.getAttribute('active'),
|
|
82
|
+
placement: (el.getAttribute('placement') || 'top'),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Get all ty-tab child elements
|
|
87
|
+
*/
|
|
88
|
+
function getChildTabs(el) {
|
|
89
|
+
return Array.from(el.querySelectorAll('ty-tab'));
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Get ID from a ty-tab element
|
|
93
|
+
*/
|
|
94
|
+
function getTabId(tab) {
|
|
95
|
+
return tab.getAttribute('id');
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Check if ty-tabs has a direct child label slot for this tab-id.
|
|
99
|
+
* Looks in ty-tabs' light DOM for slot='label-{tab-id}' elements.
|
|
100
|
+
*/
|
|
101
|
+
function hasSlotLabel(tabsEl, tabId) {
|
|
102
|
+
return tabsEl.querySelector(`[slot='label-${tabId}']`) !== null;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Determine label type: 'slot' (rich content) or 'text' (simple attribute).
|
|
106
|
+
* Checks ty-tabs element for slot='label-{tab-id}' direct children.
|
|
107
|
+
*/
|
|
108
|
+
function getTabLabelType(tabsEl, tab) {
|
|
109
|
+
const tabId = getTabId(tab);
|
|
110
|
+
if (tabId && hasSlotLabel(tabsEl, tabId)) {
|
|
111
|
+
return 'slot';
|
|
112
|
+
}
|
|
113
|
+
return 'text';
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Check if tab is disabled
|
|
117
|
+
*/
|
|
118
|
+
function isTabDisabled(tab) {
|
|
119
|
+
return tab.hasAttribute('disabled');
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Check if user provided custom marker content via slot
|
|
123
|
+
*/
|
|
124
|
+
function hasCustomMarker(el) {
|
|
125
|
+
return el.querySelector('[slot="marker"]') !== null;
|
|
126
|
+
}
|
|
127
|
+
// ============================================================================
|
|
128
|
+
// Helper Functions - Active Tab Management
|
|
129
|
+
// ============================================================================
|
|
130
|
+
/**
|
|
131
|
+
* Find index of tab with given ID
|
|
132
|
+
*/
|
|
133
|
+
function findTabIndex(tabs, tabId) {
|
|
134
|
+
const index = tabs.findIndex(tab => getTabId(tab) === tabId);
|
|
135
|
+
return index >= 0 ? index : undefined;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Get the active tab ID, defaulting to first tab if not specified
|
|
139
|
+
*/
|
|
140
|
+
function getActiveTabId(el, tabs) {
|
|
141
|
+
const activeAttr = el.getAttribute('active');
|
|
142
|
+
if (activeAttr && findTabIndex(tabs, activeAttr) !== undefined) {
|
|
143
|
+
return activeAttr;
|
|
144
|
+
}
|
|
145
|
+
// Default to first tab
|
|
146
|
+
if (tabs.length > 0) {
|
|
147
|
+
return getTabId(tabs[0]);
|
|
148
|
+
}
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Set the active tab by ID
|
|
153
|
+
*/
|
|
154
|
+
function setActiveTab(el, tabId) {
|
|
155
|
+
el.setAttribute('active', tabId);
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Dispatch ty-tab-change event
|
|
159
|
+
*/
|
|
160
|
+
function dispatchTabChangeEvent(el, activeId, activeIndex, previousId, previousIndex) {
|
|
161
|
+
const event = new CustomEvent('ty-tab-change', {
|
|
162
|
+
detail: {
|
|
163
|
+
activeId,
|
|
164
|
+
activeIndex,
|
|
165
|
+
previousId,
|
|
166
|
+
previousIndex,
|
|
167
|
+
},
|
|
168
|
+
bubbles: true,
|
|
169
|
+
cancelable: false,
|
|
170
|
+
});
|
|
171
|
+
el.dispatchEvent(event);
|
|
172
|
+
}
|
|
173
|
+
// ============================================================================
|
|
174
|
+
// Event Handlers - Tab Button Click
|
|
175
|
+
// ============================================================================
|
|
176
|
+
/**
|
|
177
|
+
* Handle tab button click
|
|
178
|
+
*/
|
|
179
|
+
function handleTabClick(el, tabId, event) {
|
|
180
|
+
event.preventDefault();
|
|
181
|
+
event.stopPropagation();
|
|
182
|
+
// Set the active attribute (which will trigger state update)
|
|
183
|
+
setActiveTab(el, tabId);
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Cleanup existing event listeners
|
|
187
|
+
*/
|
|
188
|
+
function cleanupEventListeners(el) {
|
|
189
|
+
const handlers = eventHandlers.get(el);
|
|
190
|
+
if (!handlers)
|
|
191
|
+
return;
|
|
192
|
+
const shadowRoot = el.shadowRoot;
|
|
193
|
+
if (!shadowRoot)
|
|
194
|
+
return;
|
|
195
|
+
// Remove all tab click handlers
|
|
196
|
+
handlers.tabClickHandlers.forEach((handler, tabId) => {
|
|
197
|
+
const button = shadowRoot.querySelector(`[data-tab-id='${tabId}']`);
|
|
198
|
+
if (button) {
|
|
199
|
+
button.removeEventListener('pointerdown', handler);
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
handlers.tabClickHandlers.clear();
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Setup event listeners for tab button clicks
|
|
206
|
+
*/
|
|
207
|
+
function setupEventListeners(el, shadowRoot, tabs) {
|
|
208
|
+
// Clean up any existing listeners first
|
|
209
|
+
cleanupEventListeners(el);
|
|
210
|
+
// Initialize handlers storage
|
|
211
|
+
const handlers = {
|
|
212
|
+
tabClickHandlers: new Map(),
|
|
213
|
+
};
|
|
214
|
+
// Add click listener for each tab button
|
|
215
|
+
tabs.forEach((tab) => {
|
|
216
|
+
const tabId = getTabId(tab);
|
|
217
|
+
if (!tabId)
|
|
218
|
+
return;
|
|
219
|
+
const button = shadowRoot.querySelector(`[data-tab-id='${tabId}']`);
|
|
220
|
+
if (button) {
|
|
221
|
+
const handler = (e) => handleTabClick(el, tabId, e);
|
|
222
|
+
button.addEventListener('pointerdown', handler);
|
|
223
|
+
handlers.tabClickHandlers.set(tabId, handler);
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
// Store handlers for cleanup
|
|
227
|
+
eventHandlers.set(el, handlers);
|
|
228
|
+
}
|
|
229
|
+
// ============================================================================
|
|
230
|
+
// Transform & Positioning Updates
|
|
231
|
+
// ============================================================================
|
|
232
|
+
/**
|
|
233
|
+
* Update the transform on panels-wrapper based on active index and measured width
|
|
234
|
+
*/
|
|
235
|
+
function updateTransform(el, activeIndex) {
|
|
236
|
+
const shadowRoot = el.shadowRoot;
|
|
237
|
+
if (!shadowRoot)
|
|
238
|
+
return;
|
|
239
|
+
const panelsWrapper = shadowRoot.querySelector('.panels-wrapper');
|
|
240
|
+
if (!panelsWrapper)
|
|
241
|
+
return;
|
|
242
|
+
// Measure the actual width of the container
|
|
243
|
+
const containerWidth = el.offsetWidth;
|
|
244
|
+
const offsetPx = activeIndex * containerWidth;
|
|
245
|
+
// Apply transform directly in pixels
|
|
246
|
+
panelsWrapper.style.transform = `translateX(-${offsetPx}px)`;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Update ARIA attributes on tab buttons without re-rendering
|
|
250
|
+
*/
|
|
251
|
+
function updateAriaAttributes(el, shadowRoot, activeId) {
|
|
252
|
+
const tabs = getChildTabs(el);
|
|
253
|
+
tabs.forEach((tab, idx) => {
|
|
254
|
+
const tabId = getTabId(tab);
|
|
255
|
+
if (!tabId)
|
|
256
|
+
return;
|
|
257
|
+
const button = shadowRoot.querySelector(`[data-tab-id='${tabId}']`);
|
|
258
|
+
const isActive = tabId === activeId;
|
|
259
|
+
if (button) {
|
|
260
|
+
button.setAttribute('aria-selected', String(isActive));
|
|
261
|
+
button.setAttribute('tabindex', isActive ? '0' : '-1');
|
|
262
|
+
// Add data-active attribute for styling slotted content
|
|
263
|
+
button.setAttribute('data-active', String(isActive));
|
|
264
|
+
// Also set data-active on the slotted label element in light DOM
|
|
265
|
+
const slottedLabel = el.querySelector(`[slot='label-${tabId}']`);
|
|
266
|
+
if (slottedLabel) {
|
|
267
|
+
slottedLabel.setAttribute('data-active', String(isActive));
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Update pointer-events, opacity, and data-active on tab panels without re-rendering
|
|
274
|
+
*/
|
|
275
|
+
function updatePanelInteraction(el, activeId) {
|
|
276
|
+
const tabs = getChildTabs(el);
|
|
277
|
+
tabs.forEach((tab) => {
|
|
278
|
+
const tabId = getTabId(tab);
|
|
279
|
+
if (!tabId)
|
|
280
|
+
return;
|
|
281
|
+
const isActive = tabId === activeId;
|
|
282
|
+
// Set data-active attribute for framework conditional rendering
|
|
283
|
+
tab.setAttribute('data-active', String(isActive));
|
|
284
|
+
if (isActive) {
|
|
285
|
+
tab.style.pointerEvents = 'auto';
|
|
286
|
+
tab.style.opacity = '1';
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
tab.style.pointerEvents = 'none';
|
|
290
|
+
tab.style.opacity = '0';
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Calculate marker position and dimensions based on active tab button.
|
|
296
|
+
* Returns position object with left, top, width, height in pixels, or null if button not found.
|
|
297
|
+
*/
|
|
298
|
+
function calculateMarkerPosition(el, shadowRoot, activeId) {
|
|
299
|
+
const button = shadowRoot.querySelector(`[data-tab-id='${activeId}']`);
|
|
300
|
+
const buttonsContainer = shadowRoot.querySelector('.tab-buttons');
|
|
301
|
+
if (!button || !buttonsContainer)
|
|
302
|
+
return null;
|
|
303
|
+
const buttonRect = button.getBoundingClientRect();
|
|
304
|
+
// Use offset properties for position relative to container (accounts for padding)
|
|
305
|
+
const left = button.offsetLeft;
|
|
306
|
+
const top = button.offsetTop;
|
|
307
|
+
return {
|
|
308
|
+
left,
|
|
309
|
+
top,
|
|
310
|
+
width: buttonRect.width,
|
|
311
|
+
height: buttonRect.height,
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Update marker wrapper position and dimensions to match active tab button
|
|
316
|
+
*/
|
|
317
|
+
function updateMarker(el, activeId) {
|
|
318
|
+
const shadowRoot = el.shadowRoot;
|
|
319
|
+
if (!shadowRoot)
|
|
320
|
+
return;
|
|
321
|
+
const marker = shadowRoot.querySelector('.marker-wrapper');
|
|
322
|
+
if (!marker)
|
|
323
|
+
return;
|
|
324
|
+
const position = calculateMarkerPosition(el, shadowRoot, activeId);
|
|
325
|
+
if (!position)
|
|
326
|
+
return;
|
|
327
|
+
marker.style.left = `${position.left}px`;
|
|
328
|
+
marker.style.top = `${position.top}px`;
|
|
329
|
+
marker.style.width = `${position.width}px`;
|
|
330
|
+
marker.style.height = `${position.height}px`;
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Update only the active tab state without re-rendering DOM.
|
|
334
|
+
* Called from `attributeChangedCallback` when the `active` attribute changes.
|
|
335
|
+
*
|
|
336
|
+
* `previousId` MUST be the value the attribute held *before* it was changed —
|
|
337
|
+
* never call `getActiveTabId(el, ...)` here, because the attribute has already
|
|
338
|
+
* been updated to `tabId` by the time this runs. Reading it back would always
|
|
339
|
+
* yield the new value, making the change-detection guard below trip on every
|
|
340
|
+
* click and silently suppress `ty-tab-change` dispatch.
|
|
341
|
+
*/
|
|
342
|
+
function updateActiveTabState(el, tabId, previousId) {
|
|
343
|
+
const tabs = getChildTabs(el);
|
|
344
|
+
const shadowRoot = el.shadowRoot;
|
|
345
|
+
if (!shadowRoot)
|
|
346
|
+
return;
|
|
347
|
+
const currentIndex = previousId ? findTabIndex(tabs, previousId) : undefined;
|
|
348
|
+
const newIndex = findTabIndex(tabs, tabId);
|
|
349
|
+
// Only update if different tab and valid
|
|
350
|
+
if (previousId === tabId || newIndex === undefined)
|
|
351
|
+
return;
|
|
352
|
+
// Update CSS variable for transform
|
|
353
|
+
el.style.setProperty('--active-index', String(newIndex));
|
|
354
|
+
// Update transform directly
|
|
355
|
+
updateTransform(el, newIndex);
|
|
356
|
+
// Update ARIA attributes on buttons
|
|
357
|
+
updateAriaAttributes(el, shadowRoot, tabId);
|
|
358
|
+
// Update pointer-events on panels
|
|
359
|
+
updatePanelInteraction(el, tabId);
|
|
360
|
+
// Update marker position to match new active tab
|
|
361
|
+
updateMarker(el, tabId);
|
|
362
|
+
// Reset scroll position of new active panel
|
|
363
|
+
const newPanel = tabs[newIndex];
|
|
364
|
+
if (newPanel?.resetScroll) {
|
|
365
|
+
newPanel.resetScroll();
|
|
366
|
+
}
|
|
367
|
+
// Dispatch change event
|
|
368
|
+
dispatchTabChangeEvent(el, tabId, newIndex, previousId, currentIndex ?? null);
|
|
369
|
+
}
|
|
370
|
+
// ============================================================================
|
|
371
|
+
// ResizeObserver for Responsive Width
|
|
372
|
+
// ============================================================================
|
|
373
|
+
/**
|
|
374
|
+
* Setup ResizeObserver for percentage widths and marker updates
|
|
375
|
+
*/
|
|
376
|
+
function setupResizeObserver(el) {
|
|
377
|
+
// Clean up old observer
|
|
378
|
+
const oldObserver = resizeObservers.get(el);
|
|
379
|
+
if (oldObserver) {
|
|
380
|
+
oldObserver.disconnect();
|
|
381
|
+
}
|
|
382
|
+
const { width } = getTabsAttributes(el);
|
|
383
|
+
// Only setup observer for percentage widths
|
|
384
|
+
if (width.includes('%')) {
|
|
385
|
+
const observer = new ResizeObserver((entries) => {
|
|
386
|
+
const entry = entries[0];
|
|
387
|
+
const measuredWidth = entry.contentRect.width;
|
|
388
|
+
const tabs = getChildTabs(el);
|
|
389
|
+
const activeId = getActiveTabId(el, tabs);
|
|
390
|
+
const activeIndex = activeId ? findTabIndex(tabs, activeId) : 0;
|
|
391
|
+
// Update CSS variable with measured width
|
|
392
|
+
el.style.setProperty('--tabs-width', `${measuredWidth}px`);
|
|
393
|
+
// Update transform with new width
|
|
394
|
+
if (activeIndex !== undefined) {
|
|
395
|
+
updateTransform(el, activeIndex);
|
|
396
|
+
}
|
|
397
|
+
// Update marker position (tab button positions may have changed)
|
|
398
|
+
if (activeId) {
|
|
399
|
+
updateMarker(el, activeId);
|
|
400
|
+
}
|
|
401
|
+
});
|
|
402
|
+
observer.observe(el);
|
|
403
|
+
resizeObservers.set(el, observer);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Cleanup ResizeObserver
|
|
408
|
+
*/
|
|
409
|
+
function cleanupResizeObserver(el) {
|
|
410
|
+
const observer = resizeObservers.get(el);
|
|
411
|
+
if (observer) {
|
|
412
|
+
observer.disconnect();
|
|
413
|
+
resizeObservers.delete(el);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
// ============================================================================
|
|
417
|
+
// Rendering Functions
|
|
418
|
+
// ============================================================================
|
|
419
|
+
/**
|
|
420
|
+
* Generate HTML for tab buttons using slots for rich labels.
|
|
421
|
+
* Slots are looked up as direct children of tabs-el with slot='label-{tab-id}'.
|
|
422
|
+
* Also renders marker wrapper with optional default underline (only if no custom marker).
|
|
423
|
+
*/
|
|
424
|
+
function renderTabButtons(tabsEl, tabs, activeId) {
|
|
425
|
+
const buttons = tabs.map((tab) => {
|
|
426
|
+
const tabId = getTabId(tab);
|
|
427
|
+
if (!tabId)
|
|
428
|
+
return '';
|
|
429
|
+
const labelType = getTabLabelType(tabsEl, tab);
|
|
430
|
+
const textLabel = labelType === 'text' ? (tab.getAttribute('label') || 'Tab') : '';
|
|
431
|
+
const disabled = isTabDisabled(tab);
|
|
432
|
+
const active = tabId === activeId;
|
|
433
|
+
return `<button
|
|
434
|
+
class="tab-button"
|
|
435
|
+
role="tab"
|
|
436
|
+
data-tab-id="${tabId}"
|
|
437
|
+
id="tab-${tabId}"
|
|
438
|
+
aria-controls="panel-${tabId}"
|
|
439
|
+
aria-selected="${active}"
|
|
440
|
+
tabindex="${active ? '0' : '-1'}"
|
|
441
|
+
data-active="${active}"
|
|
442
|
+
${disabled ? 'disabled aria-disabled="true"' : ''}
|
|
443
|
+
>
|
|
444
|
+
${labelType === 'slot' ? `<slot name="label-${tabId}"></slot>` : textLabel}
|
|
445
|
+
</button>`;
|
|
446
|
+
}).join('');
|
|
447
|
+
return `
|
|
448
|
+
<div class="tab-buttons" role="tablist" part="buttons-container">
|
|
449
|
+
<div class="marker-wrapper" part="marker-wrapper">
|
|
450
|
+
${!hasCustomMarker(tabsEl) ? '<div class="default-marker"></div>' : ''}
|
|
451
|
+
<slot name="marker"></slot>
|
|
452
|
+
</div>
|
|
453
|
+
${buttons}
|
|
454
|
+
</div>
|
|
455
|
+
`;
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* Generate HTML for ONLY the button elements (no marker wrapper).
|
|
459
|
+
* Used during smart updates to preserve the marker wrapper.
|
|
460
|
+
*/
|
|
461
|
+
function renderButtonsOnly(tabsEl, tabs, activeId) {
|
|
462
|
+
return tabs.map((tab) => {
|
|
463
|
+
const tabId = getTabId(tab);
|
|
464
|
+
if (!tabId)
|
|
465
|
+
return '';
|
|
466
|
+
const labelType = getTabLabelType(tabsEl, tab);
|
|
467
|
+
const textLabel = labelType === 'text' ? (tab.getAttribute('label') || 'Tab') : '';
|
|
468
|
+
const disabled = isTabDisabled(tab);
|
|
469
|
+
const active = tabId === activeId;
|
|
470
|
+
return `<button
|
|
471
|
+
class="tab-button"
|
|
472
|
+
role="tab"
|
|
473
|
+
data-tab-id="${tabId}"
|
|
474
|
+
id="tab-${tabId}"
|
|
475
|
+
aria-controls="panel-${tabId}"
|
|
476
|
+
aria-selected="${active}"
|
|
477
|
+
tabindex="${active ? '0' : '-1'}"
|
|
478
|
+
data-active="${active}"
|
|
479
|
+
${disabled ? 'disabled aria-disabled="true"' : ''}
|
|
480
|
+
>
|
|
481
|
+
${labelType === 'slot' ? `<slot name="label-${tabId}"></slot>` : textLabel}
|
|
482
|
+
</button>`;
|
|
483
|
+
}).join('');
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* Render the tabs container with buttons and panel viewport.
|
|
487
|
+
* Smart rendering: checks if structure exists and only updates when needed.
|
|
488
|
+
*/
|
|
489
|
+
function render(el) {
|
|
490
|
+
const shadowRoot = el.shadowRoot;
|
|
491
|
+
if (!shadowRoot)
|
|
492
|
+
return;
|
|
493
|
+
const { width, height, placement } = getTabsAttributes(el);
|
|
494
|
+
const tabs = getChildTabs(el);
|
|
495
|
+
const activeId = getActiveTabId(el, tabs);
|
|
496
|
+
const activeIndex = activeId ? (findTabIndex(tabs, activeId) ?? 0) : 0;
|
|
497
|
+
// Check if structure already exists
|
|
498
|
+
const existingContainer = shadowRoot.querySelector('.tabs-container');
|
|
499
|
+
const existingButtons = shadowRoot.querySelector('.tab-buttons');
|
|
500
|
+
const existingViewport = shadowRoot.querySelector('.panels-viewport');
|
|
501
|
+
// Ensure styles are loaded
|
|
502
|
+
ensureStyles(shadowRoot, { css: tabsStyles, id: 'ty-tabs' });
|
|
503
|
+
// Dev warning for too many tabs
|
|
504
|
+
if (tabs.length > 7) {
|
|
505
|
+
console.warn(`[ty-tabs] More than 7 tabs detected (${tabs.length} tabs). ` +
|
|
506
|
+
'This may cause overflow and poor UX. ' +
|
|
507
|
+
'Consider using sidebar navigation, accordion menu, or other patterns.');
|
|
508
|
+
}
|
|
509
|
+
// Set CSS variables for dimensions
|
|
510
|
+
el.style.setProperty('--tabs-width', width.includes('%') ? '100%' : width);
|
|
511
|
+
el.style.setProperty('--tabs-height', height);
|
|
512
|
+
el.style.setProperty('--active-index', String(activeIndex));
|
|
513
|
+
if (existingContainer && existingButtons && existingViewport) {
|
|
514
|
+
// === SMART UPDATE: Structure exists, only update what changed ===
|
|
515
|
+
// Update placement if changed
|
|
516
|
+
existingContainer.setAttribute('data-placement', placement);
|
|
517
|
+
// SMART UPDATE: Preserve marker wrapper, only update buttons
|
|
518
|
+
const allButtons = existingButtons.querySelectorAll('.tab-button');
|
|
519
|
+
allButtons.forEach(button => button.remove());
|
|
520
|
+
// Generate and append new buttons after the marker wrapper
|
|
521
|
+
const buttonsHtml = renderButtonsOnly(el, tabs, activeId);
|
|
522
|
+
const tempDiv = document.createElement('div');
|
|
523
|
+
tempDiv.innerHTML = buttonsHtml;
|
|
524
|
+
Array.from(tempDiv.children).forEach(button => {
|
|
525
|
+
existingButtons.appendChild(button);
|
|
526
|
+
});
|
|
527
|
+
// Re-setup event listeners (buttons were recreated)
|
|
528
|
+
setupEventListeners(el, shadowRoot, tabs);
|
|
529
|
+
// Update ARIA and data-active attributes on initial render
|
|
530
|
+
updateAriaAttributes(el, shadowRoot, activeId || '');
|
|
531
|
+
// Measure button height and update marker after update
|
|
532
|
+
requestAnimationFrame(() => {
|
|
533
|
+
const buttons = shadowRoot.querySelector('.tab-buttons');
|
|
534
|
+
if (buttons) {
|
|
535
|
+
const buttonsHeight = buttons.offsetHeight;
|
|
536
|
+
el.style.setProperty('--buttons-height', `${buttonsHeight}px`);
|
|
537
|
+
}
|
|
538
|
+
// Update transform with current active index
|
|
539
|
+
updateTransform(el, activeIndex);
|
|
540
|
+
// Update marker position to match active tab
|
|
541
|
+
if (activeId) {
|
|
542
|
+
updateMarker(el, activeId);
|
|
543
|
+
}
|
|
544
|
+
});
|
|
545
|
+
// Update panel interaction states
|
|
546
|
+
if (activeId) {
|
|
547
|
+
updatePanelInteraction(el, activeId);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
else {
|
|
551
|
+
// === FULL RENDER: First time or structure missing ===
|
|
552
|
+
shadowRoot.innerHTML = `
|
|
553
|
+
<div class="tabs-container" data-placement="${placement}">
|
|
554
|
+
${renderTabButtons(el, tabs, activeId)}
|
|
555
|
+
<div class="panels-viewport" part="panels-container">
|
|
556
|
+
<div class="panels-wrapper">
|
|
557
|
+
<slot></slot>
|
|
558
|
+
</div>
|
|
559
|
+
</div>
|
|
560
|
+
</div>
|
|
561
|
+
`;
|
|
562
|
+
// Measure button height, update transform and marker after render
|
|
563
|
+
requestAnimationFrame(() => {
|
|
564
|
+
const buttons = shadowRoot.querySelector('.tab-buttons');
|
|
565
|
+
if (buttons) {
|
|
566
|
+
const buttonsHeight = buttons.offsetHeight;
|
|
567
|
+
el.style.setProperty('--buttons-height', `${buttonsHeight}px`);
|
|
568
|
+
}
|
|
569
|
+
// Update transform with measured width
|
|
570
|
+
updateTransform(el, activeIndex);
|
|
571
|
+
// Update marker position to match active tab
|
|
572
|
+
if (activeId) {
|
|
573
|
+
updateMarker(el, activeId);
|
|
574
|
+
}
|
|
575
|
+
});
|
|
576
|
+
// Setup event listeners
|
|
577
|
+
setupEventListeners(el, shadowRoot, tabs);
|
|
578
|
+
// Update ARIA and data-active attributes on initial render
|
|
579
|
+
updateAriaAttributes(el, shadowRoot, activeId || '');
|
|
580
|
+
// Setup ResizeObserver for responsive width
|
|
581
|
+
setupResizeObserver(el);
|
|
582
|
+
// Update tab panel states
|
|
583
|
+
if (activeId) {
|
|
584
|
+
updatePanelInteraction(el, activeId);
|
|
585
|
+
}
|
|
586
|
+
// Listen for marker slot changes to hide default marker
|
|
587
|
+
const markerSlot = shadowRoot.querySelector('slot[name="marker"]');
|
|
588
|
+
if (markerSlot) {
|
|
589
|
+
const updateDefaultMarkerVisibility = () => {
|
|
590
|
+
const defaultMarker = shadowRoot.querySelector('.default-marker');
|
|
591
|
+
if (defaultMarker) {
|
|
592
|
+
const hasCustom = markerSlot.assignedElements().length > 0;
|
|
593
|
+
defaultMarker.style.display = hasCustom ? 'none' : '';
|
|
594
|
+
}
|
|
595
|
+
};
|
|
596
|
+
markerSlot.addEventListener('slotchange', updateDefaultMarkerVisibility);
|
|
597
|
+
// Check immediately in case content is already slotted
|
|
598
|
+
updateDefaultMarkerVisibility();
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* Cleanup when tabs component is disconnected
|
|
604
|
+
*/
|
|
605
|
+
function cleanup(el) {
|
|
606
|
+
cleanupEventListeners(el);
|
|
607
|
+
cleanupResizeObserver(el);
|
|
608
|
+
}
|
|
609
|
+
// ============================================================================
|
|
610
|
+
// Component Definition
|
|
611
|
+
// ============================================================================
|
|
612
|
+
/**
|
|
613
|
+
* TyTabs Web Component
|
|
614
|
+
*/
|
|
615
|
+
export class TyTabs extends HTMLElement {
|
|
616
|
+
/** Observed attributes */
|
|
617
|
+
static get observedAttributes() {
|
|
618
|
+
return ['width', 'height', 'active', 'placement'];
|
|
619
|
+
}
|
|
620
|
+
constructor() {
|
|
621
|
+
super();
|
|
622
|
+
this.attachShadow({ mode: 'open' });
|
|
623
|
+
}
|
|
624
|
+
connectedCallback() {
|
|
625
|
+
render(this);
|
|
626
|
+
}
|
|
627
|
+
disconnectedCallback() {
|
|
628
|
+
cleanup(this);
|
|
629
|
+
}
|
|
630
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
631
|
+
// Smart rendering: only full render when structural attributes change
|
|
632
|
+
if (name === 'active') {
|
|
633
|
+
// Active tab changed - update state, then do smart render
|
|
634
|
+
if (newValue) {
|
|
635
|
+
// Pass `oldValue` explicitly so the change-detection inside
|
|
636
|
+
// `updateActiveTabState` compares against the previous value
|
|
637
|
+
// rather than re-reading the (already updated) attribute.
|
|
638
|
+
updateActiveTabState(this, newValue, oldValue);
|
|
639
|
+
}
|
|
640
|
+
// Always call render after active change to update button states
|
|
641
|
+
render(this);
|
|
642
|
+
}
|
|
643
|
+
else {
|
|
644
|
+
// Other attributes changed (width, height, placement) - full render
|
|
645
|
+
render(this);
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
// Register the custom element
|
|
650
|
+
if (!customElements.get('ty-tabs')) {
|
|
651
|
+
customElements.define('ty-tabs', TyTabs);
|
|
652
|
+
}
|
|
653
|
+
//# sourceMappingURL=tabs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tabs.js","sourceRoot":"","sources":["../../src/components/tabs.ts"],"names":[],"mappings":"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"}
|