udp-stencil-component-library 25.18.1-beta.6 → 25.18.1-beta.7
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/dist/cjs/advanced-search_50.cjs.entry.js +111 -41
- package/dist/cjs/ag-grid-base_5.cjs.entry.js +1 -1
- package/dist/cjs/chip-section.cjs.entry.js +2 -2
- package/dist/cjs/color-preview.cjs.entry.js +1 -1
- package/dist/cjs/index-DrMNAZCL.js +4 -0
- package/dist/cjs/inputs-example.cjs.entry.js +2 -2
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/page-renderer.cjs.entry.js +1 -1
- package/dist/cjs/stencil-library.cjs.js +1 -1
- package/dist/cjs/udp-tab-panel.cjs.entry.js +22 -0
- package/dist/cjs/udp-tab-panel.entry.cjs.js.map +1 -0
- package/dist/collection/collection-manifest.json +1 -0
- package/dist/collection/components/my-component/UI/tabs/tab/tabs/udp-tabs.css +0 -5
- package/dist/collection/components/my-component/UI/tabs/tab/tabs/udp-tabs.js +170 -37
- package/dist/collection/components/my-component/UI/tabs/tab/tabs/udp-tabs.js.map +1 -1
- package/dist/collection/components/my-component/UI/tabs/tab/udp-tab.css +2 -4
- package/dist/collection/components/my-component/UI/tabs/tab/udp-tab.js +2 -2
- package/dist/collection/components/my-component/UI/tabs/tab/udp-tab.js.map +1 -1
- package/dist/collection/components/my-component/UI/tabs/udp-tab-panel/udp-tab-panel.css +11 -0
- package/dist/collection/components/my-component/UI/tabs/udp-tab-panel/udp-tab-panel.js +65 -0
- package/dist/collection/components/my-component/UI/tabs/udp-tab-panel/udp-tab-panel.js.map +1 -0
- package/dist/collection/components/my-component/UI/toolbars/app-bar/app-bar.js +1 -1
- package/dist/collection/components/my-component/UI/util/ghost-render/ghost-render.js +1 -1
- package/dist/collection/components/my-component/demo/ambient-demo-container.js +1 -1
- package/dist/collection/components/test-component/inputs-example/inputs-example.js +2 -2
- package/dist/collection/page-renderer/page-renderer.js +1 -1
- package/dist/collection/theme/color-preview/color-preview.js +1 -1
- package/dist/collection/udp-utilities/layout/udp-dynamic-container-with-menu/chip-section/chip-section.js +2 -2
- package/dist/collection/udp-utilities/layout/udp-dynamic-container-with-menu/udp-dynamic-container-with-menu.js +1 -1
- package/dist/components/ambient-demo-container2.js +1 -1
- package/dist/components/app-bar2.js +1 -1
- package/dist/components/chip-section.js +2 -2
- package/dist/components/color-preview.js +1 -1
- package/dist/components/ghost-render2.js +1 -1
- package/dist/components/inputs-example.js +2 -2
- package/dist/components/page-renderer.js +1 -1
- package/dist/components/udp-dynamic-container-with-menu2.js +1 -1
- package/dist/components/udp-tab-panel.d.ts +11 -0
- package/dist/components/udp-tab-panel.js +45 -0
- package/dist/components/udp-tab-panel.js.map +1 -0
- package/dist/components/udp-tab2.js +2 -2
- package/dist/components/udp-tab2.js.map +1 -1
- package/dist/components/udp-tabs2.js +114 -40
- package/dist/components/udp-tabs2.js.map +1 -1
- package/dist/docs.json +141 -4
- package/dist/esm/advanced-search_50.entry.js +111 -41
- package/dist/esm/ag-grid-base_5.entry.js +1 -1
- package/dist/esm/chip-section.entry.js +2 -2
- package/dist/esm/color-preview.entry.js +1 -1
- package/dist/esm/index-n-1ZSeAs.js +4 -0
- package/dist/esm/inputs-example.entry.js +2 -2
- package/dist/esm/loader.js +1 -1
- package/dist/esm/page-renderer.entry.js +1 -1
- package/dist/esm/stencil-library.js +1 -1
- package/dist/esm/udp-tab-panel.entry.js +20 -0
- package/dist/esm/udp-tab-panel.entry.js.map +1 -0
- package/dist/stencil-library/advanced-search_50.entry.js +1 -1
- package/dist/stencil-library/advanced-search_50.entry.js.map +1 -1
- package/dist/stencil-library/ag-grid-base_5.entry.js +1 -1
- package/dist/stencil-library/chip-section.entry.js +1 -1
- package/dist/stencil-library/color-preview.entry.js +1 -1
- package/dist/stencil-library/inputs-example.entry.js +1 -1
- package/dist/stencil-library/page-renderer.entry.js +1 -1
- package/dist/stencil-library/stencil-library.esm.js +1 -1
- package/dist/stencil-library/udp-tab-panel.entry.esm.js.map +1 -0
- package/dist/stencil-library/udp-tab-panel.entry.js +2 -0
- package/dist/stencil-library/udp-tab-panel.entry.js.map +1 -0
- package/dist/types/components/my-component/UI/tabs/tab/tabs/udp-tabs.d.ts +47 -4
- package/dist/types/components/my-component/UI/tabs/tab/udp-tab.d.ts +1 -1
- package/dist/types/components/my-component/UI/tabs/udp-tab-panel/udp-tab-panel.d.ts +11 -0
- package/dist/types/components.d.ts +68 -2
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { p as proxyCustomElement, H, h } from './index2.js';
|
|
1
|
+
import { p as proxyCustomElement, H, c as createEvent, h } from './index2.js';
|
|
2
2
|
import { d as defineCustomElement$1 } from './udp-icon2.js';
|
|
3
3
|
|
|
4
|
-
const udpTabsCss = ".tab-container{display:flex;flex-direction:column}.tab-header{background-color:#ffffff;position:relative;display:flex;align-items:center}.tab-scroll-container{display:flex;position:relative;overflow-x:auto;overflow-y:hidden;flex:1;min-width:0}.tab-scroll-container::-webkit-scrollbar{height:4px}.tab-scroll-container::-webkit-scrollbar-track{background:transparent}.tab-scroll-container::-webkit-scrollbar-thumb{background-color:rgba(0, 0, 0, 0.2);border-radius:4px}.tab-scroll-container::-webkit-scrollbar-thumb:hover{background-color:rgba(0, 0, 0, 0.3)}.tab-header::after{content:'';position:absolute;bottom:0;left:0;width:100%;height:1px;background-color:var(--divider-color, #e0e0e0)}.tab-header button{padding:16px;font-size:14px;text-align:center;border:none;background:none;cursor:pointer;outline:none;transition:all 0.22s ease;color:#555555;font-weight:600;opacity:0.9;white-space:nowrap;display:flex;align-items:center;justify-content:center;gap:8px}.tab-header.fill .tab-scroll-container{width:100%}.tab-header.fill .tab-scroll-container button{flex-grow:1}.tab-header button.active{color:var(--secondary-color, #344861);opacity:1.0}.tab-header button.scroll-arrow{position:absolute;top:0;bottom:0;display:flex;align-items:center;justify-content:center;width:40px;padding:0;background:#ffffff;cursor:pointer;font-size:16px;font-weight:bold;color:#757575;z-index:2;transition:color 0.2s ease;flex-shrink:0;opacity:1;gap:0}.tab-header button.scroll-arrow:hover{color:#000}.tab-header button.scroll-arrow.left{left:0}.tab-header button.scroll-arrow.right{right:0}.scroll-fade{position:absolute;top:0;bottom:0;width:30px;z-index:1;pointer-events:none}.scroll-fade.left{left:40px;background:linear-gradient(\n to right,\n #ffffff,\n rgba(255, 255, 255, 0)\n )}.scroll-fade.right{right:40px;background:linear-gradient(\n to left,\n #ffffff,\n rgba(255, 255, 255, 0)\n )}.tab-header button udp-icon{font-size:1.2em;line-height:1}.tab-header button.icon-start{flex-direction:row}.tab-header button.icon-end{flex-direction:row-reverse}.tab-header button.icon-top{flex-direction:column;gap:4px}.tab-header button.icon-bottom{flex-direction:column-reverse;gap:4px}.
|
|
4
|
+
const udpTabsCss = ".tab-container{display:flex;flex-direction:column}.tab-header{background-color:#ffffff;position:relative;display:flex;align-items:center}.tab-scroll-container{display:flex;position:relative;overflow-x:auto;overflow-y:hidden;flex:1;min-width:0}.tab-scroll-container::-webkit-scrollbar{height:4px}.tab-scroll-container::-webkit-scrollbar-track{background:transparent}.tab-scroll-container::-webkit-scrollbar-thumb{background-color:rgba(0, 0, 0, 0.2);border-radius:4px}.tab-scroll-container::-webkit-scrollbar-thumb:hover{background-color:rgba(0, 0, 0, 0.3)}.tab-header::after{content:'';position:absolute;bottom:0;left:0;width:100%;height:1px;background-color:var(--divider-color, #e0e0e0)}.tab-header button{padding:16px;font-size:14px;text-align:center;border:none;background:none;cursor:pointer;outline:none;transition:all 0.22s ease;color:#555555;font-weight:600;opacity:0.9;white-space:nowrap;display:flex;align-items:center;justify-content:center;gap:8px}.tab-header.fill .tab-scroll-container{width:100%}.tab-header.fill .tab-scroll-container button{flex-grow:1}.tab-header button.active{color:var(--secondary-color, #344861);opacity:1.0}.tab-header button.scroll-arrow{position:absolute;top:0;bottom:0;display:flex;align-items:center;justify-content:center;width:40px;padding:0;background:#ffffff;cursor:pointer;font-size:16px;font-weight:bold;color:#757575;z-index:2;transition:color 0.2s ease;flex-shrink:0;opacity:1;gap:0}.tab-header button.scroll-arrow:hover{color:#000}.tab-header button.scroll-arrow.left{left:0}.tab-header button.scroll-arrow.right{right:0}.scroll-fade{position:absolute;top:0;bottom:0;width:30px;z-index:1;pointer-events:none}.scroll-fade.left{left:40px;background:linear-gradient(\n to right,\n #ffffff,\n rgba(255, 255, 255, 0)\n )}.scroll-fade.right{right:40px;background:linear-gradient(\n to left,\n #ffffff,\n rgba(255, 255, 255, 0)\n )}.tab-header button udp-icon{font-size:1.2em;line-height:1}.tab-header button.icon-start{flex-direction:row}.tab-header button.icon-end{flex-direction:row-reverse}.tab-header button.icon-top{flex-direction:column;gap:4px}.tab-header button.icon-bottom{flex-direction:column-reverse;gap:4px}.slider{position:absolute;bottom:0;left:0;height:2px;background-color:var(--secondary-color, #344861);transition:transform 0.22s cubic-bezier(0.4, 0, 0.2, 1),\n width 0.22s cubic-bezier(0.4, 0, 0.2, 1);z-index:1}.tab-header button.disabled{opacity:0.5;cursor:not-allowed}.tab-header button.disabled.active{color:#757575;opacity:0.5}";
|
|
5
5
|
|
|
6
6
|
const UdpTabs = /*@__PURE__*/ proxyCustomElement(class UdpTabs extends H {
|
|
7
7
|
constructor(registerHost) {
|
|
@@ -10,6 +10,7 @@ const UdpTabs = /*@__PURE__*/ proxyCustomElement(class UdpTabs extends H {
|
|
|
10
10
|
this.__registerHost();
|
|
11
11
|
}
|
|
12
12
|
this.__attachShadow();
|
|
13
|
+
this.udpTabChange = createEvent(this, "udpTabChange");
|
|
13
14
|
/**
|
|
14
15
|
* Specifies the layout variant of the tab header.
|
|
15
16
|
*
|
|
@@ -17,18 +18,46 @@ const UdpTabs = /*@__PURE__*/ proxyCustomElement(class UdpTabs extends H {
|
|
|
17
18
|
* - `'fill'`: Tabs will stretch to fill the available horizontal space.
|
|
18
19
|
*/
|
|
19
20
|
this.variant = 'fill';
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
/**
|
|
22
|
+
* (Optional) An array of tab configuration objects.
|
|
23
|
+
* If provided, this will be used to render tabs instead of slotted `<udp-tab>` components.
|
|
24
|
+
* This mode is typically used with controlled tabs.
|
|
25
|
+
*/
|
|
26
|
+
this.tabs = [];
|
|
27
|
+
this.internalActiveTab = 0; // For uncontrolled mode
|
|
28
|
+
this.tabDetails = []; // Unified details from prop or slot
|
|
22
29
|
this.sliderStyle = {
|
|
23
30
|
width: '0',
|
|
24
31
|
transform: 'translateX(0)',
|
|
25
32
|
};
|
|
26
33
|
this.showScrollLeft = false;
|
|
27
34
|
this.showScrollRight = false;
|
|
28
|
-
this.
|
|
35
|
+
this.slottedTabs = []; // Renamed from `tabs`
|
|
29
36
|
this.buttonRefs = [];
|
|
30
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Returns true if the component is in controlled mode.
|
|
40
|
+
*/
|
|
41
|
+
get isControlled() {
|
|
42
|
+
return this.value != null;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Returns true if tabs are being provided by the `tabs` prop.
|
|
46
|
+
*/
|
|
47
|
+
get useTabsProp() {
|
|
48
|
+
return this.tabs && this.tabs.length > 0;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Returns the currently active tab index,
|
|
52
|
+
* respecting controlled or uncontrolled mode.
|
|
53
|
+
*/
|
|
54
|
+
get activeTab() {
|
|
55
|
+
return this.isControlled ? this.value : this.internalActiveTab;
|
|
56
|
+
}
|
|
31
57
|
handleSlotChange() {
|
|
58
|
+
// If we're using the tabs prop, slot changes are irrelevant
|
|
59
|
+
if (this.useTabsProp)
|
|
60
|
+
return;
|
|
32
61
|
this.initializeTabs();
|
|
33
62
|
}
|
|
34
63
|
handleResize() {
|
|
@@ -40,9 +69,27 @@ const UdpTabs = /*@__PURE__*/ proxyCustomElement(class UdpTabs extends H {
|
|
|
40
69
|
componentDidLoad() {
|
|
41
70
|
this.initializeTabs();
|
|
42
71
|
}
|
|
43
|
-
|
|
72
|
+
/**
|
|
73
|
+
* Watcher for uncontrolled state changes.
|
|
74
|
+
*/
|
|
75
|
+
onActiveTabChange(newValue) {
|
|
76
|
+
this.updateActiveTabs();
|
|
77
|
+
this.updateSliderPosition();
|
|
78
|
+
this.scrollTabIntoView(newValue);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Watcher for controlled state changes.
|
|
82
|
+
*/
|
|
83
|
+
onValueChange(newValue) {
|
|
44
84
|
this.updateActiveTabs();
|
|
45
85
|
this.updateSliderPosition();
|
|
86
|
+
this.scrollTabIntoView(newValue);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Watcher for tabs prop changes.
|
|
90
|
+
*/
|
|
91
|
+
onTabsPropChange() {
|
|
92
|
+
this.initializeTabs();
|
|
46
93
|
}
|
|
47
94
|
onVariantChange() {
|
|
48
95
|
requestAnimationFrame(() => {
|
|
@@ -53,21 +100,29 @@ const UdpTabs = /*@__PURE__*/ proxyCustomElement(class UdpTabs extends H {
|
|
|
53
100
|
initializeTabs() {
|
|
54
101
|
var _a, _b;
|
|
55
102
|
this.buttonRefs = [];
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
103
|
+
if (this.useTabsProp) {
|
|
104
|
+
// --- Prop-based ---
|
|
105
|
+
this.tabDetails = this.tabs.map(t => (Object.assign({}, t))); // Use data from prop
|
|
106
|
+
this.slottedTabs = []; // Ensure we're not tracking slotted tabs
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
// --- Slot-based ---
|
|
110
|
+
this.slottedTabs = Array.from(this.el.children).filter((child) => child.tagName.toLowerCase() === 'udp-tab');
|
|
111
|
+
this.tabDetails = this.slottedTabs.map(tab => ({
|
|
112
|
+
label: tab.label,
|
|
113
|
+
icon: tab.icon,
|
|
114
|
+
iconPlacement: tab.iconPlacement,
|
|
115
|
+
hidden: tab.hidden,
|
|
116
|
+
disabled: tab.disabled,
|
|
117
|
+
}));
|
|
118
|
+
}
|
|
119
|
+
// --- Common Logic ---
|
|
120
|
+
// In uncontrolled mode, check if the default active tab is invalid.
|
|
121
|
+
if (!this.isControlled) {
|
|
122
|
+
if (((_a = this.tabDetails[this.internalActiveTab]) === null || _a === void 0 ? void 0 : _a.hidden) || ((_b = this.tabDetails[this.internalActiveTab]) === null || _b === void 0 ? void 0 : _b.disabled)) {
|
|
123
|
+
const firstValidIndex = this.tabDetails.findIndex(tab => !tab.hidden && !tab.disabled);
|
|
124
|
+
this.internalActiveTab = firstValidIndex > -1 ? firstValidIndex : 0;
|
|
125
|
+
}
|
|
71
126
|
}
|
|
72
127
|
this.updateActiveTabs();
|
|
73
128
|
requestAnimationFrame(() => {
|
|
@@ -76,12 +131,17 @@ const UdpTabs = /*@__PURE__*/ proxyCustomElement(class UdpTabs extends H {
|
|
|
76
131
|
});
|
|
77
132
|
}
|
|
78
133
|
updateActiveTabs() {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
134
|
+
// Only update slotted tabs if we're in slot mode
|
|
135
|
+
if (!this.useTabsProp) {
|
|
136
|
+
const currentActiveTab = this.activeTab;
|
|
137
|
+
this.slottedTabs.forEach((tab, index) => {
|
|
138
|
+
tab.active = index === currentActiveTab;
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
// If in prop mode, the <button> 'active' class is handled by render()
|
|
82
142
|
}
|
|
83
143
|
updateSliderPosition() {
|
|
84
|
-
const activeButton = this.buttonRefs[this.activeTab];
|
|
144
|
+
const activeButton = this.buttonRefs[this.activeTab]; // Use getter
|
|
85
145
|
if (!activeButton) {
|
|
86
146
|
this.sliderStyle = { width: '0px', transform: 'translateX(0px)' };
|
|
87
147
|
return;
|
|
@@ -104,7 +164,18 @@ const UdpTabs = /*@__PURE__*/ proxyCustomElement(class UdpTabs extends H {
|
|
|
104
164
|
if ((_a = this.tabDetails[tabIndex]) === null || _a === void 0 ? void 0 : _a.disabled) {
|
|
105
165
|
return;
|
|
106
166
|
}
|
|
107
|
-
this.
|
|
167
|
+
if (this.isControlled) {
|
|
168
|
+
// In controlled mode, emit the event for the parent to handle.
|
|
169
|
+
// The `onValueChange` watcher will handle UI updates when the prop changes.
|
|
170
|
+
this.udpTabChange.emit(tabIndex);
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
// In uncontrolled mode, update state directly.
|
|
174
|
+
// The `onActiveTabChange` watcher will handle UI updates.
|
|
175
|
+
this.internalActiveTab = tabIndex;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
scrollTabIntoView(tabIndex) {
|
|
108
179
|
const tabButton = this.buttonRefs[tabIndex];
|
|
109
180
|
const container = this.scrollContainerRef;
|
|
110
181
|
if (!tabButton || !container)
|
|
@@ -115,20 +186,16 @@ const UdpTabs = /*@__PURE__*/ proxyCustomElement(class UdpTabs extends H {
|
|
|
115
186
|
const safeZonePadding = 70;
|
|
116
187
|
const safeZoneLeft = scrollLeft + safeZonePadding;
|
|
117
188
|
const safeZoneRight = scrollLeft + clientWidth - safeZonePadding;
|
|
118
|
-
// Check if the tab's left edge is hidden by the left fade
|
|
119
189
|
if (tabLeft < safeZoneLeft) {
|
|
120
|
-
// Scroll to position the tab's left edge at the start of the safe zone
|
|
121
190
|
container.scrollTo({
|
|
122
191
|
left: tabLeft - safeZonePadding,
|
|
123
|
-
behavior: 'smooth'
|
|
192
|
+
behavior: 'smooth',
|
|
124
193
|
});
|
|
125
194
|
}
|
|
126
|
-
// Check if the tab's right edge is hidden by the right fade
|
|
127
195
|
else if (tabRight > safeZoneRight) {
|
|
128
|
-
// Scroll to position the tab's right edge at the end of the safe zone
|
|
129
196
|
container.scrollTo({
|
|
130
197
|
left: tabRight - clientWidth + safeZonePadding,
|
|
131
|
-
behavior: 'smooth'
|
|
198
|
+
behavior: 'smooth',
|
|
132
199
|
});
|
|
133
200
|
}
|
|
134
201
|
}
|
|
@@ -146,37 +213,44 @@ const UdpTabs = /*@__PURE__*/ proxyCustomElement(class UdpTabs extends H {
|
|
|
146
213
|
container.scrollTo({ left: maxScrollLeft, behavior: 'smooth' });
|
|
147
214
|
}
|
|
148
215
|
render() {
|
|
149
|
-
|
|
216
|
+
const currentActiveTab = this.activeTab; // Use getter
|
|
217
|
+
return (h("div", { key: 'dd8ac7e3d101993b8df00c97bf561e2502e9f3c1', class: "tab-container" }, h("div", { key: '5f70a5c0da906152b130f6eaa98b81bf80485920', class: `tab-header ${this.variant}` }, this.showScrollLeft && (h("button", { key: 'e1a3a7d3650ae3703734a51b251600bf12dbed0c', class: "scroll-arrow left", onClick: () => this.scrollToStart(), "aria-label": "Scroll to first tab" }, h("udp-icon", { key: '36e6294b1a775a30906cc0236f8104ad03998c01', iconName: "chevronLeft16", color: "inherit" }))), this.showScrollLeft && h("div", { key: '8dca0bd111f13c1890fbc010efbabb2aa0440c13', class: "scroll-fade left" }), h("div", { key: '966f761c7f3cc45eb5b6737e8dbb63dc75a68325', class: "tab-scroll-container", ref: el => (this.scrollContainerRef = el), onScroll: () => this.checkScroll() }, this.tabDetails.map((tab, index) => {
|
|
150
218
|
if (tab.hidden) {
|
|
151
219
|
return null;
|
|
152
220
|
}
|
|
153
221
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
154
222
|
const iconEl = tab.icon ? h("udp-icon", { iconName: tab.icon, color: 'inherit' }) : null;
|
|
155
223
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
156
|
-
const
|
|
224
|
+
const labelEl = h("span", null, tab.label);
|
|
157
225
|
return (h("button", { class: {
|
|
158
|
-
'active': index ===
|
|
226
|
+
'active': index === currentActiveTab,
|
|
159
227
|
'has-icon': !!tab.icon,
|
|
160
228
|
[`icon-${tab.iconPlacement}`]: !!tab.icon,
|
|
161
229
|
'disabled': tab.disabled,
|
|
162
|
-
}, disabled: tab.disabled, onClick: () => this.tabClicked(index), role: "tab", "aria-selected": index ===
|
|
163
|
-
}), h("div", { key: '
|
|
230
|
+
}, disabled: tab.disabled, onClick: () => this.tabClicked(index), role: "tab", "aria-selected": index === currentActiveTab ? 'true' : 'false', "aria-disabled": tab.disabled ? 'true' : 'false', ref: el => (this.buttonRefs[index] = el) }, iconEl, labelEl));
|
|
231
|
+
}), h("div", { key: 'df383b17c3e36fc7f261ff6a6c1220a4f923477f', class: "slider", style: this.sliderStyle })), this.showScrollRight && h("div", { key: '7f8ae28f6662266a113adbb7ca40a4ef7d0b8427', class: "scroll-fade right" }), this.showScrollRight && (h("button", { key: '0ad034fb7dc24388476e0c37bc9cf4196f4145bc', class: "scroll-arrow right", onClick: () => this.scrollToEnd(), "aria-label": "Scroll to last tab" }, h("udp-icon", { key: '4cdbf5880b2e30dc6541228323a31e2dd34eabae', iconName: "chevronRight16", color: "inherit" })))), !this.isControlled && !this.useTabsProp && (h("div", { key: '2097c674562eb5acfdadda5a05e6f2eed8821f99' }, h("slot", { key: '375c96eb85f6581426f72bf1c544538df4c6fdd6' })))));
|
|
164
232
|
}
|
|
165
233
|
get el() { return this; }
|
|
166
234
|
static get watchers() { return {
|
|
167
|
-
"
|
|
235
|
+
"internalActiveTab": ["onActiveTabChange"],
|
|
236
|
+
"value": ["onValueChange"],
|
|
237
|
+
"tabs": ["onTabsPropChange"],
|
|
168
238
|
"variant": ["onVariantChange"]
|
|
169
239
|
}; }
|
|
170
240
|
static get style() { return udpTabsCss; }
|
|
171
241
|
}, [257, "udp-tabs", {
|
|
172
242
|
"variant": [1],
|
|
173
|
-
"
|
|
243
|
+
"value": [2],
|
|
244
|
+
"tabs": [16],
|
|
245
|
+
"internalActiveTab": [32],
|
|
174
246
|
"tabDetails": [32],
|
|
175
247
|
"sliderStyle": [32],
|
|
176
248
|
"showScrollLeft": [32],
|
|
177
249
|
"showScrollRight": [32]
|
|
178
250
|
}, [[0, "slotchange", "handleSlotChange"], [9, "resize", "handleResize"]], {
|
|
179
|
-
"
|
|
251
|
+
"internalActiveTab": ["onActiveTabChange"],
|
|
252
|
+
"value": ["onValueChange"],
|
|
253
|
+
"tabs": ["onTabsPropChange"],
|
|
180
254
|
"variant": ["onVariantChange"]
|
|
181
255
|
}]);
|
|
182
256
|
function defineCustomElement() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"file":"udp-tabs2.js","mappings":"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","names":["__stencil_proxyCustomElement","HTMLElement"],"sources":["src/components/my-component/UI/tabs/tab/tabs/udp-tabs.css?tag=udp-tabs&encapsulation=shadow","src/components/my-component/UI/tabs/tab/tabs/udp-tabs.tsx"],"sourcesContent":[".tab-container {\n display: flex;\n flex-direction: column;\n}\n\n.tab-header {\n background-color: #ffffff;\n position: relative;\n display: flex;\n align-items: center;\n}\n\n.tab-scroll-container {\n display: flex;\n position: relative;\n overflow-x: auto;\n overflow-y: hidden;\n flex: 1;\n min-width: 0;\n}\n\n.tab-scroll-container::-webkit-scrollbar {\n height: 4px;\n}\n.tab-scroll-container::-webkit-scrollbar-track {\n background: transparent;\n}\n.tab-scroll-container::-webkit-scrollbar-thumb {\n background-color: rgba(0, 0, 0, 0.2);\n border-radius: 4px;\n}\n.tab-scroll-container::-webkit-scrollbar-thumb:hover {\n background-color: rgba(0, 0, 0, 0.3);\n}\n\n.tab-header::after {\n content: '';\n position: absolute;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 1px;\n background-color: var(--divider-color, #e0e0e0);\n}\n\n/* This is the base style for tab buttons */\n.tab-header button {\n padding: 16px;\n font-size: 14px;\n text-align: center;\n border: none;\n background: none;\n cursor: pointer;\n outline: none;\n transition: all 0.22s ease;\n color: #555555;;\n font-weight: 600;\n opacity: 0.9;\n white-space: nowrap;\n\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n}\n\n.tab-header.fill .tab-scroll-container {\n width: 100%;\n}\n.tab-header.fill .tab-scroll-container button {\n flex-grow: 1;\n}\n\n.tab-header button.active {\n color: var(--secondary-color, #344861);\n opacity: 1.0;\n}\n\n.tab-header button.scroll-arrow {\n position: absolute;\n top: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n\n width: 40px;\n padding: 0;\n\n background: #ffffff;\n cursor: pointer;\n font-size: 16px;\n font-weight: bold;\n color: #757575;\n z-index: 2;\n transition: color 0.2s ease;\n\n flex-shrink: 0;\n opacity: 1;\n gap: 0;\n}\n\n.tab-header button.scroll-arrow:hover {\n color: #000;\n}\n\n.tab-header button.scroll-arrow.left {\n left: 0;\n}\n\n.tab-header button.scroll-arrow.right {\n right: 0;\n\n}\n\n.scroll-fade {\n position: absolute;\n top: 0;\n bottom: 0;\n width: 30px;\n z-index: 1;\n pointer-events: none;\n}\n\n.scroll-fade.left {\n left: 40px;\n background: linear-gradient(\n to right,\n #ffffff,\n rgba(255, 255, 255, 0)\n );\n}\n\n.scroll-fade.right {\n right: 40px;\n background: linear-gradient(\n to left,\n #ffffff,\n rgba(255, 255, 255, 0)\n );\n}\n\n.tab-header button udp-icon {\n font-size: 1.2em;\n line-height: 1;\n}\n\n.tab-header button.icon-start {\n flex-direction: row;\n}\n.tab-header button.icon-end {\n flex-direction: row-reverse;\n}\n.tab-header button.icon-top {\n flex-direction: column;\n gap: 4px;\n}\n.tab-header button.icon-bottom {\n flex-direction: column-reverse;\n gap: 4px;\n}\n\n.tab-content {\n padding: 16px;\n background-color: #ffffff;\n}\n\n.slider {\n position: absolute;\n bottom: 0;\n left: 0;\n height: 2px;\n background-color: var(--secondary-color, #344861);\n\n transition: transform 0.22s cubic-bezier(0.4, 0, 0.2, 1),\n width 0.22s cubic-bezier(0.4, 0, 0.2, 1);\n z-index: 1;\n}\n\n.tab-header button.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.tab-header button.disabled.active {\n color: #757575;\n opacity: 0.5;\n}\n","import { Component, h, State, Element, Watch, Listen, Prop } from '@stencil/core';\n\ninterface TabDetail {\n title: string;\n icon?: string;\n iconPlacement?: 'start' | 'end' | 'top' | 'bottom';\n hidden?: boolean;\n disabled?: boolean;\n}\n\n@Component({\n tag: 'udp-tabs',\n styleUrl: 'udp-tabs.css',\n shadow: true,\n})\nexport class UdpTabs {\n @Element() el: HTMLElement;\n\n /**\n * Specifies the layout variant of the tab header.\n *\n * - `'standard'`: Tabs will be sized based on their content.\n * - `'fill'`: Tabs will stretch to fill the available horizontal space.\n */\n @Prop() variant: 'fill' | 'standard' = 'fill';\n\n @State() activeTab: number = 0;\n @State() tabDetails: TabDetail[] = []; // Uses new interface\n @State() sliderStyle: { width: string; transform: string } = {\n width: '0',\n transform: 'translateX(0)',\n };\n @State() showScrollLeft: boolean = false;\n @State() showScrollRight: boolean = false;\n\n private tabs: HTMLUdpTabElement[] = [];\n private buttonRefs: HTMLButtonElement[] = [];\n private scrollContainerRef?: HTMLDivElement;\n\n @Listen('slotchange')\n handleSlotChange() {\n this.initializeTabs();\n }\n\n @Listen('resize', { target: 'window' })\n handleResize() {\n requestAnimationFrame(() => {\n this.updateSliderPosition();\n this.checkScroll();\n });\n }\n\n componentDidLoad() {\n this.initializeTabs();\n }\n\n @Watch('activeTab')\n onActiveTabChange() {\n this.updateActiveTabs();\n this.updateSliderPosition();\n }\n\n @Watch('variant')\n onVariantChange() {\n requestAnimationFrame(() => {\n this.updateSliderPosition();\n this.checkScroll();\n });\n }\n\n private initializeTabs() {\n this.buttonRefs = [];\n // Get ALL tabs from the slot\n this.tabs = Array.from(this.el.children).filter(\n (child): child is HTMLUdpTabElement => child.tagName.toLowerCase() === 'udp-tab',\n );\n\n this.tabDetails = this.tabs.map(tab => ({\n title: tab.title,\n icon: tab.icon,\n iconPlacement: tab.iconPlacement,\n hidden: tab.hidden,\n disabled: tab.disabled,\n }));\n\n // Check if the current activeTab (default 0) is invalid\n if (this.tabDetails[this.activeTab]?.hidden || this.tabDetails[this.activeTab]?.disabled) {\n // If it is, find the first valid tab to select\n const firstValidIndex = this.tabDetails.findIndex(tab => !tab.hidden && !tab.disabled);\n // If we found one, set it. If not (all tabs invalid), set to -1\n this.activeTab = firstValidIndex;\n }\n\n this.updateActiveTabs();\n\n requestAnimationFrame(() => {\n this.updateSliderPosition();\n this.checkScroll();\n });\n }\n\n private updateActiveTabs() {\n this.tabs.forEach((tab, index) => {\n tab.active = index === this.activeTab;\n });\n }\n\n private updateSliderPosition() {\n const activeButton = this.buttonRefs[this.activeTab];\n if (!activeButton) {\n this.sliderStyle = { width: '0px', transform: 'translateX(0px)' };\n return;\n }\n\n this.sliderStyle = {\n width: `${activeButton.offsetWidth}px`,\n transform: `translateX(${activeButton.offsetLeft}px)`,\n };\n }\n\n private checkScroll() {\n if (!this.scrollContainerRef) return;\n const { scrollLeft, scrollWidth, clientWidth } = this.scrollContainerRef;\n const isOverflowing = scrollWidth > clientWidth;\n this.showScrollLeft = isOverflowing && scrollLeft > 1;\n this.showScrollRight = isOverflowing && scrollLeft < scrollWidth - clientWidth - 1;\n }\n\n private tabClicked(tabIndex: number) {\n if (this.tabDetails[tabIndex]?.disabled) {\n return;\n }\n\n this.activeTab = tabIndex;\n\n const tabButton = this.buttonRefs[tabIndex];\n const container = this.scrollContainerRef;\n\n if (!tabButton || !container) return;\n\n const { scrollLeft, clientWidth } = container;\n const tabLeft = tabButton.offsetLeft;\n const tabRight = tabLeft + tabButton.offsetWidth;\n\n const safeZonePadding = 70;\n\n const safeZoneLeft = scrollLeft + safeZonePadding;\n const safeZoneRight = scrollLeft + clientWidth - safeZonePadding;\n\n // Check if the tab's left edge is hidden by the left fade\n if (tabLeft < safeZoneLeft) {\n // Scroll to position the tab's left edge at the start of the safe zone\n container.scrollTo({\n left: tabLeft - safeZonePadding,\n behavior: 'smooth'\n });\n }\n // Check if the tab's right edge is hidden by the right fade\n else if (tabRight > safeZoneRight) {\n // Scroll to position the tab's right edge at the end of the safe zone\n container.scrollTo({\n left: tabRight - clientWidth + safeZonePadding,\n behavior: 'smooth'\n });\n }\n }\n\n private scrollToStart() {\n if (!this.scrollContainerRef) return;\n this.scrollContainerRef.scrollTo({ left: 0, behavior: 'smooth' });\n }\n\n private scrollToEnd() {\n if (!this.scrollContainerRef) return;\n const container = this.scrollContainerRef;\n const { scrollWidth, clientWidth } = container;\n const maxScrollLeft = scrollWidth - clientWidth;\n container.scrollTo({ left: maxScrollLeft, behavior: 'smooth' });\n }\n\n render() {\n return (\n <div class=\"tab-container\">\n <div class={`tab-header ${this.variant}`}>\n {this.showScrollLeft && (\n <button\n class=\"scroll-arrow left\"\n onClick={() => this.scrollToStart()}\n aria-label=\"Scroll to first tab\"\n >\n <udp-icon iconName=\"chevronLeft16\" color=\"inherit\" />\n </button>\n )}\n\n {this.showScrollLeft && <div class=\"scroll-fade left\"></div>}\n\n <div\n class=\"tab-scroll-container\"\n ref={el => (this.scrollContainerRef = el)}\n onScroll={() => this.checkScroll()}\n >\n {this.tabDetails.map((tab, index) => {\n if (tab.hidden) {\n return null;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const iconEl = tab.icon ? <udp-icon iconName={tab.icon} color={'inherit'} /> : null;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const titleEl = <span>{tab.title}</span>;\n\n return (\n <button\n class={{\n 'active': index === this.activeTab,\n 'has-icon': !!tab.icon,\n [`icon-${tab.iconPlacement}`]: !!tab.icon,\n 'disabled': tab.disabled,\n }}\n disabled={tab.disabled}\n onClick={() => this.tabClicked(index)}\n role=\"tab\"\n aria-selected={index === this.activeTab ? 'true' : 'false'}\n aria-disabled={tab.disabled ? 'true' : 'false'}\n ref={el => (this.buttonRefs[index] = el)}\n >\n {iconEl}\n {titleEl}\n </button>\n );\n })}\n\n <div class=\"slider\" style={this.sliderStyle}></div>\n </div>\n\n {this.showScrollRight && <div class=\"scroll-fade right\"></div>}\n\n {this.showScrollRight && (\n <button\n class=\"scroll-arrow right\"\n onClick={() => this.scrollToEnd()}\n aria-label=\"Scroll to last tab\"\n >\n <udp-icon iconName=\"chevronRight16\" color=\"inherit\" />\n </button>\n )}\n </div>\n <div class=\"tab-content\">\n <slot></slot>\n </div>\n </div>\n );\n }\n}\n"],"version":3}
|
|
1
|
+
{"file":"udp-tabs2.js","mappings":"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","names":["__stencil_proxyCustomElement","HTMLElement"],"sources":["src/components/my-component/UI/tabs/tab/tabs/udp-tabs.css?tag=udp-tabs&encapsulation=shadow","src/components/my-component/UI/tabs/tab/tabs/udp-tabs.tsx"],"sourcesContent":[".tab-container {\n display: flex;\n flex-direction: column;\n}\n\n.tab-header {\n background-color: #ffffff;\n position: relative;\n display: flex;\n align-items: center;\n}\n\n.tab-scroll-container {\n display: flex;\n position: relative;\n overflow-x: auto;\n overflow-y: hidden;\n flex: 1;\n min-width: 0;\n}\n\n.tab-scroll-container::-webkit-scrollbar {\n height: 4px;\n}\n.tab-scroll-container::-webkit-scrollbar-track {\n background: transparent;\n}\n.tab-scroll-container::-webkit-scrollbar-thumb {\n background-color: rgba(0, 0, 0, 0.2);\n border-radius: 4px;\n}\n.tab-scroll-container::-webkit-scrollbar-thumb:hover {\n background-color: rgba(0, 0, 0, 0.3);\n}\n\n.tab-header::after {\n content: '';\n position: absolute;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 1px;\n background-color: var(--divider-color, #e0e0e0);\n}\n\n/* This is the base style for tab buttons */\n.tab-header button {\n padding: 16px;\n font-size: 14px;\n text-align: center;\n border: none;\n background: none;\n cursor: pointer;\n outline: none;\n transition: all 0.22s ease;\n color: #555555;;\n font-weight: 600;\n opacity: 0.9;\n white-space: nowrap;\n\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n}\n\n.tab-header.fill .tab-scroll-container {\n width: 100%;\n}\n.tab-header.fill .tab-scroll-container button {\n flex-grow: 1;\n}\n\n.tab-header button.active {\n color: var(--secondary-color, #344861);\n opacity: 1.0;\n}\n\n.tab-header button.scroll-arrow {\n position: absolute;\n top: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n\n width: 40px;\n padding: 0;\n\n background: #ffffff;\n cursor: pointer;\n font-size: 16px;\n font-weight: bold;\n color: #757575;\n z-index: 2;\n transition: color 0.2s ease;\n\n flex-shrink: 0;\n opacity: 1;\n gap: 0;\n}\n\n.tab-header button.scroll-arrow:hover {\n color: #000;\n}\n\n.tab-header button.scroll-arrow.left {\n left: 0;\n}\n\n.tab-header button.scroll-arrow.right {\n right: 0;\n\n}\n\n.scroll-fade {\n position: absolute;\n top: 0;\n bottom: 0;\n width: 30px;\n z-index: 1;\n pointer-events: none;\n}\n\n.scroll-fade.left {\n left: 40px;\n background: linear-gradient(\n to right,\n #ffffff,\n rgba(255, 255, 255, 0)\n );\n}\n\n.scroll-fade.right {\n right: 40px;\n background: linear-gradient(\n to left,\n #ffffff,\n rgba(255, 255, 255, 0)\n );\n}\n\n.tab-header button udp-icon {\n font-size: 1.2em;\n line-height: 1;\n}\n\n.tab-header button.icon-start {\n flex-direction: row;\n}\n.tab-header button.icon-end {\n flex-direction: row-reverse;\n}\n.tab-header button.icon-top {\n flex-direction: column;\n gap: 4px;\n}\n.tab-header button.icon-bottom {\n flex-direction: column-reverse;\n gap: 4px;\n}\n\n.slider {\n position: absolute;\n bottom: 0;\n left: 0;\n height: 2px;\n background-color: var(--secondary-color, #344861);\n\n transition: transform 0.22s cubic-bezier(0.4, 0, 0.2, 1),\n width 0.22s cubic-bezier(0.4, 0, 0.2, 1);\n z-index: 1;\n}\n\n.tab-header button.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.tab-header button.disabled.active {\n color: #757575;\n opacity: 0.5;\n}\n","import { Component, h, State, Element, Watch, Listen, Prop, Event, EventEmitter } from '@stencil/core';\n\ninterface TabDetail {\n label: string;\n icon?: string;\n iconPlacement?: 'start' | 'end' | 'top' | 'bottom';\n hidden?: boolean;\n disabled?: boolean;\n}\n\n@Component({\n tag: 'udp-tabs',\n styleUrl: 'udp-tabs.css',\n shadow: true,\n})\nexport class UdpTabs {\n @Element() el: HTMLElement;\n\n /**\n * Specifies the layout variant of the tab header.\n *\n * - `'standard'`: Tabs will be sized based on their content.\n * - `'fill'`: Tabs will stretch to fill the available horizontal space.\n */\n @Prop() variant: 'fill' | 'standard' = 'fill';\n\n /**\n * (Controlled) The index of the currently active tab.\n * If this prop is provided, the component will be in \"controlled\" mode.\n * The parent must listen for `udpTabChange` to update this value.\n */\n @Prop() value?: number;\n\n /**\n * (Optional) An array of tab configuration objects.\n * If provided, this will be used to render tabs instead of slotted `<udp-tab>` components.\n * This mode is typically used with controlled tabs.\n */\n @Prop() tabs: TabDetail[] = [];\n\n /**\n * (Controlled) Emits the index of the tab that was clicked.\n * This is only emitted in \"controlled\" mode (when `value` is provided).\n */\n @Event() udpTabChange: EventEmitter<number>;\n\n @State() internalActiveTab: number = 0; // For uncontrolled mode\n @State() tabDetails: TabDetail[] = []; // Unified details from prop or slot\n @State() sliderStyle: { width: string; transform: string } = {\n width: '0',\n transform: 'translateX(0)',\n };\n @State() showScrollLeft: boolean = false;\n @State() showScrollRight: boolean = false;\n\n private slottedTabs: HTMLUdpTabElement[] = []; // Renamed from `tabs`\n private buttonRefs: HTMLButtonElement[] = [];\n private scrollContainerRef?: HTMLDivElement;\n\n /**\n * Returns true if the component is in controlled mode.\n */\n private get isControlled(): boolean {\n return this.value != null;\n }\n\n /**\n * Returns true if tabs are being provided by the `tabs` prop.\n */\n private get useTabsProp(): boolean {\n return this.tabs && this.tabs.length > 0;\n }\n\n /**\n * Returns the currently active tab index,\n * respecting controlled or uncontrolled mode.\n */\n private get activeTab(): number {\n return this.isControlled ? this.value : this.internalActiveTab;\n }\n\n @Listen('slotchange')\n handleSlotChange() {\n // If we're using the tabs prop, slot changes are irrelevant\n if (this.useTabsProp) return;\n this.initializeTabs();\n }\n\n @Listen('resize', { target: 'window' })\n handleResize() {\n requestAnimationFrame(() => {\n this.updateSliderPosition();\n this.checkScroll();\n });\n }\n\n componentDidLoad() {\n this.initializeTabs();\n }\n\n /**\n * Watcher for uncontrolled state changes.\n */\n @Watch('internalActiveTab')\n onActiveTabChange(newValue: number) {\n this.updateActiveTabs();\n this.updateSliderPosition();\n this.scrollTabIntoView(newValue);\n }\n\n /**\n * Watcher for controlled state changes.\n */\n @Watch('value')\n onValueChange(newValue: number) {\n this.updateActiveTabs();\n this.updateSliderPosition();\n this.scrollTabIntoView(newValue);\n }\n\n /**\n * Watcher for tabs prop changes.\n */\n @Watch('tabs')\n onTabsPropChange() {\n this.initializeTabs();\n }\n\n @Watch('variant')\n onVariantChange() {\n requestAnimationFrame(() => {\n this.updateSliderPosition();\n this.checkScroll();\n });\n }\n\n private initializeTabs() {\n this.buttonRefs = [];\n\n if (this.useTabsProp) {\n // --- Prop-based ---\n this.tabDetails = this.tabs.map(t => ({ ...t })); // Use data from prop\n this.slottedTabs = []; // Ensure we're not tracking slotted tabs\n } else {\n // --- Slot-based ---\n this.slottedTabs = Array.from(this.el.children).filter(\n (child): child is HTMLUdpTabElement => child.tagName.toLowerCase() === 'udp-tab',\n );\n\n this.tabDetails = this.slottedTabs.map(tab => ({\n label: tab.label,\n icon: tab.icon,\n iconPlacement: tab.iconPlacement,\n hidden: tab.hidden,\n disabled: tab.disabled,\n }));\n }\n\n // --- Common Logic ---\n // In uncontrolled mode, check if the default active tab is invalid.\n if (!this.isControlled) {\n if (this.tabDetails[this.internalActiveTab]?.hidden || this.tabDetails[this.internalActiveTab]?.disabled) {\n const firstValidIndex = this.tabDetails.findIndex(tab => !tab.hidden && !tab.disabled);\n this.internalActiveTab = firstValidIndex > -1 ? firstValidIndex : 0;\n }\n }\n\n this.updateActiveTabs();\n\n requestAnimationFrame(() => {\n this.updateSliderPosition();\n this.checkScroll();\n });\n }\n\n private updateActiveTabs() {\n // Only update slotted tabs if we're in slot mode\n if (!this.useTabsProp) {\n const currentActiveTab = this.activeTab;\n this.slottedTabs.forEach((tab, index) => {\n tab.active = index === currentActiveTab;\n });\n }\n // If in prop mode, the <button> 'active' class is handled by render()\n }\n\n private updateSliderPosition() {\n const activeButton = this.buttonRefs[this.activeTab]; // Use getter\n if (!activeButton) {\n this.sliderStyle = { width: '0px', transform: 'translateX(0px)' };\n return;\n }\n\n this.sliderStyle = {\n width: `${activeButton.offsetWidth}px`,\n transform: `translateX(${activeButton.offsetLeft}px)`,\n };\n }\n\n private checkScroll() {\n if (!this.scrollContainerRef) return;\n const { scrollLeft, scrollWidth, clientWidth } = this.scrollContainerRef;\n const isOverflowing = scrollWidth > clientWidth;\n this.showScrollLeft = isOverflowing && scrollLeft > 1;\n this.showScrollRight = isOverflowing && scrollLeft < scrollWidth - clientWidth - 1;\n }\n\n private tabClicked(tabIndex: number) {\n if (this.tabDetails[tabIndex]?.disabled) {\n return;\n }\n\n if (this.isControlled) {\n // In controlled mode, emit the event for the parent to handle.\n // The `onValueChange` watcher will handle UI updates when the prop changes.\n this.udpTabChange.emit(tabIndex);\n } else {\n // In uncontrolled mode, update state directly.\n // The `onActiveTabChange` watcher will handle UI updates.\n this.internalActiveTab = tabIndex;\n }\n }\n\n private scrollTabIntoView(tabIndex: number) {\n const tabButton = this.buttonRefs[tabIndex];\n const container = this.scrollContainerRef;\n\n if (!tabButton || !container) return;\n\n const { scrollLeft, clientWidth } = container;\n const tabLeft = tabButton.offsetLeft;\n const tabRight = tabLeft + tabButton.offsetWidth;\n\n const safeZonePadding = 70;\n const safeZoneLeft = scrollLeft + safeZonePadding;\n const safeZoneRight = scrollLeft + clientWidth - safeZonePadding;\n\n if (tabLeft < safeZoneLeft) {\n container.scrollTo({\n left: tabLeft - safeZonePadding,\n behavior: 'smooth',\n });\n } else if (tabRight > safeZoneRight) {\n container.scrollTo({\n left: tabRight - clientWidth + safeZonePadding,\n behavior: 'smooth',\n });\n }\n }\n\n private scrollToStart() {\n if (!this.scrollContainerRef) return;\n this.scrollContainerRef.scrollTo({ left: 0, behavior: 'smooth' });\n }\n\n private scrollToEnd() {\n if (!this.scrollContainerRef) return;\n const container = this.scrollContainerRef;\n const { scrollWidth, clientWidth } = container;\n const maxScrollLeft = scrollWidth - clientWidth;\n container.scrollTo({ left: maxScrollLeft, behavior: 'smooth' });\n }\n\n render() {\n const currentActiveTab = this.activeTab; // Use getter\n\n return (\n <div class=\"tab-container\">\n <div class={`tab-header ${this.variant}`}>\n {this.showScrollLeft && (\n <button\n class=\"scroll-arrow left\"\n onClick={() => this.scrollToStart()}\n aria-label=\"Scroll to first tab\"\n >\n <udp-icon iconName=\"chevronLeft16\" color=\"inherit\" />\n </button>\n )}\n\n {this.showScrollLeft && <div class=\"scroll-fade left\"></div>}\n\n <div\n class=\"tab-scroll-container\"\n ref={el => (this.scrollContainerRef = el)}\n onScroll={() => this.checkScroll()}\n >\n {this.tabDetails.map((tab, index) => {\n if (tab.hidden) {\n return null;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const iconEl = tab.icon ? <udp-icon iconName={tab.icon} color={'inherit'} /> : null;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const labelEl = <span>{tab.label}</span>;\n\n return (\n <button\n class={{\n 'active': index === currentActiveTab,\n 'has-icon': !!tab.icon,\n [`icon-${tab.iconPlacement}`]: !!tab.icon,\n 'disabled': tab.disabled,\n }}\n disabled={tab.disabled}\n onClick={() => this.tabClicked(index)}\n role=\"tab\"\n aria-selected={index === currentActiveTab ? 'true' : 'false'}\n aria-disabled={tab.disabled ? 'true' : 'false'}\n ref={el => (this.buttonRefs[index] = el)}\n >\n {iconEl}\n {labelEl}\n </button>\n );\n })}\n\n <div class=\"slider\" style={this.sliderStyle}></div>\n </div>\n\n {this.showScrollRight && <div class=\"scroll-fade right\"></div>}\n\n {this.showScrollRight && (\n <button\n class=\"scroll-arrow right\"\n onClick={() => this.scrollToEnd()}\n aria-label=\"Scroll to last tab\"\n >\n <udp-icon iconName=\"chevronRight16\" color=\"inherit\" />\n </button>\n )}\n </div>\n\n {!this.isControlled && !this.useTabsProp && (\n <div>\n <slot></slot>\n </div>\n )}\n </div>\n );\n }\n}\n"],"version":3}
|
package/dist/docs.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"timestamp": "2025-11-
|
|
2
|
+
"timestamp": "2025-11-07T23:09:31",
|
|
3
3
|
"compiler": {
|
|
4
4
|
"name": "@stencil/core",
|
|
5
5
|
"version": "4.38.2",
|
|
@@ -46597,7 +46597,7 @@
|
|
|
46597
46597
|
"setter": false
|
|
46598
46598
|
},
|
|
46599
46599
|
{
|
|
46600
|
-
"name": "
|
|
46600
|
+
"name": "label",
|
|
46601
46601
|
"type": "string",
|
|
46602
46602
|
"complexType": {
|
|
46603
46603
|
"original": "string",
|
|
@@ -46605,7 +46605,7 @@
|
|
|
46605
46605
|
"references": {}
|
|
46606
46606
|
},
|
|
46607
46607
|
"mutable": false,
|
|
46608
|
-
"attr": "
|
|
46608
|
+
"attr": "label",
|
|
46609
46609
|
"reflectToAttr": false,
|
|
46610
46610
|
"docs": "The title of the tab, displayed in the tab-header.",
|
|
46611
46611
|
"docsTags": [],
|
|
@@ -46636,6 +46636,72 @@
|
|
|
46636
46636
|
]
|
|
46637
46637
|
}
|
|
46638
46638
|
},
|
|
46639
|
+
{
|
|
46640
|
+
"filePath": "src/components/my-component/UI/tabs/udp-tab-panel/udp-tab-panel.tsx",
|
|
46641
|
+
"encapsulation": "shadow",
|
|
46642
|
+
"tag": "udp-tab-panel",
|
|
46643
|
+
"readme": "# udp-tab-panel\n\n\n",
|
|
46644
|
+
"docs": "",
|
|
46645
|
+
"docsTags": [],
|
|
46646
|
+
"usage": {},
|
|
46647
|
+
"props": [
|
|
46648
|
+
{
|
|
46649
|
+
"name": "index",
|
|
46650
|
+
"type": "number",
|
|
46651
|
+
"complexType": {
|
|
46652
|
+
"original": "number",
|
|
46653
|
+
"resolved": "number",
|
|
46654
|
+
"references": {}
|
|
46655
|
+
},
|
|
46656
|
+
"mutable": false,
|
|
46657
|
+
"attr": "index",
|
|
46658
|
+
"reflectToAttr": false,
|
|
46659
|
+
"docs": "The index this panel corresponds to.",
|
|
46660
|
+
"docsTags": [],
|
|
46661
|
+
"values": [
|
|
46662
|
+
{
|
|
46663
|
+
"type": "number"
|
|
46664
|
+
}
|
|
46665
|
+
],
|
|
46666
|
+
"optional": false,
|
|
46667
|
+
"required": false,
|
|
46668
|
+
"getter": false,
|
|
46669
|
+
"setter": false
|
|
46670
|
+
},
|
|
46671
|
+
{
|
|
46672
|
+
"name": "value",
|
|
46673
|
+
"type": "number",
|
|
46674
|
+
"complexType": {
|
|
46675
|
+
"original": "number",
|
|
46676
|
+
"resolved": "number",
|
|
46677
|
+
"references": {}
|
|
46678
|
+
},
|
|
46679
|
+
"mutable": false,
|
|
46680
|
+
"attr": "value",
|
|
46681
|
+
"reflectToAttr": false,
|
|
46682
|
+
"docs": "The active tab index, provided by the parent.",
|
|
46683
|
+
"docsTags": [],
|
|
46684
|
+
"values": [
|
|
46685
|
+
{
|
|
46686
|
+
"type": "number"
|
|
46687
|
+
}
|
|
46688
|
+
],
|
|
46689
|
+
"optional": false,
|
|
46690
|
+
"required": false,
|
|
46691
|
+
"getter": false,
|
|
46692
|
+
"setter": false
|
|
46693
|
+
}
|
|
46694
|
+
],
|
|
46695
|
+
"methods": [],
|
|
46696
|
+
"events": [],
|
|
46697
|
+
"listeners": [],
|
|
46698
|
+
"styles": [],
|
|
46699
|
+
"slots": [],
|
|
46700
|
+
"parts": [],
|
|
46701
|
+
"dependents": [],
|
|
46702
|
+
"dependencies": [],
|
|
46703
|
+
"dependencyGraph": {}
|
|
46704
|
+
},
|
|
46639
46705
|
{
|
|
46640
46706
|
"filePath": "src/components/my-component/UI/tabs/tab/tabs/udp-tabs.tsx",
|
|
46641
46707
|
"encapsulation": "shadow",
|
|
@@ -46645,6 +46711,62 @@
|
|
|
46645
46711
|
"docsTags": [],
|
|
46646
46712
|
"usage": {},
|
|
46647
46713
|
"props": [
|
|
46714
|
+
{
|
|
46715
|
+
"name": "tabs",
|
|
46716
|
+
"type": "TabDetail[]",
|
|
46717
|
+
"complexType": {
|
|
46718
|
+
"original": "TabDetail[]",
|
|
46719
|
+
"resolved": "TabDetail[]",
|
|
46720
|
+
"references": {
|
|
46721
|
+
"TabDetail": {
|
|
46722
|
+
"location": "global",
|
|
46723
|
+
"id": "global::TabDetail"
|
|
46724
|
+
}
|
|
46725
|
+
}
|
|
46726
|
+
},
|
|
46727
|
+
"mutable": false,
|
|
46728
|
+
"reflectToAttr": false,
|
|
46729
|
+
"docs": "(Optional) An array of tab configuration objects.\nIf provided, this will be used to render tabs instead of slotted `<udp-tab>` components.\nThis mode is typically used with controlled tabs.",
|
|
46730
|
+
"docsTags": [
|
|
46731
|
+
{
|
|
46732
|
+
"name": "default",
|
|
46733
|
+
"text": "[]"
|
|
46734
|
+
}
|
|
46735
|
+
],
|
|
46736
|
+
"default": "[]",
|
|
46737
|
+
"values": [
|
|
46738
|
+
{
|
|
46739
|
+
"type": "TabDetail[]"
|
|
46740
|
+
}
|
|
46741
|
+
],
|
|
46742
|
+
"optional": false,
|
|
46743
|
+
"required": false,
|
|
46744
|
+
"getter": false,
|
|
46745
|
+
"setter": false
|
|
46746
|
+
},
|
|
46747
|
+
{
|
|
46748
|
+
"name": "value",
|
|
46749
|
+
"type": "number",
|
|
46750
|
+
"complexType": {
|
|
46751
|
+
"original": "number",
|
|
46752
|
+
"resolved": "number",
|
|
46753
|
+
"references": {}
|
|
46754
|
+
},
|
|
46755
|
+
"mutable": false,
|
|
46756
|
+
"attr": "value",
|
|
46757
|
+
"reflectToAttr": false,
|
|
46758
|
+
"docs": "(Controlled) The index of the currently active tab.\nIf this prop is provided, the component will be in \"controlled\" mode.\nThe parent must listen for `udpTabChange` to update this value.",
|
|
46759
|
+
"docsTags": [],
|
|
46760
|
+
"values": [
|
|
46761
|
+
{
|
|
46762
|
+
"type": "number"
|
|
46763
|
+
}
|
|
46764
|
+
],
|
|
46765
|
+
"optional": true,
|
|
46766
|
+
"required": false,
|
|
46767
|
+
"getter": false,
|
|
46768
|
+
"setter": false
|
|
46769
|
+
},
|
|
46648
46770
|
{
|
|
46649
46771
|
"name": "variant",
|
|
46650
46772
|
"type": "\"fill\" | \"standard\"",
|
|
@@ -46681,7 +46803,22 @@
|
|
|
46681
46803
|
}
|
|
46682
46804
|
],
|
|
46683
46805
|
"methods": [],
|
|
46684
|
-
"events": [
|
|
46806
|
+
"events": [
|
|
46807
|
+
{
|
|
46808
|
+
"event": "udpTabChange",
|
|
46809
|
+
"detail": "number",
|
|
46810
|
+
"bubbles": true,
|
|
46811
|
+
"complexType": {
|
|
46812
|
+
"original": "number",
|
|
46813
|
+
"resolved": "number",
|
|
46814
|
+
"references": {}
|
|
46815
|
+
},
|
|
46816
|
+
"cancelable": true,
|
|
46817
|
+
"composed": true,
|
|
46818
|
+
"docs": "(Controlled) Emits the index of the tab that was clicked.\nThis is only emitted in \"controlled\" mode (when `value` is provided).",
|
|
46819
|
+
"docsTags": []
|
|
46820
|
+
}
|
|
46821
|
+
],
|
|
46685
46822
|
"listeners": [
|
|
46686
46823
|
{
|
|
46687
46824
|
"event": "slotchange",
|