@sekiui/elements 0.1.6 → 0.1.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/accordion-ids-Cjq6aIVd.js +42 -0
- package/dist/cjs/direction-Dt-r6_ec.js +14 -0
- package/dist/cjs/host-id-C3XieWsk.js +32 -0
- package/dist/cjs/layout-DR0fTNAb.js +109 -0
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/seki-accordion-content.cjs.entry.js +27 -25
- package/dist/cjs/seki-accordion-item.cjs.entry.js +13 -29
- package/dist/cjs/seki-accordion-trigger.cjs.entry.js +36 -28
- package/dist/cjs/seki-accordion.cjs.entry.js +18 -12
- package/dist/cjs/seki-carousel-dots.cjs.entry.js +15 -7
- package/dist/cjs/seki-carousel-next.cjs.entry.js +1 -1
- package/dist/cjs/seki-carousel-previous.cjs.entry.js +1 -1
- package/dist/cjs/seki-carousel.cjs.entry.js +51 -6
- package/dist/cjs/seki-combobox.cjs.entry.js +80 -1
- package/dist/cjs/seki-context-menu-content.cjs.entry.js +13 -16
- package/dist/cjs/seki-context-menu.cjs.entry.js +14 -9
- package/dist/cjs/seki-dropdown-menu-content.cjs.entry.js +13 -16
- package/dist/cjs/seki-dropdown-menu-trigger.cjs.entry.js +7 -15
- package/dist/cjs/seki-dropdown-menu.cjs.entry.js +14 -9
- package/dist/cjs/seki-hover-card-content.cjs.entry.js +27 -33
- package/dist/cjs/seki-hover-card-trigger.cjs.entry.js +10 -25
- package/dist/cjs/seki-hover-card.cjs.entry.js +7 -6
- package/dist/cjs/seki-radio-group-item.cjs.entry.js +18 -1
- package/dist/cjs/seki-radio-group.cjs.entry.js +8 -1
- package/dist/cjs/seki-resizable-handle.cjs.entry.js +72 -15
- package/dist/cjs/seki-resizable-panel-group.cjs.entry.js +11 -107
- package/dist/cjs/seki-resizable-panel.cjs.entry.js +5 -3
- package/dist/cjs/seki-tabs-content.cjs.entry.js +21 -19
- package/dist/cjs/seki-tabs-list.cjs.entry.js +8 -24
- package/dist/cjs/seki-tabs-trigger.cjs.entry.js +23 -31
- package/dist/cjs/seki-tabs.cjs.entry.js +15 -18
- package/dist/cjs/sekiui.cjs.js +1 -1
- package/dist/cjs/{tab-ids-BzpIZnUS.js → tab-ids-BOdn1Fu2.js} +14 -0
- package/dist/collection/collection-manifest.json +2 -2
- package/dist/collection/components/accordion/accordion-ids.js +36 -0
- package/dist/collection/components/accordion/seki-accordion-content.js +27 -25
- package/dist/collection/components/accordion/seki-accordion-item.js +12 -29
- package/dist/collection/components/accordion/seki-accordion-trigger.css +6 -2
- package/dist/collection/components/accordion/seki-accordion-trigger.js +37 -28
- package/dist/collection/components/accordion/seki-accordion.js +40 -11
- package/dist/collection/components/carousel/seki-carousel-dots.js +15 -7
- package/dist/collection/components/carousel/seki-carousel-navigation.css +9 -4
- package/dist/collection/components/carousel/seki-carousel.js +51 -6
- package/dist/collection/components/combobox/seki-combobox.js +103 -1
- package/dist/collection/components/context-menu/seki-context-menu-content.js +13 -16
- package/dist/collection/components/context-menu/seki-context-menu.js +31 -9
- package/dist/collection/components/dropdown-menu/seki-dropdown-menu-content.js +13 -16
- package/dist/collection/components/dropdown-menu/seki-dropdown-menu-trigger.js +7 -15
- package/dist/collection/components/dropdown-menu/seki-dropdown-menu.js +31 -9
- package/dist/collection/components/hover-card/seki-hover-card-content.js +27 -33
- package/dist/collection/components/hover-card/seki-hover-card-trigger.js +10 -25
- package/dist/collection/components/hover-card/seki-hover-card.js +24 -6
- package/dist/collection/components/radio-group/seki-radio-group-item.js +18 -1
- package/dist/collection/components/radio-group/seki-radio-group.js +25 -1
- package/dist/collection/components/resizable/layout.js +2 -0
- package/dist/collection/components/resizable/seki-resizable-handle.css +6 -2
- package/dist/collection/components/resizable/seki-resizable-handle.js +71 -14
- package/dist/collection/components/resizable/seki-resizable-panel-group.js +5 -2
- package/dist/collection/components/resizable/seki-resizable-panel.js +5 -3
- package/dist/collection/components/tabs/seki-tabs-content.js +24 -19
- package/dist/collection/components/tabs/seki-tabs-list.js +8 -24
- package/dist/collection/components/tabs/seki-tabs-trigger.js +24 -19
- package/dist/collection/components/tabs/seki-tabs.js +34 -18
- package/dist/collection/components/tabs/tab-ids.js +13 -0
- package/dist/collection/utils/host-id.js +27 -0
- package/dist/components/p-BD28aG2U.js +12 -0
- package/dist/components/p-BuvZJ6_r.js +39 -0
- package/dist/components/p-DmN32Mrm.js +103 -0
- package/dist/components/{p-CmuSriLz.js → p-bxPJJ6k4.js} +14 -1
- package/dist/components/p-ppXRAghy.js +29 -0
- package/dist/components/seki-accordion-content.js +27 -25
- package/dist/components/seki-accordion-item.js +12 -29
- package/dist/components/seki-accordion-trigger.js +38 -29
- package/dist/components/seki-accordion.js +22 -13
- package/dist/components/seki-carousel-dots.js +15 -7
- package/dist/components/seki-carousel-next.js +1 -1
- package/dist/components/seki-carousel-previous.js +1 -1
- package/dist/components/seki-carousel.js +51 -6
- package/dist/components/seki-combobox.js +81 -2
- package/dist/components/seki-context-menu-content.js +13 -16
- package/dist/components/seki-context-menu.js +14 -9
- package/dist/components/seki-dropdown-menu-content.js +13 -16
- package/dist/components/seki-dropdown-menu-trigger.js +7 -15
- package/dist/components/seki-dropdown-menu.js +14 -9
- package/dist/components/seki-hover-card-content.js +27 -33
- package/dist/components/seki-hover-card-trigger.js +10 -25
- package/dist/components/seki-hover-card.js +7 -6
- package/dist/components/seki-radio-group-item.js +18 -1
- package/dist/components/seki-radio-group.js +8 -1
- package/dist/components/seki-resizable-handle.js +72 -15
- package/dist/components/seki-resizable-panel-group.js +6 -102
- package/dist/components/seki-resizable-panel.js +5 -3
- package/dist/components/seki-tabs-content.js +23 -19
- package/dist/components/seki-tabs-list.js +8 -24
- package/dist/components/seki-tabs-trigger.js +25 -31
- package/dist/components/seki-tabs.js +16 -18
- package/dist/esm/accordion-ids-D58tRFZv.js +39 -0
- package/dist/esm/direction-BD28aG2U.js +12 -0
- package/dist/esm/host-id-ppXRAghy.js +29 -0
- package/dist/esm/layout-DmN32Mrm.js +103 -0
- package/dist/esm/loader.js +1 -1
- package/dist/esm/seki-accordion-content.entry.js +27 -25
- package/dist/esm/seki-accordion-item.entry.js +13 -29
- package/dist/esm/seki-accordion-trigger.entry.js +36 -28
- package/dist/esm/seki-accordion.entry.js +18 -12
- package/dist/esm/seki-carousel-dots.entry.js +15 -7
- package/dist/esm/seki-carousel-next.entry.js +1 -1
- package/dist/esm/seki-carousel-previous.entry.js +1 -1
- package/dist/esm/seki-carousel.entry.js +51 -6
- package/dist/esm/seki-combobox.entry.js +80 -1
- package/dist/esm/seki-context-menu-content.entry.js +13 -16
- package/dist/esm/seki-context-menu.entry.js +14 -9
- package/dist/esm/seki-dropdown-menu-content.entry.js +13 -16
- package/dist/esm/seki-dropdown-menu-trigger.entry.js +7 -15
- package/dist/esm/seki-dropdown-menu.entry.js +14 -9
- package/dist/esm/seki-hover-card-content.entry.js +27 -33
- package/dist/esm/seki-hover-card-trigger.entry.js +10 -25
- package/dist/esm/seki-hover-card.entry.js +7 -6
- package/dist/esm/seki-radio-group-item.entry.js +18 -1
- package/dist/esm/seki-radio-group.entry.js +8 -1
- package/dist/esm/seki-resizable-handle.entry.js +72 -15
- package/dist/esm/seki-resizable-panel-group.entry.js +6 -102
- package/dist/esm/seki-resizable-panel.entry.js +5 -3
- package/dist/esm/seki-tabs-content.entry.js +21 -19
- package/dist/esm/seki-tabs-list.entry.js +8 -24
- package/dist/esm/seki-tabs-trigger.entry.js +22 -30
- package/dist/esm/seki-tabs.entry.js +15 -18
- package/dist/esm/sekiui.js +1 -1
- package/dist/esm/{tab-ids-CmuSriLz.js → tab-ids-bxPJJ6k4.js} +14 -1
- package/dist/sekiui/p-05646b3d.entry.js +1 -0
- package/dist/sekiui/p-06307251.entry.js +1 -0
- package/dist/sekiui/p-13206751.entry.js +1 -0
- package/dist/sekiui/p-2681547f.entry.js +1 -0
- package/dist/sekiui/p-34880473.entry.js +1 -0
- package/dist/sekiui/{p-3a950a93.entry.js → p-44c4e0ca.entry.js} +1 -1
- package/dist/sekiui/p-45d3e21b.entry.js +1 -0
- package/dist/sekiui/p-5a222bfa.entry.js +1 -0
- package/dist/sekiui/p-68d2ef55.entry.js +1 -0
- package/dist/sekiui/p-78df4dc1.entry.js +1 -0
- package/dist/sekiui/p-81e180e1.entry.js +1 -0
- package/dist/sekiui/{p-5cb2a9fc.entry.js → p-99aba093.entry.js} +1 -1
- package/dist/sekiui/p-BD28aG2U.js +1 -0
- package/dist/sekiui/p-BuvZJ6_r.js +1 -0
- package/dist/sekiui/p-DmN32Mrm.js +1 -0
- package/dist/sekiui/p-ad26ccd9.entry.js +1 -0
- package/dist/sekiui/p-b3260d62.entry.js +1 -0
- package/dist/sekiui/p-bxPJJ6k4.js +1 -0
- package/dist/sekiui/{p-d26b63d0.entry.js → p-c906ad1e.entry.js} +1 -1
- package/dist/sekiui/p-cb621f86.entry.js +1 -0
- package/dist/sekiui/p-d4863b02.entry.js +1 -0
- package/dist/sekiui/p-d81d442f.entry.js +1 -0
- package/dist/sekiui/p-d9a625f4.entry.js +1 -0
- package/dist/sekiui/p-db922f6f.entry.js +1 -0
- package/dist/sekiui/p-e1fbadc1.entry.js +1 -0
- package/dist/sekiui/p-e3dc7f49.entry.js +1 -0
- package/dist/sekiui/{p-8a96f54c.entry.js → p-ea8654dc.entry.js} +1 -1
- package/dist/sekiui/p-eb76021c.entry.js +1 -0
- package/dist/sekiui/p-f049f47a.entry.js +1 -0
- package/dist/sekiui/p-f0650660.entry.js +1 -0
- package/dist/sekiui/p-ppXRAghy.js +1 -0
- package/dist/sekiui/sekiui.esm.js +1 -1
- package/dist/types/components/accordion/accordion-ids.d.ts +17 -0
- package/dist/types/components/accordion/seki-accordion-content.d.ts +3 -3
- package/dist/types/components/accordion/seki-accordion-item.d.ts +2 -9
- package/dist/types/components/accordion/seki-accordion-trigger.d.ts +4 -4
- package/dist/types/components/accordion/seki-accordion.d.ts +7 -2
- package/dist/types/components/carousel/seki-carousel.d.ts +10 -0
- package/dist/types/components/combobox/seki-combobox.d.ts +13 -0
- package/dist/types/components/context-menu/seki-context-menu-content.d.ts +3 -3
- package/dist/types/components/context-menu/seki-context-menu.d.ts +6 -0
- package/dist/types/components/dropdown-menu/seki-dropdown-menu-content.d.ts +3 -3
- package/dist/types/components/dropdown-menu/seki-dropdown-menu-trigger.d.ts +2 -4
- package/dist/types/components/dropdown-menu/seki-dropdown-menu.d.ts +6 -0
- package/dist/types/components/hover-card/seki-hover-card-content.d.ts +3 -1
- package/dist/types/components/hover-card/seki-hover-card-trigger.d.ts +2 -2
- package/dist/types/components/hover-card/seki-hover-card.d.ts +5 -1
- package/dist/types/components/radio-group/seki-radio-group-item.d.ts +3 -0
- package/dist/types/components/radio-group/seki-radio-group.d.ts +14 -0
- package/dist/types/components/resizable/layout.d.ts +2 -0
- package/dist/types/components/resizable/seki-resizable-handle.d.ts +13 -0
- package/dist/types/components/resizable/seki-resizable-panel-group.d.ts +1 -0
- package/dist/types/components/resizable/types.d.ts +2 -0
- package/dist/types/components/tabs/seki-tabs-content.d.ts +3 -4
- package/dist/types/components/tabs/seki-tabs-list.d.ts +2 -5
- package/dist/types/components/tabs/seki-tabs-trigger.d.ts +3 -4
- package/dist/types/components/tabs/seki-tabs.d.ts +8 -2
- package/dist/types/components/tabs/tab-ids.d.ts +5 -0
- package/dist/types/components.d.ts +14 -0
- package/dist/types/utils/host-id.d.ts +7 -0
- package/package.json +1 -1
- package/dist/sekiui/p-00ed0a52.entry.js +0 -1
- package/dist/sekiui/p-02fe58f7.entry.js +0 -1
- package/dist/sekiui/p-044e875d.entry.js +0 -1
- package/dist/sekiui/p-1971d77d.entry.js +0 -1
- package/dist/sekiui/p-233a4393.entry.js +0 -1
- package/dist/sekiui/p-2622ca4c.entry.js +0 -1
- package/dist/sekiui/p-28c64e07.entry.js +0 -1
- package/dist/sekiui/p-2bd22398.entry.js +0 -1
- package/dist/sekiui/p-368d2d15.entry.js +0 -1
- package/dist/sekiui/p-49742de9.entry.js +0 -1
- package/dist/sekiui/p-5bfb96fd.entry.js +0 -1
- package/dist/sekiui/p-5e596590.entry.js +0 -1
- package/dist/sekiui/p-78c8c4bf.entry.js +0 -1
- package/dist/sekiui/p-88ba7051.entry.js +0 -1
- package/dist/sekiui/p-90387022.entry.js +0 -1
- package/dist/sekiui/p-CmuSriLz.js +0 -1
- package/dist/sekiui/p-af71afe5.entry.js +0 -1
- package/dist/sekiui/p-b26b3102.entry.js +0 -1
- package/dist/sekiui/p-b43f6733.entry.js +0 -1
- package/dist/sekiui/p-bf687983.entry.js +0 -1
- package/dist/sekiui/p-eafe8a84.entry.js +0 -1
- package/dist/sekiui/p-ec0d8978.entry.js +0 -1
- package/dist/sekiui/p-f418ba3a.entry.js +0 -1
|
@@ -801,11 +801,15 @@
|
|
|
801
801
|
}
|
|
802
802
|
|
|
803
803
|
.resizable-handle:hover:not(.resizable-handle--disabled),
|
|
804
|
-
.resizable-handle:
|
|
804
|
+
:host(:focus-visible) .resizable-handle:not(.resizable-handle--disabled) {
|
|
805
805
|
background: var(--seki-primary, hsl(240 5.9% 10%));
|
|
806
806
|
}
|
|
807
807
|
|
|
808
|
-
|
|
808
|
+
:host {
|
|
809
|
+
outline: none;
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
:host(:focus-visible) .resizable-handle {
|
|
809
813
|
outline: 2px solid var(--seki-ring, hsl(240 5% 64.9%));
|
|
810
814
|
outline-offset: 2px;
|
|
811
815
|
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
// src/components/resizable/seki-resizable-handle.tsx
|
|
2
2
|
import { h, Host } from "@stencil/core";
|
|
3
3
|
import { subscribeToContextChange } from "../../utils/context-bridge";
|
|
4
|
+
import { isRtl } from "../../utils/direction";
|
|
5
|
+
import { effectiveHostId } from "../../utils/host-id";
|
|
6
|
+
import { panelHostId } from "./layout";
|
|
4
7
|
/**
|
|
5
8
|
* Resizable handle - draggable divider between panels
|
|
6
9
|
*
|
|
@@ -23,6 +26,9 @@ export class SekiResizableHandle {
|
|
|
23
26
|
this._direction = 'horizontal';
|
|
24
27
|
this.startPosition = 0;
|
|
25
28
|
this.groupElement = null;
|
|
29
|
+
this.loaded = false;
|
|
30
|
+
// The aria-label we generated on the host; any other value is the author's.
|
|
31
|
+
this.ownLabel = null;
|
|
26
32
|
this.contextSubscription = null;
|
|
27
33
|
this.handleDirectionChange = () => {
|
|
28
34
|
const context = this.getContext();
|
|
@@ -52,7 +58,10 @@ export class SekiResizableHandle {
|
|
|
52
58
|
if (!context || !this.groupElement)
|
|
53
59
|
return;
|
|
54
60
|
const currentPosition = this._direction === 'horizontal' ? event.clientX : event.clientY;
|
|
55
|
-
|
|
61
|
+
// A horizontal group lays its panels out right-to-left under dir="rtl", so
|
|
62
|
+
// moving the pointer right shrinks the panel before the handle.
|
|
63
|
+
const flip = this._direction === 'horizontal' && isRtl(this.el) ? -1 : 1;
|
|
64
|
+
const deltaPixels = (currentPosition - this.startPosition) * flip;
|
|
56
65
|
// Convert to percentage
|
|
57
66
|
const groupRect = this.groupElement.getBoundingClientRect();
|
|
58
67
|
const groupSize = this._direction === 'horizontal' ? groupRect.width : groupRect.height;
|
|
@@ -82,13 +91,34 @@ export class SekiResizableHandle {
|
|
|
82
91
|
this._direction = context.direction;
|
|
83
92
|
}
|
|
84
93
|
}
|
|
85
|
-
|
|
94
|
+
/** (Re)bind to the enclosing group; also runs after the handle is moved. */
|
|
95
|
+
attach() {
|
|
86
96
|
const group = this.el.closest('seki-resizable-panel-group');
|
|
87
|
-
if (group)
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
97
|
+
if (!group || group === this.groupElement)
|
|
98
|
+
return;
|
|
99
|
+
this.detach();
|
|
100
|
+
this.groupElement = group;
|
|
101
|
+
group.addEventListener('sekiDirectionChange', this.handleDirectionChange);
|
|
102
|
+
group.addEventListener('sekiLayoutChange', this.handleLayoutChange);
|
|
103
|
+
}
|
|
104
|
+
detach() {
|
|
105
|
+
if (this.groupElement) {
|
|
106
|
+
this.groupElement.removeEventListener('sekiDirectionChange', this.handleDirectionChange);
|
|
107
|
+
this.groupElement.removeEventListener('sekiLayoutChange', this.handleLayoutChange);
|
|
91
108
|
}
|
|
109
|
+
this.groupElement = null;
|
|
110
|
+
}
|
|
111
|
+
connectedCallback() {
|
|
112
|
+
// Re-wire after a DOM move; componentDidLoad only fires once.
|
|
113
|
+
if (this.loaded) {
|
|
114
|
+
this.attach();
|
|
115
|
+
this.handleDirectionChange();
|
|
116
|
+
this.handleLayoutChange();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
componentDidLoad() {
|
|
120
|
+
this.loaded = true;
|
|
121
|
+
this.attach();
|
|
92
122
|
// Pick up the direction once the group publishes its context, which may be
|
|
93
123
|
// after this handle loaded in the per-tag custom-elements build.
|
|
94
124
|
this.contextSubscription = subscribeToContextChange(this.el, 'seki-resizable-panel-group', this.handleDirectionChange);
|
|
@@ -96,10 +126,7 @@ export class SekiResizableHandle {
|
|
|
96
126
|
}
|
|
97
127
|
disconnectedCallback() {
|
|
98
128
|
var _a;
|
|
99
|
-
|
|
100
|
-
this.groupElement.removeEventListener('sekiDirectionChange', this.handleDirectionChange);
|
|
101
|
-
this.groupElement.removeEventListener('sekiLayoutChange', this.handleLayoutChange);
|
|
102
|
-
}
|
|
129
|
+
this.detach();
|
|
103
130
|
(_a = this.contextSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
|
|
104
131
|
this.contextSubscription = null;
|
|
105
132
|
}
|
|
@@ -113,20 +140,22 @@ export class SekiResizableHandle {
|
|
|
113
140
|
if (handleIndex === -1)
|
|
114
141
|
return;
|
|
115
142
|
const isHorizontal = this._direction === 'horizontal';
|
|
143
|
+
// Arrow keys are visual; in RTL the panel before the handle is on the right.
|
|
144
|
+
const flip = isHorizontal && isRtl(this.el) ? -1 : 1;
|
|
116
145
|
const smallStep = 1;
|
|
117
146
|
const largeStep = 10;
|
|
118
147
|
switch (event.key) {
|
|
119
148
|
case 'ArrowLeft':
|
|
120
149
|
if (isHorizontal) {
|
|
121
150
|
event.preventDefault();
|
|
122
|
-
const step = event.shiftKey ? -largeStep : -smallStep;
|
|
151
|
+
const step = (event.shiftKey ? -largeStep : -smallStep) * flip;
|
|
123
152
|
context.resizePanels(handleIndex, step);
|
|
124
153
|
}
|
|
125
154
|
break;
|
|
126
155
|
case 'ArrowRight':
|
|
127
156
|
if (isHorizontal) {
|
|
128
157
|
event.preventDefault();
|
|
129
|
-
const step = event.shiftKey ? largeStep : smallStep;
|
|
158
|
+
const step = (event.shiftKey ? largeStep : smallStep) * flip;
|
|
130
159
|
context.resizePanels(handleIndex, step);
|
|
131
160
|
}
|
|
132
161
|
break;
|
|
@@ -163,16 +192,44 @@ export class SekiResizableHandle {
|
|
|
163
192
|
return { now: 50, min: 0, max: 100 };
|
|
164
193
|
return { now: Math.round(range.now), min: Math.round(range.min), max: Math.round(range.max) };
|
|
165
194
|
}
|
|
195
|
+
/**
|
|
196
|
+
* WAI-ARIA window splitter: the separator controls the primary pane (the one
|
|
197
|
+
* before it). IDREFs cannot cross shadow roots, so everything lives on this
|
|
198
|
+
* light-DOM host and points at the panel host in the same tree scope.
|
|
199
|
+
*/
|
|
200
|
+
getControlled() {
|
|
201
|
+
const context = this.getContext();
|
|
202
|
+
if (!context)
|
|
203
|
+
return { id: null, label: null };
|
|
204
|
+
const panelId = context.getPanelOrder()[context.getHandleIndex(this.el)];
|
|
205
|
+
const panel = panelId ? context.getPanelElement(panelId) : null;
|
|
206
|
+
if (!panelId || !panel)
|
|
207
|
+
return { id: null, label: null };
|
|
208
|
+
return {
|
|
209
|
+
id: effectiveHostId(panel, panelHostId(panelId)),
|
|
210
|
+
label: panel.getAttribute('aria-label'),
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
resolveLabel(controlledLabel) {
|
|
214
|
+
const current = this.el.getAttribute('aria-label');
|
|
215
|
+
if (current !== null && current !== this.ownLabel)
|
|
216
|
+
return current; // author-provided
|
|
217
|
+
this.ownLabel = controlledLabel || 'Resize handle';
|
|
218
|
+
return this.ownLabel;
|
|
219
|
+
}
|
|
166
220
|
render() {
|
|
221
|
+
var _a, _b;
|
|
167
222
|
const isHorizontal = this._direction === 'horizontal';
|
|
168
223
|
const range = this.getAriaRange();
|
|
169
|
-
|
|
224
|
+
const controlled = this.getControlled();
|
|
225
|
+
const isDisabled = this.disabled || !!((_a = this.getContext()) === null || _a === void 0 ? void 0 : _a.disabled);
|
|
226
|
+
return (h(Host, { key: 'd5d598d73db57d447393e478c4bcbad036cabc21', role: "separator", tabindex: isDisabled ? -1 : 0, "aria-valuenow": range.now, "aria-valuemin": range.min, "aria-valuemax": range.max, "aria-orientation": isHorizontal ? 'vertical' : 'horizontal', "aria-label": this.resolveLabel(controlled.label), "aria-controls": (_b = controlled.id) !== null && _b !== void 0 ? _b : undefined, "aria-disabled": isDisabled ? 'true' : undefined }, h("div", { key: '29f8a250bf62aadc3ad5a436935367f9b26cd7da', part: "handle", class: {
|
|
170
227
|
'resizable-handle': true,
|
|
171
228
|
'resizable-handle--horizontal': isHorizontal,
|
|
172
229
|
'resizable-handle--vertical': !isHorizontal,
|
|
173
230
|
'resizable-handle--disabled': this.disabled,
|
|
174
231
|
'resizable-handle--dragging': this._isDragging,
|
|
175
|
-
}, onPointerDown: this.handlePointerDown, onPointerMove: this.handlePointerMove, onPointerUp: this.handlePointerUp }, this.withHandle && (h("div", { key: '
|
|
232
|
+
}, onPointerDown: this.handlePointerDown, onPointerMove: this.handlePointerMove, onPointerUp: this.handlePointerUp }, this.withHandle && (h("div", { key: '65c10331e9f97979b272b1dc83c9a122939fc437', part: "grip", class: "resizable-handle__grip" }, h("svg", { key: '3c02d5f8bd72bc7e9549f251168dc6a6de081dad', class: "resizable-handle__grip-icon", viewBox: "0 0 6 16", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, h("circle", { key: '380a11b2cf250b6190734083e5f05ba0c00b4dde', cx: "1.5", cy: "2", r: "1", fill: "currentColor" }), h("circle", { key: 'bc169db3f5d287264797dd56da8374ea35663327', cx: "4.5", cy: "2", r: "1", fill: "currentColor" }), h("circle", { key: '626d7dfa182d9f1f1248e7cea476378e645fbc5b', cx: "1.5", cy: "6", r: "1", fill: "currentColor" }), h("circle", { key: 'd95b05917be3964f1c3c1d5abf8969aa667dab65', cx: "4.5", cy: "6", r: "1", fill: "currentColor" }), h("circle", { key: 'f98ecea62129e2af13ff87f59407f7c150384357', cx: "1.5", cy: "10", r: "1", fill: "currentColor" }), h("circle", { key: '5f7f37ed7a8d8afe81444cfe7a412719ed9f0b7f', cx: "4.5", cy: "10", r: "1", fill: "currentColor" }), h("circle", { key: '06941c191e2bb1273dffd15d956dd43faf4fadb6', cx: "1.5", cy: "14", r: "1", fill: "currentColor" }), h("circle", { key: '7e96b8f034b59242f98f5e4b5b97578301a5e35e', cx: "4.5", cy: "14", r: "1", fill: "currentColor" })))))));
|
|
176
233
|
}
|
|
177
234
|
static get is() { return "seki-resizable-handle"; }
|
|
178
235
|
static get encapsulation() { return "shadow"; }
|
|
@@ -44,6 +44,7 @@ export class SekiResizablePanelGroup {
|
|
|
44
44
|
collapsePanel: () => { },
|
|
45
45
|
expandPanel: () => { },
|
|
46
46
|
isCollapsed: () => false,
|
|
47
|
+
getPanelElement: () => null,
|
|
47
48
|
getHandleIndex: () => -1,
|
|
48
49
|
};
|
|
49
50
|
this.registerPanel = (id, constraints, element) => {
|
|
@@ -92,6 +93,7 @@ export class SekiResizablePanelGroup {
|
|
|
92
93
|
var _a, _b;
|
|
93
94
|
return (_b = (_a = this._panels.get(id)) === null || _a === void 0 ? void 0 : _a.isCollapsed) !== null && _b !== void 0 ? _b : false;
|
|
94
95
|
};
|
|
96
|
+
this.getPanelElement = (id) => { var _a; return (_a = this.panelElements.get(id)) !== null && _a !== void 0 ? _a : null; };
|
|
95
97
|
this.getHandleIndex = (handleElement) => {
|
|
96
98
|
const handles = Array.from(this.el.querySelectorAll('seki-resizable-handle'));
|
|
97
99
|
return handles.indexOf(handleElement);
|
|
@@ -267,6 +269,7 @@ export class SekiResizablePanelGroup {
|
|
|
267
269
|
collapsePanel: this.collapsePanel,
|
|
268
270
|
expandPanel: this.expandPanel,
|
|
269
271
|
isCollapsed: this.isCollapsed,
|
|
272
|
+
getPanelElement: this.getPanelElement,
|
|
270
273
|
getHandleIndex: this.getHandleIndex,
|
|
271
274
|
};
|
|
272
275
|
this._resizableContext = context;
|
|
@@ -332,11 +335,11 @@ export class SekiResizablePanelGroup {
|
|
|
332
335
|
}
|
|
333
336
|
}
|
|
334
337
|
render() {
|
|
335
|
-
return (h(Host, { key: '
|
|
338
|
+
return (h(Host, { key: 'e921bd4bf9566022d1b1df8b15e65fbe446a8eaf' }, h("div", { key: 'e54ea8623bba0ec7c7a4b8d2666ebcc4d2071859', part: "group", role: "group", "aria-label": "Resizable panel group", class: {
|
|
336
339
|
'resizable-panel-group': true,
|
|
337
340
|
'resizable-panel-group--horizontal': this.direction === 'horizontal',
|
|
338
341
|
'resizable-panel-group--vertical': this.direction === 'vertical',
|
|
339
|
-
} }, h("slot", { key: '
|
|
342
|
+
} }, h("slot", { key: '3c289f22bccadb3d1fe418b221619f2dc60791fe' }))));
|
|
340
343
|
}
|
|
341
344
|
static get is() { return "seki-resizable-panel-group"; }
|
|
342
345
|
static get encapsulation() { return "shadow"; }
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// src/components/resizable/seki-resizable-panel.tsx
|
|
2
2
|
import { h, Host } from "@stencil/core";
|
|
3
3
|
import { subscribeToContextChange } from "../../utils/context-bridge";
|
|
4
|
+
import { claimHostId } from "../../utils/host-id";
|
|
5
|
+
import { panelHostId } from "./layout";
|
|
4
6
|
let panelIdCounter = 0;
|
|
5
7
|
/**
|
|
6
8
|
* Resizable panel - individual content panel with size constraints
|
|
@@ -168,14 +170,14 @@ export class SekiResizablePanel {
|
|
|
168
170
|
return this.panelId;
|
|
169
171
|
}
|
|
170
172
|
render() {
|
|
171
|
-
return (h(Host, { key: '
|
|
173
|
+
return (h(Host, { key: '315770a2c0d1a43476a411d128bba7a1e0c8340d', id: claimHostId(this.el, panelHostId(this.panelId)), style: {
|
|
172
174
|
flexBasis: `${this._size}%`,
|
|
173
175
|
flexGrow: '0',
|
|
174
176
|
flexShrink: '0',
|
|
175
|
-
} }, h("div", { key: '
|
|
177
|
+
} }, h("div", { key: '966dc30c32d38089963cd8509524abd099458115', part: "panel", role: "region", class: {
|
|
176
178
|
'resizable-panel': true,
|
|
177
179
|
'resizable-panel--collapsed': this._isCollapsed,
|
|
178
|
-
} }, h("slot", { key: '
|
|
180
|
+
} }, h("slot", { key: '37cc25bf4a11a1b9a8d537092762a38be729f16a' }))));
|
|
179
181
|
}
|
|
180
182
|
static get is() { return "seki-resizable-panel"; }
|
|
181
183
|
static get encapsulation() { return "shadow"; }
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { h, Host } from "@stencil/core";
|
|
2
|
-
import {
|
|
2
|
+
import { ContextConsumer } from "../../utils/context-bridge";
|
|
3
|
+
import { getTabIds, findTabPeer } from "./tab-ids";
|
|
4
|
+
import { claimHostId, effectiveHostId } from "../../utils/host-id";
|
|
3
5
|
/**
|
|
4
6
|
* Tab content panel
|
|
5
7
|
*
|
|
@@ -10,42 +12,39 @@ import { getTabIds } from "./tab-ids";
|
|
|
10
12
|
export class SekiTabsContent {
|
|
11
13
|
constructor() {
|
|
12
14
|
this._isSelected = false;
|
|
13
|
-
this.
|
|
15
|
+
this.tabs = new ContextConsumer('seki-tabs', '_tabsContext', (context) => {
|
|
14
16
|
var _a;
|
|
15
|
-
const context = this.getContext();
|
|
16
17
|
this._isSelected = (_a = context === null || context === void 0 ? void 0 : context.isSelected(this.value)) !== null && _a !== void 0 ? _a : false;
|
|
17
|
-
};
|
|
18
|
+
});
|
|
18
19
|
}
|
|
19
20
|
getContext() {
|
|
20
|
-
|
|
21
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
22
|
-
return tabs ? tabs._tabsContext : null;
|
|
21
|
+
return this.tabs.context;
|
|
23
22
|
}
|
|
24
23
|
get ids() {
|
|
25
24
|
return getTabIds(this.el.closest('seki-tabs'), this.value);
|
|
26
25
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const context = this.getContext();
|
|
30
|
-
this._isSelected = (_a = context === null || context === void 0 ? void 0 : context.isSelected(this.value)) !== null && _a !== void 0 ? _a : false;
|
|
26
|
+
connectedCallback() {
|
|
27
|
+
this.tabs.connect(this.el);
|
|
31
28
|
}
|
|
32
|
-
|
|
29
|
+
valueChanged() {
|
|
33
30
|
var _a, _b;
|
|
34
|
-
//
|
|
35
|
-
this.
|
|
36
|
-
(_b = this.tabsEl) === null || _b === void 0 ? void 0 : _b.addEventListener('sekiValueChange', this.onTabsValueChange);
|
|
31
|
+
// The part's own value changed: re-evaluate against the current context.
|
|
32
|
+
this._isSelected = (_b = (_a = this.getContext()) === null || _a === void 0 ? void 0 : _a.isSelected(this.value)) !== null && _b !== void 0 ? _b : false;
|
|
37
33
|
}
|
|
38
34
|
disconnectedCallback() {
|
|
39
|
-
|
|
40
|
-
(_a = this.tabsEl) === null || _a === void 0 ? void 0 : _a.removeEventListener('sekiValueChange', this.onTabsValueChange);
|
|
35
|
+
this.tabs.disconnect();
|
|
41
36
|
}
|
|
42
37
|
render() {
|
|
43
38
|
const isSelected = this._isSelected;
|
|
44
39
|
const { triggerId, panelId } = this.ids;
|
|
45
|
-
|
|
40
|
+
// Keep an author-set id on either host; IDREFs use whatever id each host has.
|
|
41
|
+
const hostId = claimHostId(this.el, panelId);
|
|
42
|
+
const trigger = findTabPeer(this.el.closest('seki-tabs'), 'seki-tabs-trigger', this.value);
|
|
43
|
+
const labelledById = effectiveHostId(trigger, triggerId);
|
|
44
|
+
return (h(Host, { key: '8bbe15f6616031c9c6b75fb7028b98d5a95487f6', "data-state": isSelected ? 'active' : 'inactive', role: "tabpanel", id: hostId, "aria-labelledby": labelledById, hidden: !isSelected, tabindex: isSelected ? 0 : -1 }, h("div", { key: '6a9277868adafa201ab23fc015d87ddc4f3c0344', part: "content", class: {
|
|
46
45
|
'tabs-content': true,
|
|
47
46
|
'tabs-content--active': isSelected,
|
|
48
|
-
} }, h("slot", { key: '
|
|
47
|
+
} }, h("slot", { key: '4de0e63849e10e70990aca111e4ed85dfedad52e' }))));
|
|
49
48
|
}
|
|
50
49
|
static get is() { return "seki-tabs-content"; }
|
|
51
50
|
static get encapsulation() { return "shadow"; }
|
|
@@ -88,4 +87,10 @@ export class SekiTabsContent {
|
|
|
88
87
|
};
|
|
89
88
|
}
|
|
90
89
|
static get elementRef() { return "el"; }
|
|
90
|
+
static get watchers() {
|
|
91
|
+
return [{
|
|
92
|
+
"propName": "value",
|
|
93
|
+
"methodName": "valueChanged"
|
|
94
|
+
}];
|
|
95
|
+
}
|
|
91
96
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { h, Host } from "@stencil/core";
|
|
2
|
+
import { ContextConsumer } from "../../utils/context-bridge";
|
|
2
3
|
/**
|
|
3
4
|
* Container for tab triggers
|
|
4
5
|
*
|
|
@@ -9,40 +10,23 @@ import { h, Host } from "@stencil/core";
|
|
|
9
10
|
export class SekiTabsList {
|
|
10
11
|
constructor() {
|
|
11
12
|
this._orientation = 'horizontal';
|
|
12
|
-
this.
|
|
13
|
+
this.tabs = new ContextConsumer('seki-tabs', '_tabsContext', (context) => {
|
|
13
14
|
var _a;
|
|
14
|
-
const context = this.getContext();
|
|
15
15
|
this._orientation = (_a = context === null || context === void 0 ? void 0 : context.orientation) !== null && _a !== void 0 ? _a : 'horizontal';
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
getContext() {
|
|
19
|
-
const tabs = this.el.closest('seki-tabs');
|
|
20
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
21
|
-
return tabs ? tabs._tabsContext : null;
|
|
22
|
-
}
|
|
23
|
-
componentWillRender() {
|
|
24
|
-
var _a;
|
|
25
|
-
const context = this.getContext();
|
|
26
|
-
this._orientation = (_a = context === null || context === void 0 ? void 0 : context.orientation) !== null && _a !== void 0 ? _a : 'horizontal';
|
|
16
|
+
});
|
|
27
17
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
// Listen for the parent's only notification event so this list re-checks
|
|
31
|
-
// orientation after mount — without this, orientation freezes at whatever
|
|
32
|
-
// it was when the list first rendered (found during the #261 audit).
|
|
33
|
-
this.tabsEl = (_a = this.el.closest('seki-tabs')) !== null && _a !== void 0 ? _a : undefined;
|
|
34
|
-
(_b = this.tabsEl) === null || _b === void 0 ? void 0 : _b.addEventListener('sekiValueChange', this.onTabsValueChange);
|
|
18
|
+
connectedCallback() {
|
|
19
|
+
this.tabs.connect(this.el);
|
|
35
20
|
}
|
|
36
21
|
disconnectedCallback() {
|
|
37
|
-
|
|
38
|
-
(_a = this.tabsEl) === null || _a === void 0 ? void 0 : _a.removeEventListener('sekiValueChange', this.onTabsValueChange);
|
|
22
|
+
this.tabs.disconnect();
|
|
39
23
|
}
|
|
40
24
|
render() {
|
|
41
25
|
const orientation = this._orientation;
|
|
42
|
-
return (h(Host, { key: '
|
|
26
|
+
return (h(Host, { key: '3a9b098b96f1a1b6e639a78a71c66d9d7c0ac614', "data-orientation": orientation }, h("div", { key: 'd72c6d73977ef9daee3c70d539653df83bacec9a', part: "list", role: "tablist", "aria-orientation": orientation, class: {
|
|
43
27
|
'tabs-list': true,
|
|
44
28
|
[`tabs-list--${orientation}`]: true,
|
|
45
|
-
} }, h("slot", { key: '
|
|
29
|
+
} }, h("slot", { key: '9f80bf08dfd995468a89e7e561a97eadd59d3183' }))));
|
|
46
30
|
}
|
|
47
31
|
static get is() { return "seki-tabs-list"; }
|
|
48
32
|
static get encapsulation() { return "shadow"; }
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { h, Host } from "@stencil/core";
|
|
2
|
-
import {
|
|
2
|
+
import { ContextConsumer } from "../../utils/context-bridge";
|
|
3
|
+
import { getTabIds, findTabPeer } from "./tab-ids";
|
|
4
|
+
import { claimHostId, effectiveHostId } from "../../utils/host-id";
|
|
3
5
|
import { isRtl } from "../../utils/direction";
|
|
4
6
|
/**
|
|
5
7
|
* Tab trigger button
|
|
@@ -15,30 +17,24 @@ export class SekiTabsTrigger {
|
|
|
15
17
|
*/
|
|
16
18
|
this.disabled = false;
|
|
17
19
|
this._isSelected = false;
|
|
18
|
-
this.
|
|
20
|
+
this.tabs = new ContextConsumer('seki-tabs', '_tabsContext', (context) => {
|
|
19
21
|
var _a;
|
|
20
|
-
const context = this.getContext();
|
|
21
22
|
this._isSelected = (_a = context === null || context === void 0 ? void 0 : context.isSelected(this.value)) !== null && _a !== void 0 ? _a : false;
|
|
22
|
-
};
|
|
23
|
+
});
|
|
23
24
|
}
|
|
24
25
|
getContext() {
|
|
25
|
-
|
|
26
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
27
|
-
return tabs ? tabs._tabsContext : null;
|
|
26
|
+
return this.tabs.context;
|
|
28
27
|
}
|
|
29
28
|
get ids() {
|
|
30
29
|
return getTabIds(this.el.closest('seki-tabs'), this.value);
|
|
31
30
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const context = this.getContext();
|
|
35
|
-
this._isSelected = (_a = context === null || context === void 0 ? void 0 : context.isSelected(this.value)) !== null && _a !== void 0 ? _a : false;
|
|
31
|
+
connectedCallback() {
|
|
32
|
+
this.tabs.connect(this.el);
|
|
36
33
|
}
|
|
37
|
-
|
|
34
|
+
valueChanged() {
|
|
38
35
|
var _a, _b;
|
|
39
|
-
//
|
|
40
|
-
this.
|
|
41
|
-
(_b = this.tabsEl) === null || _b === void 0 ? void 0 : _b.addEventListener('sekiValueChange', this.onTabsValueChange);
|
|
36
|
+
// The part's own value changed: re-evaluate against the current context.
|
|
37
|
+
this._isSelected = (_b = (_a = this.getContext()) === null || _a === void 0 ? void 0 : _a.isSelected(this.value)) !== null && _b !== void 0 ? _b : false;
|
|
42
38
|
}
|
|
43
39
|
handleClick() {
|
|
44
40
|
if (this.disabled)
|
|
@@ -159,16 +155,19 @@ export class SekiTabsTrigger {
|
|
|
159
155
|
}
|
|
160
156
|
}
|
|
161
157
|
disconnectedCallback() {
|
|
162
|
-
|
|
163
|
-
(_a = this.tabsEl) === null || _a === void 0 ? void 0 : _a.removeEventListener('sekiValueChange', this.onTabsValueChange);
|
|
158
|
+
this.tabs.disconnect();
|
|
164
159
|
}
|
|
165
160
|
render() {
|
|
166
161
|
const isSelected = this._isSelected;
|
|
167
162
|
const { triggerId, panelId } = this.ids;
|
|
168
|
-
|
|
163
|
+
// Keep an author-set id on either host; IDREFs use whatever id each host has.
|
|
164
|
+
const hostId = claimHostId(this.el, triggerId);
|
|
165
|
+
const panel = findTabPeer(this.el.closest('seki-tabs'), 'seki-tabs-content', this.value);
|
|
166
|
+
const controlsId = effectiveHostId(panel, panelId);
|
|
167
|
+
return (h(Host, { key: '12d3ad61a2abcec3839d92baee7eb245514fbb52', id: hostId, "data-state": isSelected ? 'active' : 'inactive', "data-disabled": this.disabled ? '' : undefined, tabindex: this.disabled ? -1 : 0, role: "tab", "aria-selected": isSelected ? 'true' : 'false', "aria-controls": controlsId }, h("button", { key: '5ac3ffd4c1581e596ab18ce99e3aa91421ae9a4c', part: "trigger", type: "button", class: {
|
|
169
168
|
'tabs-trigger': true,
|
|
170
169
|
'tabs-trigger--active': isSelected,
|
|
171
|
-
}, disabled: this.disabled, tabindex: -1 }, h("slot", { key: '
|
|
170
|
+
}, disabled: this.disabled, tabindex: -1 }, h("slot", { key: '1e5440b27cd8a7e71f8a55c303c2331c76e2583b' }))));
|
|
172
171
|
}
|
|
173
172
|
static get is() { return "seki-tabs-trigger"; }
|
|
174
173
|
static get encapsulation() { return "shadow"; }
|
|
@@ -231,6 +230,12 @@ export class SekiTabsTrigger {
|
|
|
231
230
|
};
|
|
232
231
|
}
|
|
233
232
|
static get elementRef() { return "el"; }
|
|
233
|
+
static get watchers() {
|
|
234
|
+
return [{
|
|
235
|
+
"propName": "value",
|
|
236
|
+
"methodName": "valueChanged"
|
|
237
|
+
}];
|
|
238
|
+
}
|
|
234
239
|
static get listeners() {
|
|
235
240
|
return [{
|
|
236
241
|
"name": "click",
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { h, Host } from "@stencil/core";
|
|
2
|
+
import { publishContext } from "../../utils/context-bridge";
|
|
2
3
|
/**
|
|
3
4
|
* Tabs root component that manages selected tab state
|
|
4
5
|
*
|
|
@@ -22,15 +23,17 @@ export class SekiTabs {
|
|
|
22
23
|
// Initialize from value or defaultValue
|
|
23
24
|
const initialValue = (_b = (_a = this.value) !== null && _a !== void 0 ? _a : this.defaultValue) !== null && _b !== void 0 ? _b : '';
|
|
24
25
|
this._selectedValue = initialValue;
|
|
25
|
-
// Publish before children load:
|
|
26
|
-
//
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
// Publish before children load: parts that are already upgraded pick it up
|
|
27
|
+
// from the event, parts that upgrade later read it when they connect (#384).
|
|
28
|
+
this.publish();
|
|
29
|
+
}
|
|
30
|
+
orientationChanged() {
|
|
31
|
+
this.publish();
|
|
30
32
|
}
|
|
31
33
|
valueChanged(newValue) {
|
|
32
34
|
if (newValue !== undefined) {
|
|
33
35
|
this._selectedValue = newValue;
|
|
36
|
+
this.publish();
|
|
34
37
|
// Programmatic `tabsEl.value = x` must notify already-mounted children
|
|
35
38
|
// the same way selectTab() does, or seki-tabs-trigger/seki-tabs-list
|
|
36
39
|
// silently stay stale (found during the #261 audit).
|
|
@@ -48,9 +51,9 @@ export class SekiTabs {
|
|
|
48
51
|
// sekiValueChange — no separate emit needed here (found during #268;
|
|
49
52
|
// #261 originally left both, causing a double-emit on every click).
|
|
50
53
|
this.value = tabValue;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
this.el
|
|
54
|
+
}
|
|
55
|
+
publish() {
|
|
56
|
+
publishContext(this.el, '_tabsContext', this.getContext(), this.contextChange);
|
|
54
57
|
}
|
|
55
58
|
isSelected(tabValue) {
|
|
56
59
|
return this._selectedValue === tabValue;
|
|
@@ -63,19 +66,11 @@ export class SekiTabs {
|
|
|
63
66
|
isSelected: (value) => this.isSelected(value),
|
|
64
67
|
};
|
|
65
68
|
}
|
|
66
|
-
componentDidLoad() {
|
|
67
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
68
|
-
this.el._tabsContext = this.getContext();
|
|
69
|
-
}
|
|
70
|
-
componentDidUpdate() {
|
|
71
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
72
|
-
this.el._tabsContext = this.getContext();
|
|
73
|
-
}
|
|
74
69
|
render() {
|
|
75
|
-
return (h(Host, { key: '
|
|
70
|
+
return (h(Host, { key: '3e4cf3afc38da559d0f6f3558b5e56f3e994bcc0', "data-orientation": this.orientation }, h("div", { key: 'd7a04a38c27904ba02224e97574393dfb0fa18bc', part: "tabs", class: {
|
|
76
71
|
'tabs': true,
|
|
77
72
|
[`tabs--${this.orientation}`]: true,
|
|
78
|
-
} }, h("slot", { key: '
|
|
73
|
+
} }, h("slot", { key: '6cb943c282fe0e538dd7d6fa2ef453204c3eb0b0' }))));
|
|
79
74
|
}
|
|
80
75
|
static get is() { return "seki-tabs"; }
|
|
81
76
|
static get encapsulation() { return "shadow"; }
|
|
@@ -172,6 +167,24 @@ export class SekiTabs {
|
|
|
172
167
|
"resolved": "string",
|
|
173
168
|
"references": {}
|
|
174
169
|
}
|
|
170
|
+
}, {
|
|
171
|
+
"method": "contextChange",
|
|
172
|
+
"name": "sekiContextChange",
|
|
173
|
+
"bubbles": true,
|
|
174
|
+
"cancelable": true,
|
|
175
|
+
"composed": true,
|
|
176
|
+
"docs": {
|
|
177
|
+
"tags": [{
|
|
178
|
+
"name": "internal",
|
|
179
|
+
"text": undefined
|
|
180
|
+
}],
|
|
181
|
+
"text": "Internal: notifies tab parts that the published context changed. Not part\nof the public API (sekiValueChange is)."
|
|
182
|
+
},
|
|
183
|
+
"complexType": {
|
|
184
|
+
"original": "void",
|
|
185
|
+
"resolved": "void",
|
|
186
|
+
"references": {}
|
|
187
|
+
}
|
|
175
188
|
}];
|
|
176
189
|
}
|
|
177
190
|
static get methods() {
|
|
@@ -202,6 +215,9 @@ export class SekiTabs {
|
|
|
202
215
|
static get elementRef() { return "el"; }
|
|
203
216
|
static get watchers() {
|
|
204
217
|
return [{
|
|
218
|
+
"propName": "orientation",
|
|
219
|
+
"methodName": "orientationChanged"
|
|
220
|
+
}, {
|
|
205
221
|
"propName": "value",
|
|
206
222
|
"methodName": "valueChanged"
|
|
207
223
|
}];
|
|
@@ -20,3 +20,16 @@ export function getTabIds(tabsEl, value) {
|
|
|
20
20
|
const v = sanitize(value !== null && value !== void 0 ? value : '');
|
|
21
21
|
return { triggerId: `${base}-trigger-${v}`, panelId: `${base}-panel-${v}` };
|
|
22
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* The trigger/panel host with the given `value` that belongs to `tabsEl` (not
|
|
25
|
+
* to a nested `seki-tabs`), or null when the tree has no such peer.
|
|
26
|
+
*/
|
|
27
|
+
export function findTabPeer(tabsEl, tag, value) {
|
|
28
|
+
if (!tabsEl)
|
|
29
|
+
return null;
|
|
30
|
+
for (const el of Array.from(tabsEl.querySelectorAll(tag))) {
|
|
31
|
+
if (el.closest('seki-tabs') === tabsEl && el.getAttribute('value') === value)
|
|
32
|
+
return el;
|
|
33
|
+
}
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host ids for cross-shadow ARIA wiring (trigger host <-> content host).
|
|
3
|
+
*
|
|
4
|
+
* IDREFs cannot cross shadow roots, so components put their ids on the
|
|
5
|
+
* light-DOM hosts. An id the author wrote on the host must never be
|
|
6
|
+
* overwritten: `effectiveHostId` returns it when present and falls back to the
|
|
7
|
+
* generated id otherwise. We remember which id we generated per element so a
|
|
8
|
+
* generated id that changes later (e.g. the tab `value` changes) is replaced,
|
|
9
|
+
* while an author id (anything else on the element) is kept.
|
|
10
|
+
*/
|
|
11
|
+
const generated = new WeakMap();
|
|
12
|
+
/** The id `el` actually has (author id, else `fallback`). Does not mutate. */
|
|
13
|
+
export function effectiveHostId(el, fallback) {
|
|
14
|
+
if (el && el.id && el.id !== generated.get(el))
|
|
15
|
+
return el.id;
|
|
16
|
+
return fallback;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Resolve the id to render on `el`: keeps an author-set id, otherwise records
|
|
20
|
+
* and returns `fallback`.
|
|
21
|
+
*/
|
|
22
|
+
export function claimHostId(el, fallback) {
|
|
23
|
+
const id = effectiveHostId(el, fallback);
|
|
24
|
+
if (id === fallback)
|
|
25
|
+
generated.set(el, fallback);
|
|
26
|
+
return id;
|
|
27
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text direction helpers for keyboard handling.
|
|
3
|
+
*
|
|
4
|
+
* `getComputedStyle().direction` already folds in the `dir` attribute on any
|
|
5
|
+
* ancestor (including across shadow boundaries via inheritance) and CSS
|
|
6
|
+
* `direction`, so it is the single source of truth.
|
|
7
|
+
*/
|
|
8
|
+
function isRtl(el) {
|
|
9
|
+
return getComputedStyle(el).direction === 'rtl';
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export { isRtl as i };
|