@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
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { h, Host } from "@stencil/core";
|
|
2
|
+
import { getAccordionIds, resolveAccordionIds } from "./accordion-ids";
|
|
3
|
+
import { claimHostId } from "../../utils/host-id";
|
|
4
|
+
import { ContextConsumer } from "../../utils/context-bridge";
|
|
2
5
|
/**
|
|
3
6
|
* Trigger button for accordion item - click to toggle
|
|
4
7
|
*
|
|
@@ -10,21 +13,32 @@ import { h, Host } from "@stencil/core";
|
|
|
10
13
|
export class SekiAccordionTrigger {
|
|
11
14
|
constructor() {
|
|
12
15
|
this._isOpen = false;
|
|
13
|
-
this.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
this._isOpen = (
|
|
17
|
-
|
|
16
|
+
this._disabled = false;
|
|
17
|
+
this.accordion = new ContextConsumer('seki-accordion', '_accordionContext', (ctx) => {
|
|
18
|
+
var _a, _b;
|
|
19
|
+
this._isOpen = this.readIsOpen();
|
|
20
|
+
// Derived from the accordion and the item's attribute (what handleClick
|
|
21
|
+
// checks), not from the item's cached context, which may not exist yet when
|
|
22
|
+
// the item upgrades after this trigger.
|
|
23
|
+
const item = this.el.closest('seki-accordion-item');
|
|
24
|
+
this._disabled = ((_a = item === null || item === void 0 ? void 0 : item.hasAttribute('disabled')) !== null && _a !== void 0 ? _a : false) || ((_b = ctx === null || ctx === void 0 ? void 0 : ctx.disabled) !== null && _b !== void 0 ? _b : false);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
// Read open state straight from the accordion: the item's cached context may
|
|
28
|
+
// not have been refreshed yet when this listener runs.
|
|
29
|
+
readIsOpen() {
|
|
30
|
+
var _a, _b, _c;
|
|
31
|
+
const value = (_a = this.el.closest('seki-accordion-item')) === null || _a === void 0 ? void 0 : _a.getAttribute('value');
|
|
32
|
+
const ctx = this.accordion.context;
|
|
33
|
+
return value && ctx ? ctx.isItemOpen(value) : ((_c = (_b = this.getItemContext()) === null || _b === void 0 ? void 0 : _b.isOpen) !== null && _c !== void 0 ? _c : false);
|
|
18
34
|
}
|
|
19
35
|
getItemContext() {
|
|
20
36
|
const item = this.el.closest('seki-accordion-item');
|
|
21
37
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
22
38
|
return item ? item._accordionItemContext : null;
|
|
23
39
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const context = this.getItemContext();
|
|
27
|
-
this._isOpen = (_a = context === null || context === void 0 ? void 0 : context.isOpen) !== null && _a !== void 0 ? _a : false;
|
|
40
|
+
connectedCallback() {
|
|
41
|
+
this.accordion.connect(this.el);
|
|
28
42
|
}
|
|
29
43
|
handleClick() {
|
|
30
44
|
// Direct method call - no closures, no timing issues
|
|
@@ -105,29 +119,23 @@ export class SekiAccordionTrigger {
|
|
|
105
119
|
const triggers = this.getAllTriggers();
|
|
106
120
|
(_a = triggers[triggers.length - 1]) === null || _a === void 0 ? void 0 : _a.focus();
|
|
107
121
|
}
|
|
108
|
-
componentDidLoad() {
|
|
109
|
-
var _a, _b;
|
|
110
|
-
// Listen for value changes from parent accordion
|
|
111
|
-
this.accordionEl = (_a = this.el.closest('seki-accordion')) !== null && _a !== void 0 ? _a : undefined;
|
|
112
|
-
(_b = this.accordionEl) === null || _b === void 0 ? void 0 : _b.addEventListener('sekiValueChange', this.onAccordionValueChange);
|
|
113
|
-
}
|
|
114
122
|
disconnectedCallback() {
|
|
115
|
-
|
|
116
|
-
(_a = this.accordionEl) === null || _a === void 0 ? void 0 : _a.removeEventListener('sekiValueChange', this.onAccordionValueChange);
|
|
123
|
+
this.accordion.disconnect();
|
|
117
124
|
}
|
|
118
125
|
render() {
|
|
119
|
-
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
126
|
+
const isOpen = this._isOpen;
|
|
127
|
+
const disabled = this._disabled;
|
|
128
|
+
// IDREFs cannot cross shadow roots, so the id / aria-controls / aria-expanded
|
|
129
|
+
// live on this light-DOM host and point at the content host. An author id on
|
|
130
|
+
// either host is kept.
|
|
131
|
+
const item = this.el.closest('seki-accordion-item');
|
|
132
|
+
const ids = getAccordionIds(item);
|
|
133
|
+
const hostId = claimHostId(this.el, ids.triggerId);
|
|
134
|
+
const { contentId } = resolveAccordionIds(item);
|
|
135
|
+
return (h(Host, { key: 'e8460b73584f77661d9ef18d0b84042ccce84545', id: hostId, "data-state": isOpen ? 'open' : 'closed', "data-disabled": disabled ? '' : undefined, tabindex: disabled ? -1 : 0, role: "button", "aria-expanded": isOpen ? 'true' : 'false', "aria-controls": contentId, "aria-disabled": disabled ? 'true' : undefined }, h("div", { key: '025c1edaf275243cc2364db8d8e9cf2d19b23acd', part: "trigger", class: "accordion-trigger" }, h("slot", { key: '859a324fb14c061aea66533206a155c5080cb172' }), h("svg", { key: '87a6a132ee575ef3a7702d2a4873c9d8f6d5885e', part: "icon", class: {
|
|
128
136
|
'accordion-chevron': true,
|
|
129
137
|
'accordion-chevron--open': isOpen,
|
|
130
|
-
}, xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("path", { key: '
|
|
138
|
+
}, xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("path", { key: '849c07b8fa675659f8bb7cb035dde02820796cfd', d: "m6 9 6 6 6-6" })))));
|
|
131
139
|
}
|
|
132
140
|
static get is() { return "seki-accordion-trigger"; }
|
|
133
141
|
static get encapsulation() { return "shadow"; }
|
|
@@ -143,7 +151,8 @@ export class SekiAccordionTrigger {
|
|
|
143
151
|
}
|
|
144
152
|
static get states() {
|
|
145
153
|
return {
|
|
146
|
-
"_isOpen": {}
|
|
154
|
+
"_isOpen": {},
|
|
155
|
+
"_disabled": {}
|
|
147
156
|
};
|
|
148
157
|
}
|
|
149
158
|
static get elementRef() { return "el"; }
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { h, Host } from "@stencil/core";
|
|
2
|
+
import { publishContext } from "../../utils/context-bridge";
|
|
2
3
|
/**
|
|
3
4
|
* Accordion root component that manages expanded state of items
|
|
4
5
|
*
|
|
@@ -32,10 +33,14 @@ export class SekiAccordion {
|
|
|
32
33
|
if (initialValue) {
|
|
33
34
|
this._openItems = Array.isArray(initialValue) ? [...initialValue] : [initialValue];
|
|
34
35
|
}
|
|
36
|
+
// Parts already upgraded hear this; parts that upgrade later read it when
|
|
37
|
+
// they connect (#384).
|
|
38
|
+
this.publish();
|
|
35
39
|
}
|
|
36
40
|
valueChanged(newValue) {
|
|
37
41
|
if (newValue !== undefined) {
|
|
38
42
|
this._openItems = Array.isArray(newValue) ? [...newValue] : [newValue];
|
|
43
|
+
this.publish();
|
|
39
44
|
// Programmatic `accordionEl.value = x` must notify already-mounted
|
|
40
45
|
// children the same way toggleItem() does (found during #261 audit).
|
|
41
46
|
this.sekiValueChange.emit(newValue);
|
|
@@ -53,6 +58,7 @@ export class SekiAccordion {
|
|
|
53
58
|
// Only close if collapsible
|
|
54
59
|
if (this.collapsible) {
|
|
55
60
|
this._openItems = [];
|
|
61
|
+
this.publish();
|
|
56
62
|
// Unlike the open/multiple-mode branches below, this direct emit
|
|
57
63
|
// must stay: @Watch('value')'s handler skips emitting when
|
|
58
64
|
// newValue is undefined (a pre-existing guard), so this is the
|
|
@@ -82,9 +88,10 @@ export class SekiAccordion {
|
|
|
82
88
|
// separate emit needed (found during #268).
|
|
83
89
|
this.value = [...this._openItems];
|
|
84
90
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
91
|
+
this.publish();
|
|
92
|
+
}
|
|
93
|
+
publish() {
|
|
94
|
+
publishContext(this.el, '_accordionContext', this.getContext(), this.contextChange);
|
|
88
95
|
}
|
|
89
96
|
isItemOpen(itemValue) {
|
|
90
97
|
return this._openItems.includes(itemValue);
|
|
@@ -99,16 +106,11 @@ export class SekiAccordion {
|
|
|
99
106
|
isItemOpen: (itemValue) => this.isItemOpen(itemValue),
|
|
100
107
|
};
|
|
101
108
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
this.el._accordionContext = this.getContext();
|
|
105
|
-
}
|
|
106
|
-
componentDidUpdate() {
|
|
107
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
108
|
-
this.el._accordionContext = this.getContext();
|
|
109
|
+
settingsChanged() {
|
|
110
|
+
this.publish();
|
|
109
111
|
}
|
|
110
112
|
render() {
|
|
111
|
-
return (h(Host, { key: '
|
|
113
|
+
return (h(Host, { key: '604f9f0845c8c3facd643ccf8eab22139443ed97', "data-disabled": this.disabled ? '' : undefined }, h("div", { key: 'fee00af3c001cd0553d17021df330e62096d3413', part: "accordion", class: "accordion" }, h("slot", { key: 'b1c5b80cb3fda3015b2bfebef43d174897cd085f' }))));
|
|
112
114
|
}
|
|
113
115
|
static get is() { return "seki-accordion"; }
|
|
114
116
|
static get encapsulation() { return "shadow"; }
|
|
@@ -245,6 +247,24 @@ export class SekiAccordion {
|
|
|
245
247
|
"resolved": "string | string[]",
|
|
246
248
|
"references": {}
|
|
247
249
|
}
|
|
250
|
+
}, {
|
|
251
|
+
"method": "contextChange",
|
|
252
|
+
"name": "sekiContextChange",
|
|
253
|
+
"bubbles": true,
|
|
254
|
+
"cancelable": true,
|
|
255
|
+
"composed": true,
|
|
256
|
+
"docs": {
|
|
257
|
+
"tags": [{
|
|
258
|
+
"name": "internal",
|
|
259
|
+
"text": undefined
|
|
260
|
+
}],
|
|
261
|
+
"text": "Internal: notifies accordion parts that the published context changed."
|
|
262
|
+
},
|
|
263
|
+
"complexType": {
|
|
264
|
+
"original": "void",
|
|
265
|
+
"resolved": "void",
|
|
266
|
+
"references": {}
|
|
267
|
+
}
|
|
248
268
|
}];
|
|
249
269
|
}
|
|
250
270
|
static get methods() {
|
|
@@ -277,6 +297,15 @@ export class SekiAccordion {
|
|
|
277
297
|
return [{
|
|
278
298
|
"propName": "value",
|
|
279
299
|
"methodName": "valueChanged"
|
|
300
|
+
}, {
|
|
301
|
+
"propName": "disabled",
|
|
302
|
+
"methodName": "settingsChanged"
|
|
303
|
+
}, {
|
|
304
|
+
"propName": "collapsible",
|
|
305
|
+
"methodName": "settingsChanged"
|
|
306
|
+
}, {
|
|
307
|
+
"propName": "type",
|
|
308
|
+
"methodName": "settingsChanged"
|
|
280
309
|
}];
|
|
281
310
|
}
|
|
282
311
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { h, Host } from "@stencil/core";
|
|
2
2
|
import { subscribeToContextChange } from "../../utils/context-bridge";
|
|
3
3
|
import { whenDefined } from "../../utils/when-defined";
|
|
4
|
+
import { isRtl } from "../../utils/direction";
|
|
4
5
|
/**
|
|
5
6
|
* Dot indicators for carousel navigation.
|
|
6
7
|
* Automatically syncs with parent seki-carousel.
|
|
@@ -25,26 +26,33 @@ export class SekiCarouselDots {
|
|
|
25
26
|
if (!dots)
|
|
26
27
|
return;
|
|
27
28
|
let targetIndex = null;
|
|
29
|
+
// Dots are laid out in the inline direction, so Left/Right are visual:
|
|
30
|
+
// in RTL the next dot is to the left.
|
|
31
|
+
const rtl = isRtl(this.el);
|
|
32
|
+
const prevKey = rtl ? 'ArrowRight' : 'ArrowLeft';
|
|
33
|
+
const nextKey = rtl ? 'ArrowLeft' : 'ArrowRight';
|
|
28
34
|
switch (event.key) {
|
|
29
|
-
case
|
|
35
|
+
case prevKey:
|
|
30
36
|
case 'ArrowUp':
|
|
31
|
-
event.preventDefault();
|
|
32
37
|
targetIndex = index > 0 ? index - 1 : this.scrollSnapCount - 1;
|
|
33
38
|
break;
|
|
34
|
-
case
|
|
39
|
+
case nextKey:
|
|
35
40
|
case 'ArrowDown':
|
|
36
|
-
event.preventDefault();
|
|
37
41
|
targetIndex = index < this.scrollSnapCount - 1 ? index + 1 : 0;
|
|
38
42
|
break;
|
|
39
43
|
case 'Home':
|
|
40
|
-
event.preventDefault();
|
|
41
44
|
targetIndex = 0;
|
|
42
45
|
break;
|
|
43
46
|
case 'End':
|
|
44
|
-
event.preventDefault();
|
|
45
47
|
targetIndex = this.scrollSnapCount - 1;
|
|
46
48
|
break;
|
|
47
49
|
}
|
|
50
|
+
if (targetIndex !== null) {
|
|
51
|
+
event.preventDefault();
|
|
52
|
+
// The dots sit inside <seki-carousel>, whose own arrow-key handler would
|
|
53
|
+
// otherwise advance a second time.
|
|
54
|
+
event.stopPropagation();
|
|
55
|
+
}
|
|
48
56
|
if (targetIndex !== null) {
|
|
49
57
|
(_b = dots[targetIndex]) === null || _b === void 0 ? void 0 : _b.focus();
|
|
50
58
|
this.handleDotClick(targetIndex);
|
|
@@ -91,7 +99,7 @@ export class SekiCarouselDots {
|
|
|
91
99
|
}
|
|
92
100
|
render() {
|
|
93
101
|
const dots = Array.from({ length: this.scrollSnapCount }, (_, i) => i);
|
|
94
|
-
return (h(Host, { key: '
|
|
102
|
+
return (h(Host, { key: '54e11889da62fbd901a297bbc733af13c3920efc', class: "carousel-dots" }, h("div", { key: 'e14079fbfcef9b48cac10deaae16ebefbb949b38', class: "carousel-dots__container", role: "tablist", "aria-label": "Carousel pagination" }, dots.map((index) => (h("button", { key: index, type: "button", class: {
|
|
95
103
|
'carousel-dots__dot': true,
|
|
96
104
|
'carousel-dots__dot--active': index === this.selectedIndex,
|
|
97
105
|
}, role: "tab", "aria-selected": index === this.selectedIndex ? 'true' : 'false', "aria-label": `Go to slide ${index + 1}`, tabindex: index === this.selectedIndex ? '0' : '-1', onClick: () => this.handleDotClick(index), onKeyDown: (e) => this.handleKeyDown(e, index) }, h("span", { class: "carousel-dots__dot-inner" })))))));
|
|
@@ -9,11 +9,11 @@
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
:host(.carousel-nav--prev) {
|
|
12
|
-
|
|
12
|
+
inset-inline-start: 0.5rem;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
:host(.carousel-nav--next) {
|
|
16
|
-
|
|
16
|
+
inset-inline-end: 0.5rem;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
.carousel-nav__button {
|
|
@@ -56,14 +56,19 @@
|
|
|
56
56
|
flex-shrink: 0;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
/* Chevrons point along the inline direction, so mirror them in RTL. */
|
|
60
|
+
.carousel-nav__icon:dir(rtl) {
|
|
61
|
+
transform: scaleX(-1);
|
|
62
|
+
}
|
|
63
|
+
|
|
59
64
|
/* Responsive: hide on very small screens if needed */
|
|
60
65
|
@media (max-width: 480px) {
|
|
61
66
|
:host(.carousel-nav--prev) {
|
|
62
|
-
|
|
67
|
+
inset-inline-start: 0.25rem;
|
|
63
68
|
}
|
|
64
69
|
|
|
65
70
|
:host(.carousel-nav--next) {
|
|
66
|
-
|
|
71
|
+
inset-inline-end: 0.25rem;
|
|
67
72
|
}
|
|
68
73
|
|
|
69
74
|
.carousel-nav__button {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { h, Host } from "@stencil/core";
|
|
2
2
|
import { isDefined, whenDefined } from "../../utils/when-defined";
|
|
3
|
+
import { isRtl } from "../../utils/direction";
|
|
3
4
|
// Lazily loaded so embla-carousel (an optional peer dependency, see #263)
|
|
4
5
|
// isn't pulled into any bundle unless a <seki-carousel> actually renders.
|
|
5
6
|
// Module-scope cache shared across every seki-carousel instance on the page.
|
|
@@ -66,6 +67,16 @@ export class SekiCarousel {
|
|
|
66
67
|
/** Slide to come back to when Embla is re-created after a move or option change. */
|
|
67
68
|
this.resumeIndex = null;
|
|
68
69
|
this.waitedForContentDefinition = false;
|
|
70
|
+
/** Direction Embla was created with; compared on `dir` changes (#381). */
|
|
71
|
+
this.appliedRtl = null;
|
|
72
|
+
this.dirObserver = null;
|
|
73
|
+
this.handleDirectionChange = () => {
|
|
74
|
+
if (!this.emblaApi || this.appliedRtl === null || isRtl(this.el) === this.appliedRtl)
|
|
75
|
+
return;
|
|
76
|
+
// teardownEmbla() records the selected slide in resumeIndex.
|
|
77
|
+
this.teardownEmbla();
|
|
78
|
+
this.initEmbla();
|
|
79
|
+
};
|
|
69
80
|
this.handleSelect = () => {
|
|
70
81
|
this.updateState();
|
|
71
82
|
this.slideChange.emit({
|
|
@@ -108,23 +119,31 @@ export class SekiCarousel {
|
|
|
108
119
|
}
|
|
109
120
|
};
|
|
110
121
|
this.handleKeyDown = (event) => {
|
|
111
|
-
var _a, _b, _c, _d;
|
|
122
|
+
var _a, _b, _c, _d, _e, _f;
|
|
123
|
+
// Arrow keys are visual: in RTL the next slide is to the left.
|
|
124
|
+
const rtl = isRtl(this.el);
|
|
112
125
|
switch (event.key) {
|
|
113
126
|
case 'ArrowLeft':
|
|
114
127
|
event.preventDefault();
|
|
115
|
-
|
|
128
|
+
if (rtl)
|
|
129
|
+
(_a = this.emblaApi) === null || _a === void 0 ? void 0 : _a.scrollNext();
|
|
130
|
+
else
|
|
131
|
+
(_b = this.emblaApi) === null || _b === void 0 ? void 0 : _b.scrollPrev();
|
|
116
132
|
break;
|
|
117
133
|
case 'ArrowRight':
|
|
118
134
|
event.preventDefault();
|
|
119
|
-
|
|
135
|
+
if (rtl)
|
|
136
|
+
(_c = this.emblaApi) === null || _c === void 0 ? void 0 : _c.scrollPrev();
|
|
137
|
+
else
|
|
138
|
+
(_d = this.emblaApi) === null || _d === void 0 ? void 0 : _d.scrollNext();
|
|
120
139
|
break;
|
|
121
140
|
case 'Home':
|
|
122
141
|
event.preventDefault();
|
|
123
|
-
(
|
|
142
|
+
(_e = this.emblaApi) === null || _e === void 0 ? void 0 : _e.scrollTo(0);
|
|
124
143
|
break;
|
|
125
144
|
case 'End':
|
|
126
145
|
event.preventDefault();
|
|
127
|
-
(
|
|
146
|
+
(_f = this.emblaApi) === null || _f === void 0 ? void 0 : _f.scrollTo(this.scrollSnapCount - 1);
|
|
128
147
|
break;
|
|
129
148
|
}
|
|
130
149
|
};
|
|
@@ -137,6 +156,7 @@ export class SekiCarousel {
|
|
|
137
156
|
// once, so a carousel that is moved in the DOM (keyed lists, portals,
|
|
138
157
|
// drag-and-drop) is set up again from connectedCallback (#333).
|
|
139
158
|
connectedCallback() {
|
|
159
|
+
this.observeDirection();
|
|
140
160
|
if (this.hasLoaded)
|
|
141
161
|
this.initEmbla();
|
|
142
162
|
}
|
|
@@ -145,6 +165,9 @@ export class SekiCarousel {
|
|
|
145
165
|
this.initEmbla();
|
|
146
166
|
}
|
|
147
167
|
disconnectedCallback() {
|
|
168
|
+
var _a;
|
|
169
|
+
(_a = this.dirObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
170
|
+
this.dirObserver = null;
|
|
148
171
|
this.teardownEmbla();
|
|
149
172
|
}
|
|
150
173
|
// =========================================================================
|
|
@@ -204,6 +227,24 @@ export class SekiCarousel {
|
|
|
204
227
|
// =========================================================================
|
|
205
228
|
// Private Methods
|
|
206
229
|
// =========================================================================
|
|
230
|
+
/**
|
|
231
|
+
* Embla's `direction` is fixed at creation, so watch the `dir` attribute of
|
|
232
|
+
* every ancestor (crossing shadow roots) and re-create Embla when the computed
|
|
233
|
+
* direction actually flips. Attribute-filtered and non-subtree, so it is cheap.
|
|
234
|
+
*/
|
|
235
|
+
observeDirection() {
|
|
236
|
+
var _a, _b, _c;
|
|
237
|
+
(_a = this.dirObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
238
|
+
if (typeof MutationObserver === 'undefined')
|
|
239
|
+
return;
|
|
240
|
+
this.dirObserver = new MutationObserver(this.handleDirectionChange);
|
|
241
|
+
let node = this.el;
|
|
242
|
+
while (node) {
|
|
243
|
+
if (node.nodeType === Node.ELEMENT_NODE)
|
|
244
|
+
this.dirObserver.observe(node, { attributes: true, attributeFilter: ['dir'] });
|
|
245
|
+
node = (_c = (_b = node.parentNode) !== null && _b !== void 0 ? _b : node.host) !== null && _c !== void 0 ? _c : null;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
207
248
|
/** Stop autoplay, cancel a pending init and destroy Embla. Idempotent. */
|
|
208
249
|
teardownEmbla() {
|
|
209
250
|
this.initGeneration++;
|
|
@@ -262,6 +303,7 @@ export class SekiCarousel {
|
|
|
262
303
|
// Container found — reset retry bookkeeping.
|
|
263
304
|
this.initRetries = 0;
|
|
264
305
|
this.initRafId = null;
|
|
306
|
+
const rtl = isRtl(this.el);
|
|
265
307
|
const options = {
|
|
266
308
|
loop: this.loop,
|
|
267
309
|
// Keep the current slide when re-created (DOM move, option change).
|
|
@@ -269,6 +311,8 @@ export class SekiCarousel {
|
|
|
269
311
|
slidesToScroll: this.slidesToScroll,
|
|
270
312
|
dragFree: this.dragFree,
|
|
271
313
|
containScroll: 'trimSnaps',
|
|
314
|
+
// Slides flow right-to-left under dir="rtl"; embla must scroll to match.
|
|
315
|
+
direction: rtl ? 'rtl' : 'ltr',
|
|
272
316
|
};
|
|
273
317
|
let EmblaCarousel;
|
|
274
318
|
try {
|
|
@@ -283,6 +327,7 @@ export class SekiCarousel {
|
|
|
283
327
|
if (!this.el.isConnected || !this.viewportEl || generation !== this.initGeneration || this.emblaApi)
|
|
284
328
|
return;
|
|
285
329
|
this.emblaApi = EmblaCarousel(this.viewportEl, options);
|
|
330
|
+
this.appliedRtl = rtl;
|
|
286
331
|
// Set up event listeners
|
|
287
332
|
this.emblaApi.on('select', this.handleSelect);
|
|
288
333
|
this.emblaApi.on('reInit', this.handleReInit);
|
|
@@ -342,7 +387,7 @@ export class SekiCarousel {
|
|
|
342
387
|
// Render
|
|
343
388
|
// =========================================================================
|
|
344
389
|
render() {
|
|
345
|
-
return (h(Host, { key: '
|
|
390
|
+
return (h(Host, { key: 'b55deaf2dd34be409d82b9edc6171bd17e479fa5', class: "carousel", role: "region", "aria-roledescription": "carousel", "aria-label": this.ariaLabel, tabindex: "0", onMouseEnter: this.handleMouseEnter, onMouseLeave: this.handleMouseLeave, onFocusIn: this.handleFocusIn, onFocusOut: this.handleFocusOut, onKeyDown: this.handleKeyDown }, h("div", { key: '4e24a73b01d4f839d8f1f7feb2957664016cb6ad', class: "carousel__container" }, h("slot", { key: '0ba983eb5c01d434a5fa25073dcccdc58c8c35d3' })), h("div", { key: 'f1a62d565f8f6cda368ac6d15c95c53e1598bed6', class: "carousel__live-region", "aria-live": "polite", "aria-atomic": "true" }, `Slide ${this.selectedIndex + 1} of ${this.scrollSnapCount}`)));
|
|
346
391
|
}
|
|
347
392
|
static get is() { return "seki-carousel"; }
|
|
348
393
|
static get encapsulation() { return "shadow"; }
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Host, h } from "@stencil/core";
|
|
2
2
|
import { publishContext } from "../../utils/context-bridge";
|
|
3
3
|
import { OverlayLayer } from "../../utils/overlay";
|
|
4
|
+
import { FormControl } from "../../utils/form-control";
|
|
4
5
|
/**
|
|
5
6
|
* @slot - Content containing seki-combobox-input and seki-combobox-content
|
|
6
7
|
*/
|
|
@@ -193,6 +194,32 @@ export class SekiCombobox {
|
|
|
193
194
|
}
|
|
194
195
|
// Expose context
|
|
195
196
|
this.updateContextOnElement();
|
|
197
|
+
this.formControl = new FormControl(this.el, this.internals, {
|
|
198
|
+
getFormValue: () => this.getFormValue(),
|
|
199
|
+
isEmpty: () => this.isValueEmpty(),
|
|
200
|
+
isRequired: () => this.required,
|
|
201
|
+
isDisabled: () => this.disabled,
|
|
202
|
+
requiredMessage: 'Please select an item in the list.',
|
|
203
|
+
getAnchor: () => {
|
|
204
|
+
var _a, _b;
|
|
205
|
+
const input = this.el.querySelector('seki-combobox-input');
|
|
206
|
+
return (_b = (_a = input === null || input === void 0 ? void 0 : input.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('input')) !== null && _b !== void 0 ? _b : input;
|
|
207
|
+
},
|
|
208
|
+
restore: initial => this.setValueFromForm(initial),
|
|
209
|
+
restoreState: state => {
|
|
210
|
+
if (this.multiple) {
|
|
211
|
+
// A multiple combobox submits FormData; recover its entries for our name.
|
|
212
|
+
this.setValueFromForm(state instanceof FormData && this.name ? state.getAll(this.name).map(String) : []);
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
this.setValueFromForm(typeof state === 'string' ? state : '');
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
});
|
|
219
|
+
// form.reset() goes back to the selection the combobox was authored with.
|
|
220
|
+
this.formControl.captureInitial(Array.isArray(this.internalValue) ? [...this.internalValue] : this.internalValue);
|
|
221
|
+
// Seed the form value so an unchanged combobox still submits its initial value.
|
|
222
|
+
this.formControl.sync();
|
|
196
223
|
}
|
|
197
224
|
componentDidLoad() {
|
|
198
225
|
this.updateContextOnElement();
|
|
@@ -219,6 +246,45 @@ export class SekiCombobox {
|
|
|
219
246
|
}
|
|
220
247
|
this.updateContextOnElement();
|
|
221
248
|
}
|
|
249
|
+
handleFormStateChange() {
|
|
250
|
+
var _a;
|
|
251
|
+
(_a = this.formControl) === null || _a === void 0 ? void 0 : _a.sync();
|
|
252
|
+
}
|
|
253
|
+
// Form-associated lifecycle callbacks (all behaviour lives in FormControl)
|
|
254
|
+
formResetCallback() {
|
|
255
|
+
var _a;
|
|
256
|
+
(_a = this.formControl) === null || _a === void 0 ? void 0 : _a.reset();
|
|
257
|
+
}
|
|
258
|
+
formDisabledCallback(disabled) {
|
|
259
|
+
var _a;
|
|
260
|
+
(_a = this.formControl) === null || _a === void 0 ? void 0 : _a.setFieldsetDisabled(disabled);
|
|
261
|
+
}
|
|
262
|
+
formStateRestoreCallback(state) {
|
|
263
|
+
var _a;
|
|
264
|
+
(_a = this.formControl) === null || _a === void 0 ? void 0 : _a.restoreState(state);
|
|
265
|
+
}
|
|
266
|
+
/** Put the selection back to `next` without emitting `sekiChange` (reset is not a user edit). */
|
|
267
|
+
setValueFromForm(next) {
|
|
268
|
+
const value = Array.isArray(next) ? [...next] : next;
|
|
269
|
+
this.internalValue = value;
|
|
270
|
+
this.value = value;
|
|
271
|
+
}
|
|
272
|
+
isValueEmpty() {
|
|
273
|
+
const v = this.internalValue;
|
|
274
|
+
return Array.isArray(v) ? v.length === 0 : v === '' || v === undefined || v === null;
|
|
275
|
+
}
|
|
276
|
+
getFormValue() {
|
|
277
|
+
if (this.multiple) {
|
|
278
|
+
const values = Array.isArray(this.internalValue) ? this.internalValue : [];
|
|
279
|
+
if (!this.name || values.length === 0)
|
|
280
|
+
return null;
|
|
281
|
+
const formData = new FormData();
|
|
282
|
+
for (const val of values)
|
|
283
|
+
formData.append(this.name, String(val));
|
|
284
|
+
return formData;
|
|
285
|
+
}
|
|
286
|
+
return this.isValueEmpty() ? null : String(this.internalValue);
|
|
287
|
+
}
|
|
222
288
|
handleOpenPropChange(newOpen) {
|
|
223
289
|
if (newOpen !== undefined) {
|
|
224
290
|
this.isOpen = newOpen;
|
|
@@ -361,10 +427,11 @@ export class SekiCombobox {
|
|
|
361
427
|
// Render
|
|
362
428
|
// ===========================
|
|
363
429
|
render() {
|
|
364
|
-
return (h(Host, { key: '
|
|
430
|
+
return (h(Host, { key: 'b25ca5b559cb21768c5b9a6393bcee483dd40b1d', role: "combobox", "aria-expanded": this.isOpen ? 'true' : 'false', "aria-haspopup": "listbox", "aria-owns": this.listboxId, "aria-label": this.ariaLabel, "aria-labelledby": this.ariaLabelledby, "aria-describedby": this.ariaDescribedby }, h("div", { key: '2866fe0ec4d3d84b8568e4bcedc2a38aa2cd0047', class: "combobox-container" }, h("slot", { key: '630ea691c0b83e8b7aa7cefa8ae5704fa8a91017' }))));
|
|
365
431
|
}
|
|
366
432
|
static get is() { return "seki-combobox"; }
|
|
367
433
|
static get encapsulation() { return "shadow"; }
|
|
434
|
+
static get formAssociated() { return true; }
|
|
368
435
|
static get originalStyleUrls() {
|
|
369
436
|
return {
|
|
370
437
|
"$": ["seki-combobox.css"]
|
|
@@ -596,6 +663,25 @@ export class SekiCombobox {
|
|
|
596
663
|
"attribute": "required",
|
|
597
664
|
"defaultValue": "false"
|
|
598
665
|
},
|
|
666
|
+
"name": {
|
|
667
|
+
"type": "string",
|
|
668
|
+
"mutable": false,
|
|
669
|
+
"complexType": {
|
|
670
|
+
"original": "string",
|
|
671
|
+
"resolved": "string | undefined",
|
|
672
|
+
"references": {}
|
|
673
|
+
},
|
|
674
|
+
"required": false,
|
|
675
|
+
"optional": true,
|
|
676
|
+
"docs": {
|
|
677
|
+
"tags": [],
|
|
678
|
+
"text": "Form field name for form submission"
|
|
679
|
+
},
|
|
680
|
+
"getter": false,
|
|
681
|
+
"setter": false,
|
|
682
|
+
"reflect": true,
|
|
683
|
+
"attribute": "name"
|
|
684
|
+
},
|
|
599
685
|
"open": {
|
|
600
686
|
"type": "boolean",
|
|
601
687
|
"mutable": true,
|
|
@@ -886,6 +972,21 @@ export class SekiCombobox {
|
|
|
886
972
|
return [{
|
|
887
973
|
"propName": "value",
|
|
888
974
|
"methodName": "handleValuePropChange"
|
|
975
|
+
}, {
|
|
976
|
+
"propName": "internalValue",
|
|
977
|
+
"methodName": "handleFormStateChange"
|
|
978
|
+
}, {
|
|
979
|
+
"propName": "disabled",
|
|
980
|
+
"methodName": "handleFormStateChange"
|
|
981
|
+
}, {
|
|
982
|
+
"propName": "required",
|
|
983
|
+
"methodName": "handleFormStateChange"
|
|
984
|
+
}, {
|
|
985
|
+
"propName": "multiple",
|
|
986
|
+
"methodName": "handleFormStateChange"
|
|
987
|
+
}, {
|
|
988
|
+
"propName": "name",
|
|
989
|
+
"methodName": "handleFormStateChange"
|
|
889
990
|
}, {
|
|
890
991
|
"propName": "open",
|
|
891
992
|
"methodName": "handleOpenPropChange"
|
|
@@ -915,4 +1016,5 @@ export class SekiCombobox {
|
|
|
915
1016
|
"passive": false
|
|
916
1017
|
}];
|
|
917
1018
|
}
|
|
1019
|
+
static get attachInternalsMemberName() { return "internals"; }
|
|
918
1020
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { h, Host } from "@stencil/core";
|
|
2
2
|
import { clearTypeahead, focusFirstMenuItem, handleMenuKeyDown } from "../../utils/menu-navigation";
|
|
3
|
+
import { ContextConsumer } from "../../utils/context-bridge";
|
|
3
4
|
const NAV_CONFIG = {
|
|
4
5
|
itemSelector: 'seki-dropdown-menu-item, seki-dropdown-menu-checkbox, seki-dropdown-menu-radio, seki-dropdown-menu-sub',
|
|
5
6
|
subContentSelector: 'seki-dropdown-menu-sub [slot="content"]',
|
|
@@ -14,17 +15,20 @@ const NAV_CONFIG = {
|
|
|
14
15
|
export class SekiContextMenuContent {
|
|
15
16
|
constructor() {
|
|
16
17
|
this.typeahead = { buffer: '' };
|
|
17
|
-
this.
|
|
18
|
+
this.hasLoaded = false;
|
|
19
|
+
this.menu = new ContextConsumer('seki-context-menu', '_contextMenuContext', (context) => {
|
|
18
20
|
var _a;
|
|
19
|
-
const
|
|
21
|
+
const wasOpen = this._isOpen;
|
|
20
22
|
this._isOpen = (_a = context === null || context === void 0 ? void 0 : context.isOpen) !== null && _a !== void 0 ? _a : false;
|
|
21
|
-
|
|
23
|
+
// Focus the first item when the menu opens after mount; an initially open
|
|
24
|
+
// menu keeps focus where it is, as before.
|
|
25
|
+
if (this.hasLoaded && this._isOpen && !wasOpen) {
|
|
22
26
|
requestAnimationFrame(() => {
|
|
23
27
|
this.updatePosition();
|
|
24
28
|
void focusFirstMenuItem(this.el, NAV_CONFIG);
|
|
25
29
|
});
|
|
26
30
|
}
|
|
27
|
-
};
|
|
31
|
+
});
|
|
28
32
|
/**
|
|
29
33
|
* Internal open state
|
|
30
34
|
*/
|
|
@@ -35,19 +39,13 @@ export class SekiContextMenuContent {
|
|
|
35
39
|
this._position = { top: '0', left: '0' };
|
|
36
40
|
}
|
|
37
41
|
getContext() {
|
|
38
|
-
|
|
39
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
40
|
-
return menu ? menu._contextMenuContext : null;
|
|
42
|
+
return this.menu.context;
|
|
41
43
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const context = this.getContext();
|
|
45
|
-
this._isOpen = (_a = context === null || context === void 0 ? void 0 : context.isOpen) !== null && _a !== void 0 ? _a : false;
|
|
44
|
+
connectedCallback() {
|
|
45
|
+
this.menu.connect(this.el);
|
|
46
46
|
}
|
|
47
47
|
componentDidLoad() {
|
|
48
|
-
|
|
49
|
-
this.menuEl = (_a = this.el.closest('seki-context-menu')) !== null && _a !== void 0 ? _a : undefined;
|
|
50
|
-
(_b = this.menuEl) === null || _b === void 0 ? void 0 : _b.addEventListener('sekiOpenChange', this.onMenuOpenChange);
|
|
48
|
+
this.hasLoaded = true;
|
|
51
49
|
}
|
|
52
50
|
componentDidRender() {
|
|
53
51
|
if (this._isOpen) {
|
|
@@ -99,9 +97,8 @@ export class SekiContextMenuContent {
|
|
|
99
97
|
this._position = next;
|
|
100
98
|
}
|
|
101
99
|
disconnectedCallback() {
|
|
102
|
-
var _a;
|
|
103
100
|
clearTypeahead(this.typeahead);
|
|
104
|
-
|
|
101
|
+
this.menu.disconnect();
|
|
105
102
|
}
|
|
106
103
|
render() {
|
|
107
104
|
if (!this._isOpen) {
|