@sekiui/elements 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/dist/cdn/p-C9-yH6MD.js +33 -0
  2. package/dist/cdn/seki-carousel-dots.js +7 -3
  3. package/dist/cdn/seki-carousel-next.js +8 -6
  4. package/dist/cdn/seki-carousel-previous.js +8 -6
  5. package/dist/cdn/seki-carousel.js +15 -1
  6. package/dist/cdn/seki-hover-card-content.js +2 -2
  7. package/dist/cdn/seki-hover-card-trigger.js +3 -3
  8. package/dist/cdn/seki-hover-card.js +2 -2
  9. package/dist/cdn/seki-resizable-handle.js +11 -2
  10. package/dist/cdn/seki-resizable-panel-group.js +9 -3
  11. package/dist/cdn/seki-resizable-panel.js +42 -20
  12. package/dist/cdn/seki-select.js +2 -2
  13. package/dist/cdn/seki-sidebar-footer.js +3 -1
  14. package/dist/cdn/seki-sidebar-header.js +3 -1
  15. package/dist/cdn/seki-sidebar-menu-button.js +3 -1
  16. package/dist/cdn/seki-sidebar-rail.js +3 -1
  17. package/dist/cdn/seki-sidebar-trigger.js +6 -1
  18. package/dist/cdn/seki-sidebar.js +5 -2
  19. package/dist/cjs/seki-carousel-dots.cjs.entry.js +7 -3
  20. package/dist/cjs/seki-carousel-next.cjs.entry.js +8 -6
  21. package/dist/cjs/seki-carousel-previous.cjs.entry.js +8 -6
  22. package/dist/cjs/seki-carousel.cjs.entry.js +15 -1
  23. package/dist/cjs/seki-hover-card-content.cjs.entry.js +2 -2
  24. package/dist/cjs/seki-hover-card-trigger.cjs.entry.js +3 -3
  25. package/dist/cjs/seki-hover-card.cjs.entry.js +2 -2
  26. package/dist/cjs/seki-resizable-handle.cjs.entry.js +11 -2
  27. package/dist/cjs/seki-resizable-panel-group.cjs.entry.js +9 -3
  28. package/dist/cjs/seki-resizable-panel.cjs.entry.js +42 -20
  29. package/dist/cjs/seki-select.cjs.entry.js +2 -2
  30. package/dist/cjs/seki-sidebar-footer.cjs.entry.js +3 -1
  31. package/dist/cjs/seki-sidebar-header.cjs.entry.js +3 -1
  32. package/dist/cjs/seki-sidebar-menu-button.cjs.entry.js +3 -1
  33. package/dist/cjs/seki-sidebar-rail.cjs.entry.js +3 -1
  34. package/dist/cjs/seki-sidebar-trigger.cjs.entry.js +6 -1
  35. package/dist/cjs/seki-sidebar.cjs.entry.js +5 -2
  36. package/dist/cjs/when-defined-B2Lkz6uR.js +36 -0
  37. package/dist/collection/components/carousel/seki-carousel-dots.js +7 -3
  38. package/dist/collection/components/carousel/seki-carousel-next.js +8 -6
  39. package/dist/collection/components/carousel/seki-carousel-previous.js +8 -6
  40. package/dist/collection/components/carousel/seki-carousel.js +15 -1
  41. package/dist/collection/components/hover-card/seki-hover-card-content.js +2 -2
  42. package/dist/collection/components/hover-card/seki-hover-card-trigger.js +3 -3
  43. package/dist/collection/components/hover-card/seki-hover-card.js +5 -5
  44. package/dist/collection/components/resizable/seki-resizable-handle.js +11 -2
  45. package/dist/collection/components/resizable/seki-resizable-panel-group.js +23 -3
  46. package/dist/collection/components/resizable/seki-resizable-panel.js +42 -20
  47. package/dist/collection/components/select/seki-select.js +6 -12
  48. package/dist/collection/components/sidebar/seki-sidebar-footer.js +3 -1
  49. package/dist/collection/components/sidebar/seki-sidebar-header.js +3 -1
  50. package/dist/collection/components/sidebar/seki-sidebar-menu-button.js +3 -1
  51. package/dist/collection/components/sidebar/seki-sidebar-rail.js +3 -1
  52. package/dist/collection/components/sidebar/seki-sidebar-trigger.js +6 -1
  53. package/dist/collection/components/sidebar/seki-sidebar.js +5 -2
  54. package/dist/collection/utils/when-defined.js +31 -0
  55. package/dist/components/p-C9-yH6MD.js +33 -0
  56. package/dist/components/seki-carousel-dots.js +7 -3
  57. package/dist/components/seki-carousel-next.js +8 -6
  58. package/dist/components/seki-carousel-previous.js +8 -6
  59. package/dist/components/seki-carousel.js +15 -1
  60. package/dist/components/seki-hover-card-content.js +2 -2
  61. package/dist/components/seki-hover-card-trigger.js +3 -3
  62. package/dist/components/seki-hover-card.js +2 -2
  63. package/dist/components/seki-resizable-handle.js +11 -2
  64. package/dist/components/seki-resizable-panel-group.js +9 -3
  65. package/dist/components/seki-resizable-panel.js +42 -20
  66. package/dist/components/seki-select.js +2 -2
  67. package/dist/components/seki-sidebar-footer.js +3 -1
  68. package/dist/components/seki-sidebar-header.js +3 -1
  69. package/dist/components/seki-sidebar-menu-button.js +3 -1
  70. package/dist/components/seki-sidebar-rail.js +3 -1
  71. package/dist/components/seki-sidebar-trigger.js +6 -1
  72. package/dist/components/seki-sidebar.js +5 -2
  73. package/dist/esm/seki-carousel-dots.entry.js +7 -3
  74. package/dist/esm/seki-carousel-next.entry.js +8 -6
  75. package/dist/esm/seki-carousel-previous.entry.js +8 -6
  76. package/dist/esm/seki-carousel.entry.js +15 -1
  77. package/dist/esm/seki-hover-card-content.entry.js +2 -2
  78. package/dist/esm/seki-hover-card-trigger.entry.js +3 -3
  79. package/dist/esm/seki-hover-card.entry.js +2 -2
  80. package/dist/esm/seki-resizable-handle.entry.js +11 -2
  81. package/dist/esm/seki-resizable-panel-group.entry.js +9 -3
  82. package/dist/esm/seki-resizable-panel.entry.js +42 -20
  83. package/dist/esm/seki-select.entry.js +2 -2
  84. package/dist/esm/seki-sidebar-footer.entry.js +3 -1
  85. package/dist/esm/seki-sidebar-header.entry.js +3 -1
  86. package/dist/esm/seki-sidebar-menu-button.entry.js +3 -1
  87. package/dist/esm/seki-sidebar-rail.entry.js +3 -1
  88. package/dist/esm/seki-sidebar-trigger.entry.js +6 -1
  89. package/dist/esm/seki-sidebar.entry.js +5 -2
  90. package/dist/esm/when-defined-C9-yH6MD.js +33 -0
  91. package/dist/sekiui/p-02f1728e.entry.js +1 -0
  92. package/dist/sekiui/p-12e36a4f.entry.js +1 -0
  93. package/dist/sekiui/p-1e24698b.entry.js +1 -0
  94. package/dist/sekiui/p-26bb17cb.entry.js +1 -0
  95. package/dist/sekiui/p-26d433ff.entry.js +1 -0
  96. package/dist/sekiui/p-26f96e2d.entry.js +1 -0
  97. package/dist/sekiui/p-29b22c0f.entry.js +1 -0
  98. package/dist/sekiui/p-30fafcc6.entry.js +1 -0
  99. package/dist/sekiui/p-71656184.entry.js +1 -0
  100. package/dist/sekiui/p-7926c04a.entry.js +1 -0
  101. package/dist/sekiui/p-9f4149b9.entry.js +1 -0
  102. package/dist/sekiui/p-C9-yH6MD.js +1 -0
  103. package/dist/sekiui/p-ae87ca35.entry.js +1 -0
  104. package/dist/sekiui/p-bf151423.entry.js +1 -0
  105. package/dist/sekiui/p-d10a186d.entry.js +1 -0
  106. package/dist/sekiui/p-d1c72c91.entry.js +1 -0
  107. package/dist/sekiui/p-d1d3ae40.entry.js +1 -0
  108. package/dist/sekiui/p-fba3fa73.entry.js +1 -0
  109. package/dist/sekiui/sekiui.esm.js +1 -1
  110. package/dist/types/components/carousel/seki-carousel.d.ts +1 -0
  111. package/dist/types/components/hover-card/seki-hover-card.d.ts +3 -4
  112. package/dist/types/components/resizable/seki-resizable-handle.d.ts +1 -0
  113. package/dist/types/components/resizable/seki-resizable-panel-group.d.ts +6 -0
  114. package/dist/types/components/resizable/seki-resizable-panel.d.ts +9 -0
  115. package/dist/types/components/select/seki-select.d.ts +3 -3
  116. package/dist/types/components.d.ts +13 -8
  117. package/dist/types/utils/select/types.d.ts +0 -7
  118. package/dist/types/utils/when-defined.d.ts +19 -0
  119. package/package.json +3 -1
  120. package/dist/sekiui/p-01f26bec.entry.js +0 -1
  121. package/dist/sekiui/p-117b6f5a.entry.js +0 -1
  122. package/dist/sekiui/p-1250cad1.entry.js +0 -1
  123. package/dist/sekiui/p-219c8350.entry.js +0 -1
  124. package/dist/sekiui/p-2e2e7d0b.entry.js +0 -1
  125. package/dist/sekiui/p-346cc18f.entry.js +0 -1
  126. package/dist/sekiui/p-6311a4d8.entry.js +0 -1
  127. package/dist/sekiui/p-69843ed8.entry.js +0 -1
  128. package/dist/sekiui/p-88dd3e1f.entry.js +0 -1
  129. package/dist/sekiui/p-944c70a1.entry.js +0 -1
  130. package/dist/sekiui/p-9820cd16.entry.js +0 -1
  131. package/dist/sekiui/p-a2ae6d1b.entry.js +0 -1
  132. package/dist/sekiui/p-b45e11d8.entry.js +0 -1
  133. package/dist/sekiui/p-caa51bdf.entry.js +0 -1
  134. package/dist/sekiui/p-ce986fde.entry.js +0 -1
  135. package/dist/sekiui/p-ede4bb0c.entry.js +0 -1
  136. package/dist/sekiui/p-f4abd9a2.entry.js +0 -1
@@ -1,6 +1,7 @@
1
1
  // src/components/resizable/seki-resizable-panel-group.tsx
2
2
  import { h, Host } from "@stencil/core";
3
3
  import { syncTheme } from "../../utils/theme-sync";
4
+ import { publishContext } from "../../utils/context-bridge";
4
5
  const STORAGE_KEY_PREFIX = 'seki-resizable:';
5
6
  function clamp(value, min, max) {
6
7
  return Math.min(Math.max(value, min), max);
@@ -247,7 +248,7 @@ export class SekiResizablePanelGroup {
247
248
  this.restoreLayout();
248
249
  }
249
250
  updateContext() {
250
- this._resizableContext = {
251
+ const context = {
251
252
  direction: this.direction,
252
253
  disabled: this.disabled,
253
254
  registerPanel: this.registerPanel,
@@ -260,6 +261,10 @@ export class SekiResizablePanelGroup {
260
261
  isCollapsed: this.isCollapsed,
261
262
  getHandleIndex: this.getHandleIndex,
262
263
  };
264
+ this._resizableContext = context;
265
+ // Publish on the host so children reach it via closest() in every build,
266
+ // and notify any child that mounted before this group was defined.
267
+ publishContext(this.el, '_resizableContext', context, this.contextChange);
263
268
  }
264
269
  emitLayoutChange() {
265
270
  const sizes = this._panelOrder.map((id) => { var _a, _b; return (_b = (_a = this._panels.get(id)) === null || _a === void 0 ? void 0 : _a.size) !== null && _b !== void 0 ? _b : 0; });
@@ -311,11 +316,11 @@ export class SekiResizablePanelGroup {
311
316
  syncTheme(this.el);
312
317
  }
313
318
  render() {
314
- return (h(Host, { key: '1d6170c745798c0608abae51b7d2bbbf51b10f99' }, h("div", { key: '517e36739e6857b55d9719f191f4cb0695ca5aaa', part: "group", role: "group", "aria-label": "Resizable panel group", class: {
319
+ return (h(Host, { key: '4050d03c828d3bd09ddd73ab9009b81ffcb2a2cd' }, h("div", { key: '148dba7f6173a023c861cfdd49e626773e317c23', part: "group", role: "group", "aria-label": "Resizable panel group", class: {
315
320
  'resizable-panel-group': true,
316
321
  'resizable-panel-group--horizontal': this.direction === 'horizontal',
317
322
  'resizable-panel-group--vertical': this.direction === 'vertical',
318
- } }, h("slot", { key: '66621ac830e9e164ad833b58124504df9812c930' }))));
323
+ } }, h("slot", { key: '076d2200fad74c84d01970985d443a8cdd7d00ff' }))));
319
324
  }
320
325
  static get is() { return "seki-resizable-panel-group"; }
321
326
  static get encapsulation() { return "shadow"; }
@@ -429,6 +434,21 @@ export class SekiResizablePanelGroup {
429
434
  "resolved": "\"horizontal\" | \"vertical\"",
430
435
  "references": {}
431
436
  }
437
+ }, {
438
+ "method": "contextChange",
439
+ "name": "sekiContextChange",
440
+ "bubbles": true,
441
+ "cancelable": true,
442
+ "composed": true,
443
+ "docs": {
444
+ "tags": [],
445
+ "text": "Internal: fired whenever `_resizableContext` is (re)published so panels and\nhandles that mounted before this group was defined can register late.\nSee utils/context-bridge.ts \u2014 no payload by design."
446
+ },
447
+ "complexType": {
448
+ "original": "void",
449
+ "resolved": "void",
450
+ "references": {}
451
+ }
432
452
  }];
433
453
  }
434
454
  static get elementRef() { return "el"; }
@@ -1,6 +1,7 @@
1
1
  // src/components/resizable/seki-resizable-panel.tsx
2
2
  import { h, Host } from "@stencil/core";
3
3
  import { syncTheme } from "../../utils/theme-sync";
4
+ import { subscribeToContextChange } from "../../utils/context-bridge";
4
5
  let panelIdCounter = 0;
5
6
  /**
6
7
  * Resizable panel - individual content panel with size constraints
@@ -31,9 +32,35 @@ export class SekiResizablePanel {
31
32
  this.collapsedSize = 0;
32
33
  this._size = 0;
33
34
  this._isCollapsed = false;
35
+ this.hasRegistered = false;
36
+ this.contextSubscription = null;
34
37
  this.handleLayoutChange = () => {
35
38
  this.updateSize();
36
39
  };
40
+ /**
41
+ * The group publishes its context when *it* loads, which in the per-tag
42
+ * custom-elements build can be after this panel's componentWillLoad. Register
43
+ * whenever the context is (re)published; the group ignores duplicates.
44
+ */
45
+ this.handleParentContextChange = () => {
46
+ this.registerWithGroup();
47
+ this.updateSize();
48
+ };
49
+ }
50
+ registerWithGroup() {
51
+ if (this.hasRegistered)
52
+ return;
53
+ const context = this.getContext();
54
+ if (!context)
55
+ return;
56
+ context.registerPanel(this.panelId, {
57
+ defaultSize: this.defaultSize,
58
+ minSize: this.minSize,
59
+ maxSize: this.maxSize,
60
+ collapsible: this.collapsible,
61
+ collapsedSize: this.collapsedSize,
62
+ });
63
+ this.hasRegistered = true;
37
64
  }
38
65
  getContext() {
39
66
  const group = this.el.closest('seki-resizable-panel-group');
@@ -42,16 +69,7 @@ export class SekiResizablePanel {
42
69
  }
43
70
  componentWillLoad() {
44
71
  this.panelId = `panel-${++panelIdCounter}`;
45
- const context = this.getContext();
46
- if (context) {
47
- context.registerPanel(this.panelId, {
48
- defaultSize: this.defaultSize,
49
- minSize: this.minSize,
50
- maxSize: this.maxSize,
51
- collapsible: this.collapsible,
52
- collapsedSize: this.collapsedSize,
53
- });
54
- }
72
+ this.registerWithGroup();
55
73
  }
56
74
  componentDidLoad() {
57
75
  const group = this.el.closest('seki-resizable-panel-group');
@@ -59,34 +77,38 @@ export class SekiResizablePanel {
59
77
  this.groupElement = group;
60
78
  group.addEventListener('sekiLayoutChange', this.handleLayoutChange);
61
79
  }
80
+ this.contextSubscription = subscribeToContextChange(this.el, 'seki-resizable-panel-group', this.handleParentContextChange);
81
+ this.registerWithGroup();
62
82
  this.updateSize();
63
83
  }
64
84
  connectedCallback() {
65
85
  syncTheme(this.el);
86
+ // Re-register after a DOM move; componentWillLoad only fires once.
87
+ if (this.panelId)
88
+ this.registerWithGroup();
66
89
  }
67
90
  disconnectedCallback() {
91
+ var _a;
68
92
  // Remove event listener to prevent memory leak
69
93
  if (this.groupElement) {
70
94
  this.groupElement.removeEventListener('sekiLayoutChange', this.handleLayoutChange);
71
95
  }
96
+ (_a = this.contextSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
97
+ this.contextSubscription = null;
72
98
  // Unregister panel from group
73
99
  const context = this.getContext();
74
100
  if (context) {
75
101
  context.unregisterPanel(this.panelId);
76
102
  }
103
+ this.hasRegistered = false;
77
104
  }
78
105
  handleConstraintChange() {
79
106
  const context = this.getContext();
80
107
  if (context) {
81
108
  // Re-register with new constraints
82
109
  context.unregisterPanel(this.panelId);
83
- context.registerPanel(this.panelId, {
84
- defaultSize: this.defaultSize,
85
- minSize: this.minSize,
86
- maxSize: this.maxSize,
87
- collapsible: this.collapsible,
88
- collapsedSize: this.collapsedSize,
89
- });
110
+ this.hasRegistered = false;
111
+ this.registerWithGroup();
90
112
  }
91
113
  }
92
114
  updateSize() {
@@ -144,14 +166,14 @@ export class SekiResizablePanel {
144
166
  return this.panelId;
145
167
  }
146
168
  render() {
147
- return (h(Host, { key: '6b53e0ef0f75bbde83bb9e318a55ab8261498737', style: {
169
+ return (h(Host, { key: '69f32198c8537b16e91222dcfcbb23c18dc37782', style: {
148
170
  flexBasis: `${this._size}%`,
149
171
  flexGrow: '0',
150
172
  flexShrink: '0',
151
- } }, h("div", { key: 'dd9e5c4165ed0e65aa5949373871240fdacd3e44', part: "panel", role: "region", class: {
173
+ } }, h("div", { key: 'f45c47381a87eca45473a2da2a035bbff4c1b745', part: "panel", role: "region", class: {
152
174
  'resizable-panel': true,
153
175
  'resizable-panel--collapsed': this._isCollapsed,
154
- } }, h("slot", { key: '230de96b3ac24f7f0bbd470bf92d91e43a56f374' }))));
176
+ } }, h("slot", { key: '1f9f46fd08e315a79cc806b72c56a450c75c7ed5' }))));
155
177
  }
156
178
  static get is() { return "seki-resizable-panel"; }
157
179
  static get encapsulation() { return "shadow"; }
@@ -86,7 +86,7 @@ export class SekiSelect {
86
86
  this.hasBeenActivated = true;
87
87
  }
88
88
  // Emit event
89
- this.sekiOpenChange.emit({ open });
89
+ this.sekiOpenChange.emit(open);
90
90
  // Validate on close if required
91
91
  if (!open && this.required && this.hasBeenActivated) {
92
92
  this.validateRequired();
@@ -396,7 +396,7 @@ export class SekiSelect {
396
396
  // Render
397
397
  // ===========================
398
398
  render() {
399
- return (h(Host, { key: '4a9f13dc6746a13b0b99bf03b8092d48ab475677' }, h("slot", { key: '9c49228973bc8e62ec2129c5c3f72fadf608081f' })));
399
+ return (h(Host, { key: 'd89c2754151f8faf545b616b5dce64b4dbbfd1a4' }, h("slot", { key: 'b5bf2a24deed68b33849b9fbcb6b091297885367' })));
400
400
  }
401
401
  static get is() { return "seki-select"; }
402
402
  static get encapsulation() { return "shadow"; }
@@ -767,18 +767,12 @@ export class SekiSelect {
767
767
  "composed": true,
768
768
  "docs": {
769
769
  "tags": [],
770
- "text": "Emitted when dropdown open state changes"
770
+ "text": "Emitted when dropdown open state changes; `detail` is the new open state as a bare boolean"
771
771
  },
772
772
  "complexType": {
773
- "original": "SelectOpenChangeEventDetail",
774
- "resolved": "SelectOpenChangeEventDetail",
775
- "references": {
776
- "SelectOpenChangeEventDetail": {
777
- "location": "import",
778
- "path": "../../utils/select",
779
- "id": "src/utils/select/index.ts::SelectOpenChangeEventDetail"
780
- }
781
- }
773
+ "original": "boolean",
774
+ "resolved": "boolean",
775
+ "references": {}
782
776
  }
783
777
  }, {
784
778
  "method": "sekiValidate",
@@ -1,5 +1,6 @@
1
1
  import { h, Host } from "@stencil/core";
2
2
  import { syncTheme } from "../../utils/theme-sync";
3
+ import { whenDefined } from "../../utils/when-defined";
3
4
  export class SekiSidebarFooter {
4
5
  constructor() {
5
6
  this._isIconMode = false;
@@ -10,6 +11,7 @@ export class SekiSidebarFooter {
10
11
  async syncWithProvider() {
11
12
  const provider = document.querySelector('seki-sidebar-provider');
12
13
  if (provider) {
14
+ await whenDefined('seki-sidebar-provider');
13
15
  const state = await provider.getState();
14
16
  this._isIconMode = !state.open && !state.isMobile;
15
17
  }
@@ -21,7 +23,7 @@ export class SekiSidebarFooter {
21
23
  syncTheme(this.el);
22
24
  }
23
25
  render() {
24
- return (h(Host, { key: '9a2ebdc291b6ed7daa648c4b76684791b434477f', "data-icon-mode": this._isIconMode ? 'true' : 'false' }, h("div", { key: '8d3748862827f9d9173d8a567defaf4945b729e3', class: { 'sidebar-footer': true, 'sidebar-footer--icon-mode': this._isIconMode } }, h("slot", { key: '499a4a2e38198ed2e7c808d4b8671f2828e72e3a' }))));
26
+ return (h(Host, { key: '97bbed99c8e35ed1d85fa6267e47350a1d0c61bb', "data-icon-mode": this._isIconMode ? 'true' : 'false' }, h("div", { key: 'e951a73db7bfb322726ff0db795808d7ce99b3a6', class: { 'sidebar-footer': true, 'sidebar-footer--icon-mode': this._isIconMode } }, h("slot", { key: 'ae12b7373d704f56fcb75bba1f5c000cf19d6c90' }))));
25
27
  }
26
28
  static get is() { return "seki-sidebar-footer"; }
27
29
  static get encapsulation() { return "shadow"; }
@@ -1,5 +1,6 @@
1
1
  import { h, Host } from "@stencil/core";
2
2
  import { syncTheme } from "../../utils/theme-sync";
3
+ import { whenDefined } from "../../utils/when-defined";
3
4
  export class SekiSidebarHeader {
4
5
  constructor() {
5
6
  this._isIconMode = false;
@@ -10,6 +11,7 @@ export class SekiSidebarHeader {
10
11
  async syncWithProvider() {
11
12
  const provider = document.querySelector('seki-sidebar-provider');
12
13
  if (provider) {
14
+ await whenDefined('seki-sidebar-provider');
13
15
  const state = await provider.getState();
14
16
  this._isIconMode = !state.open && !state.isMobile;
15
17
  }
@@ -21,7 +23,7 @@ export class SekiSidebarHeader {
21
23
  syncTheme(this.el);
22
24
  }
23
25
  render() {
24
- return (h(Host, { key: 'dffab004a98884d98974fb7bd513d36c58a614f6', "data-icon-mode": this._isIconMode ? 'true' : 'false' }, h("div", { key: '3779d79509479f6e2e03d67e17f480ce833f79d2', class: { 'sidebar-header': true, 'sidebar-header--icon-mode': this._isIconMode } }, h("slot", { key: 'bd0dc0a0ffb50302594a82a5d66baee214228c89' }))));
26
+ return (h(Host, { key: 'db0e734d2c3a823fdee113913da5dc8d77b2c74a', "data-icon-mode": this._isIconMode ? 'true' : 'false' }, h("div", { key: 'f3bc87e475391af3f6bd1914e11647aaefdcb28f', class: { 'sidebar-header': true, 'sidebar-header--icon-mode': this._isIconMode } }, h("slot", { key: '9936d52c8d5c835be4db99fdea7b4133464f0bfe' }))));
25
27
  }
26
28
  static get is() { return "seki-sidebar-header"; }
27
29
  static get encapsulation() { return "shadow"; }
@@ -1,5 +1,6 @@
1
1
  import { h } from "@stencil/core";
2
2
  import { syncTheme } from "../../utils/theme-sync";
3
+ import { whenDefined } from "../../utils/when-defined";
3
4
  export class SekiSidebarMenuButton {
4
5
  constructor() {
5
6
  /**
@@ -30,6 +31,7 @@ export class SekiSidebarMenuButton {
30
31
  async syncWithProvider() {
31
32
  const provider = document.querySelector('seki-sidebar-provider');
32
33
  if (provider) {
34
+ await whenDefined('seki-sidebar-provider');
33
35
  const state = await provider.getState();
34
36
  this._isIconMode = !state.open && !state.isMobile;
35
37
  }
@@ -72,7 +74,7 @@ export class SekiSidebarMenuButton {
72
74
  buttonProps.tabIndex = -1;
73
75
  }
74
76
  }
75
- return (h(Tag, Object.assign({ key: '4ad764a828d94c36bd2c2f3da03021de7c840033' }, buttonProps), h("span", { key: '46d54d1c9c00da9ff872cbea5005e259a32b2bf1', class: "sidebar-menu-button-content" }, h("slot", { key: '74e7c32ee30b69e7a8e34339983657cda40ca604' })), this._isIconMode && this.tooltipText && (h("span", { key: 'dac5cc781bcbe62e5fd66e6fcd2278710218af92', class: "sr-only" }, this.tooltipText))));
77
+ return (h(Tag, Object.assign({ key: '5a9ae3864bd0f81f6a97016287654bf75daf781b' }, buttonProps), h("span", { key: '49aca3cd6870bed8b365ccd943b5ec2de09ff51b', class: "sidebar-menu-button-content" }, h("slot", { key: 'cf0ecec0ded3870521788cd0c7113e8c98d521f4' })), this._isIconMode && this.tooltipText && (h("span", { key: '272d33f45b0ad14a51de4f1af56b33549dcfb2c4', class: "sr-only" }, this.tooltipText))));
76
78
  }
77
79
  static get is() { return "seki-sidebar-menu-button"; }
78
80
  static get encapsulation() { return "shadow"; }
@@ -1,11 +1,13 @@
1
1
  import { h, Host } from "@stencil/core";
2
2
  import { syncTheme } from "../../utils/theme-sync";
3
+ import { whenDefined } from "../../utils/when-defined";
3
4
  import { mirrorAncestorAttributes } from "../../utils/ancestor-attrs";
4
5
  export class SekiSidebarRail {
5
6
  constructor() {
6
7
  this.handleClick = async () => {
7
8
  const provider = document.querySelector('seki-sidebar-provider');
8
9
  if (provider) {
10
+ await whenDefined('seki-sidebar-provider');
9
11
  await provider.toggleSidebar();
10
12
  }
11
13
  };
@@ -20,7 +22,7 @@ export class SekiSidebarRail {
20
22
  this.attrMirror = undefined;
21
23
  }
22
24
  render() {
23
- return (h(Host, { key: '79ffed26bc4327ba5f1de9b8bad97875e577bcc8' }, h("button", { key: 'd2239a1ee3fd2d7cb4af24e2d57bb776850d93a6', class: "sidebar-rail", type: "button", tabIndex: -1, "aria-hidden": "true", onClick: this.handleClick, title: "Toggle sidebar" }, h("slot", { key: 'd9677dcf1739a26c2c50d5297d86302e6deef5a4' }))));
25
+ return (h(Host, { key: '08ed37b7a0967238dfad84a8bd0f0f11fd750ccf' }, h("button", { key: '6c2dc41d659807fe6ce5f66a228d1157f8598b02', class: "sidebar-rail", type: "button", tabIndex: -1, "aria-hidden": "true", onClick: this.handleClick, title: "Toggle sidebar" }, h("slot", { key: 'd11d9face59e5aca55f21749376d6cb9464f612d' }))));
24
26
  }
25
27
  static get is() { return "seki-sidebar-rail"; }
26
28
  static get encapsulation() { return "shadow"; }
@@ -1,5 +1,6 @@
1
1
  import { h, Host } from "@stencil/core";
2
2
  import { syncTheme } from "../../utils/theme-sync";
3
+ import { whenDefined } from "../../utils/when-defined";
3
4
  export class SekiSidebarTrigger {
4
5
  constructor() {
5
6
  /**
@@ -11,6 +12,7 @@ export class SekiSidebarTrigger {
11
12
  this.provider = null;
12
13
  this.handleClick = async () => {
13
14
  if (this.provider && !this.disabled) {
15
+ await whenDefined('seki-sidebar-provider');
14
16
  await this.provider.toggleSidebar();
15
17
  }
16
18
  };
@@ -21,6 +23,9 @@ export class SekiSidebarTrigger {
21
23
  }
22
24
  async syncWithProvider() {
23
25
  if (this.provider) {
26
+ // In the per-tag custom-elements build the provider may still be an
27
+ // un-upgraded HTMLElement here; its @Methods only exist after definition.
28
+ await whenDefined('seki-sidebar-provider');
24
29
  const state = await this.provider.getState();
25
30
  this._isOpen = state.isMobile ? state.openMobile : state.open;
26
31
  this._isMobile = state.isMobile;
@@ -34,7 +39,7 @@ export class SekiSidebarTrigger {
34
39
  syncTheme(this.el);
35
40
  }
36
41
  render() {
37
- return (h(Host, { key: '710c2e498aba73505947fdd40ef4ebfa2fd6f452' }, h("button", { key: 'd08c906afe57f392fc09ce3cb165199bac889cb5', class: "sidebar-trigger", type: "button", disabled: this.disabled, onClick: this.handleClick, "aria-label": this._isOpen ? 'Close sidebar' : 'Open sidebar', "aria-expanded": this._isOpen ? 'true' : 'false', "data-state": this._isOpen ? 'open' : 'closed' }, h("slot", { key: 'd8a51ef01bdbf22fd04efc33195b83b583a0f80c' }, h("svg", { key: 'e78789a27515ea2478cb4ef0bac254b605a95cb0', 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("rect", { key: '55b0d78be2313cc2c4f6188747517c0723cdaa73', width: "18", height: "18", x: "3", y: "3", rx: "2" }), h("path", { key: '436522322595a5db692bbc25e8cd7eca1d55057f', d: "M9 3v18" }))), h("span", { key: 'db23ca2266166ba0271c3b5baf6ac16ec8c8ba4c', class: "sr-only" }, this._isOpen ? 'Close sidebar' : 'Open sidebar'))));
42
+ return (h(Host, { key: 'a18bf01eca1a28a9b4f7043af9d175582c842793' }, h("button", { key: '7dd9593f5a61a5162dfd57c63e6d07d21607a3c6', class: "sidebar-trigger", type: "button", disabled: this.disabled, onClick: this.handleClick, "aria-label": this._isOpen ? 'Close sidebar' : 'Open sidebar', "aria-expanded": this._isOpen ? 'true' : 'false', "data-state": this._isOpen ? 'open' : 'closed' }, h("slot", { key: '2a99e96d6ae89b2b9fe6278b8abebd07a49b1bba' }, h("svg", { key: '1f4d96e67ed5a0db4040de3a29747bd2b95d30cf', 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("rect", { key: '697fbbd25bfee694b0a58c736852ba61e8474552', width: "18", height: "18", x: "3", y: "3", rx: "2" }), h("path", { key: '0ccd3b41479789c19bd0c535665c562bd0d72e26', d: "M9 3v18" }))), h("span", { key: '172d3a201a80b474002ba5eded4ca56f025970cb', class: "sr-only" }, this._isOpen ? 'Close sidebar' : 'Open sidebar'))));
38
43
  }
39
44
  static get is() { return "seki-sidebar-trigger"; }
40
45
  static get encapsulation() { return "shadow"; }
@@ -1,5 +1,6 @@
1
1
  import { h, Host } from "@stencil/core";
2
2
  import { syncTheme } from "../../utils/theme-sync";
3
+ import { whenDefined } from "../../utils/when-defined";
3
4
  export class SekiSidebar {
4
5
  constructor() {
5
6
  /**
@@ -20,6 +21,7 @@ export class SekiSidebar {
20
21
  this.handleOverlayClick = async () => {
21
22
  const provider = this.el.closest('seki-sidebar-provider');
22
23
  if (provider && this._isMobile) {
24
+ await whenDefined('seki-sidebar-provider');
23
25
  await provider.setOpenMobile(false);
24
26
  }
25
27
  };
@@ -31,6 +33,7 @@ export class SekiSidebar {
31
33
  async syncWithProvider() {
32
34
  const provider = this.el.closest('seki-sidebar-provider');
33
35
  if (provider) {
36
+ await whenDefined('seki-sidebar-provider');
34
37
  const state = await provider.getState();
35
38
  this._open = state.open;
36
39
  this._openMobile = state.openMobile;
@@ -51,10 +54,10 @@ export class SekiSidebar {
51
54
  const isIconMode = this.collapsible === 'icon' && isClosed && !this._isMobile;
52
55
  const isOffcanvas = this.collapsible === 'offcanvas' && isClosed && !this._isMobile;
53
56
  const showMobileSheet = this._isMobile && this._openMobile;
54
- return (h(Host, { key: 'd0c658a422f9df8dfffb5b999950a30a55f7691e', "data-variant": this.variant, "data-collapsible": this.collapsible, "data-side": this.side, "data-state": isOpen ? 'open' : 'closed', "data-mobile": this._isMobile ? 'true' : 'false', "data-icon-mode": isIconMode ? 'true' : 'false', "data-offcanvas": isOffcanvas ? 'true' : 'false' }, showMobileSheet && (h("div", { key: '9349459bcee006b9ab721a838542e83fe230be54', class: "sidebar-overlay", onClick: this.handleOverlayClick, "aria-hidden": "true" })), h("aside", { key: '742b7a834dc63ceee602415005222c0317f66a3b', class: {
57
+ return (h(Host, { key: '191942c5c2d3d3c543b398f7bcbec0ae7e4177b8', "data-variant": this.variant, "data-collapsible": this.collapsible, "data-side": this.side, "data-state": isOpen ? 'open' : 'closed', "data-mobile": this._isMobile ? 'true' : 'false', "data-icon-mode": isIconMode ? 'true' : 'false', "data-offcanvas": isOffcanvas ? 'true' : 'false' }, showMobileSheet && (h("div", { key: 'bbdcc59f534b71525ae15c797bb2a9685d254e66', class: "sidebar-overlay", onClick: this.handleOverlayClick, "aria-hidden": "true" })), h("aside", { key: '8b8d5e372ef31d6d7fcad96284b02d55049e5344', class: {
55
58
  'sidebar': true,
56
59
  'sidebar--mobile-sheet': showMobileSheet,
57
- }, role: "complementary", "aria-label": "Sidebar" }, h("slot", { key: 'a2097f110bb64dbb251002f8e7fb566cd3b91158' }))));
60
+ }, role: "complementary", "aria-label": "Sidebar" }, h("slot", { key: 'c52ad8d438101ac1a5d339a4fac427587ae88be5' }))));
58
61
  }
59
62
  static get is() { return "seki-sidebar"; }
60
63
  static get encapsulation() { return "shadow"; }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Custom-element definition helpers for compound components.
3
+ *
4
+ * In the lazy-loaded build every tag is registered up front (as a proxy), so a
5
+ * child can always reach its parent's `@Method`s. In the `dist/components`
6
+ * custom-elements build each tag is defined by its own module, in whatever
7
+ * order those modules resolve — over a CDN that can be seconds apart. A child
8
+ * that calls `closest('seki-parent').someMethod()` while the parent is still
9
+ * an un-upgraded `HTMLElement` throws "someMethod is not a function" and the
10
+ * component silently loses its initial state (#314).
11
+ *
12
+ * `whenDefined(tag)` resolves immediately when the tag is already registered
13
+ * or when there is no `customElements` registry (SSR, some test runners), so
14
+ * awaiting it costs nothing on the happy path.
15
+ */
16
+ function registry() {
17
+ return typeof globalThis !== 'undefined' && globalThis.customElements ? globalThis.customElements : null;
18
+ }
19
+ /** True when `tag` is registered (or when there is no registry to ask). */
20
+ export function isDefined(tag) {
21
+ const reg = registry();
22
+ return !reg || typeof reg.get !== 'function' || !!reg.get(tag);
23
+ }
24
+ /** Resolves once `tag` is registered. Never rejects. */
25
+ export function whenDefined(tag) {
26
+ const reg = registry();
27
+ if (!reg || typeof reg.whenDefined !== 'function' || isDefined(tag)) {
28
+ return Promise.resolve();
29
+ }
30
+ return reg.whenDefined(tag).then(() => undefined, () => undefined);
31
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Custom-element definition helpers for compound components.
3
+ *
4
+ * In the lazy-loaded build every tag is registered up front (as a proxy), so a
5
+ * child can always reach its parent's `@Method`s. In the `dist/components`
6
+ * custom-elements build each tag is defined by its own module, in whatever
7
+ * order those modules resolve — over a CDN that can be seconds apart. A child
8
+ * that calls `closest('seki-parent').someMethod()` while the parent is still
9
+ * an un-upgraded `HTMLElement` throws "someMethod is not a function" and the
10
+ * component silently loses its initial state (#314).
11
+ *
12
+ * `whenDefined(tag)` resolves immediately when the tag is already registered
13
+ * or when there is no `customElements` registry (SSR, some test runners), so
14
+ * awaiting it costs nothing on the happy path.
15
+ */
16
+ function registry() {
17
+ return typeof globalThis !== 'undefined' && globalThis.customElements ? globalThis.customElements : null;
18
+ }
19
+ /** True when `tag` is registered (or when there is no registry to ask). */
20
+ function isDefined(tag) {
21
+ const reg = registry();
22
+ return !reg || typeof reg.get !== 'function' || !!reg.get(tag);
23
+ }
24
+ /** Resolves once `tag` is registered. Never rejects. */
25
+ function whenDefined(tag) {
26
+ const reg = registry();
27
+ if (!reg || typeof reg.whenDefined !== 'function' || isDefined(tag)) {
28
+ return Promise.resolve();
29
+ }
30
+ return reg.whenDefined(tag).then(() => undefined, () => undefined);
31
+ }
32
+
33
+ export { isDefined as i, whenDefined as w };
@@ -1,5 +1,6 @@
1
1
  import { p as proxyCustomElement, H, d as syncTheme, h, e as Host } from './p-BGFP3hxa.js';
2
2
  import { s as subscribeToContextChange } from './p-DJMgrCw3.js';
3
+ import { w as whenDefined } from './p-C9-yH6MD.js';
3
4
 
4
5
  const sekiCarouselDotsCss = ":host{display:flex;justify-content:center;width:100%;padding-top:0.75rem}.carousel-dots__container{display:flex;align-items:center;justify-content:center;gap:var(--seki-carousel-dot-gap, 0.5rem)}.carousel-dots__dot{display:flex;align-items:center;justify-content:center;padding:0.25rem;border:none;background:transparent;cursor:pointer;transition:transform 0.2s ease}.carousel-dots__dot:hover{transform:scale(1.2)}.carousel-dots__dot:focus-visible{outline:2px solid var(--seki-ring, hsl(0, 0%, 3.9%));outline-offset:2px;border-radius:50%}.carousel-dots__dot-inner{display:block;width:var(--seki-carousel-dot-size, 0.5rem);height:var(--seki-carousel-dot-size, 0.5rem);border-radius:50%;background:var(--seki-carousel-dot-color, var(--seki-muted-foreground, hsl(0, 0%, 42%)));transition:background-color 0.2s ease, width 0.2s ease, height 0.2s ease}.carousel-dots__dot--active .carousel-dots__dot-inner{width:var(--seki-carousel-dot-active-size, 0.625rem);height:var(--seki-carousel-dot-active-size, 0.625rem);background:var(--seki-carousel-dot-active-color, var(--seki-foreground, hsl(0, 0%, 3.9%)))}@media (prefers-reduced-motion: reduce){.carousel-dots__dot,.carousel-dots__dot-inner{transition:none}}";
5
6
 
@@ -73,12 +74,15 @@ const SekiCarouselDots$1 = /*@__PURE__*/ proxyCustomElement(class SekiCarouselDo
73
74
  async subscribeToCarousel() {
74
75
  if (!this.parentCarousel)
75
76
  return;
76
- // Initial state
77
+ // Subscribe first so a context change can never be missed, then wait for
78
+ // <seki-carousel> to be *defined* — in the per-tag custom-elements build its
79
+ // @Methods do not exist until then (#314).
80
+ this.unsubscribe = subscribeToContextChange(this.el, 'seki-carousel', this.handleContextChange).unsubscribe;
81
+ await whenDefined('seki-carousel');
77
82
  await this.updateState();
78
83
  // Re-sync on every carousel context change — including embla's async init
79
84
  // and reInit, not just user navigation — so the dots reflect the real slide
80
85
  // count/position instead of freezing at their premature mount-time state (#274).
81
- this.unsubscribe = subscribeToContextChange(this.el, 'seki-carousel', this.handleContextChange).unsubscribe;
82
86
  }
83
87
  async updateState() {
84
88
  if (!this.parentCarousel)
@@ -89,7 +93,7 @@ const SekiCarouselDots$1 = /*@__PURE__*/ proxyCustomElement(class SekiCarouselDo
89
93
  }
90
94
  render() {
91
95
  const dots = Array.from({ length: this.scrollSnapCount }, (_, i) => i);
92
- return (h(Host, { key: '26e61e1799d34e8d750c02c1287f85461d8e99a6', class: "carousel-dots" }, h("div", { key: '8fea8befb4cfc3859da4c5f1ee1c6b8c1485e8da', class: "carousel-dots__container", role: "tablist", "aria-label": "Carousel pagination" }, dots.map((index) => (h("button", { key: index, type: "button", class: {
96
+ return (h(Host, { key: '3bc07e8ad34358f497c99b4a4a51d84efe3f0f5b', class: "carousel-dots" }, h("div", { key: 'b779622f331bb7899737f51eea87469980269f52', class: "carousel-dots__container", role: "tablist", "aria-label": "Carousel pagination" }, dots.map((index) => (h("button", { key: index, type: "button", class: {
93
97
  'carousel-dots__dot': true,
94
98
  'carousel-dots__dot--active': index === this.selectedIndex,
95
99
  }, 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" })))))));
@@ -1,5 +1,6 @@
1
1
  import { p as proxyCustomElement, H, d as syncTheme, h, e as Host } from './p-BGFP3hxa.js';
2
2
  import { s as subscribeToContextChange } from './p-DJMgrCw3.js';
3
+ import { w as whenDefined } from './p-C9-yH6MD.js';
3
4
 
4
5
  const sekiCarouselNavigationCss = ":host{display:flex;align-items:center;justify-content:center;position:absolute;top:50%;transform:translateY(-50%);z-index:10}:host(.carousel-nav--prev){left:0.5rem}:host(.carousel-nav--next){right:0.5rem}.carousel-nav__button{display:flex;align-items:center;justify-content:center;width:var(--seki-carousel-arrow-size, 2.5rem);height:var(--seki-carousel-arrow-size, 2.5rem);padding:0;border:none;border-radius:50%;background:var(--seki-carousel-arrow-bg, var(--seki-background, hsl(0, 0%, 100%)));color:var(--seki-carousel-arrow-color, var(--seki-foreground, hsl(0, 0%, 3.9%)));cursor:pointer;backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);transition:background-color 0.2s ease, opacity 0.2s ease, transform 0.2s ease;box-shadow:0 2px 8px rgba(0, 0, 0, 0.1)}.carousel-nav__button:hover:not(:disabled){background:var(--seki-carousel-arrow-bg-hover, var(--seki-accent, hsl(0, 0%, 96.1%)));transform:scale(1.05)}.carousel-nav__button:focus-visible{outline:2px solid var(--seki-ring, hsl(0, 0%, 3.9%));outline-offset:2px}.carousel-nav__button:disabled{opacity:0.5;cursor:not-allowed;pointer-events:none}.carousel-nav__icon{width:1.25rem;height:1.25rem;flex-shrink:0}@media (max-width: 480px){:host(.carousel-nav--prev){left:0.25rem}:host(.carousel-nav--next){right:0.25rem}.carousel-nav__button{width:2rem;height:2rem}.carousel-nav__icon{width:1rem;height:1rem}}@media (prefers-reduced-motion: reduce){.carousel-nav__button{transition:none}.carousel-nav__button:hover:not(:disabled){transform:none}}";
5
6
 
@@ -19,6 +20,7 @@ const SekiCarouselNext$1 = /*@__PURE__*/ proxyCustomElement(class SekiCarouselNe
19
20
  this.handleClick = async () => {
20
21
  if (this.disabled || !this.parentCarousel)
21
22
  return;
23
+ await whenDefined('seki-carousel');
22
24
  await this.parentCarousel.scrollNext();
23
25
  };
24
26
  }
@@ -41,12 +43,12 @@ const SekiCarouselNext$1 = /*@__PURE__*/ proxyCustomElement(class SekiCarouselNe
41
43
  async subscribeToCarousel() {
42
44
  if (!this.parentCarousel)
43
45
  return;
44
- // Initial state
45
- await this.updateState();
46
- // Re-sync on every carousel context change — including embla's async init
47
- // and reInit, not just user navigation — so the button never freezes at its
48
- // premature mount-time disabled state (#274).
46
+ // Subscribe first so a context change can never be missed, then wait for
47
+ // <seki-carousel> to be *defined* — in the per-tag custom-elements build its
48
+ // @Methods do not exist until then (#314).
49
49
  this.unsubscribe = subscribeToContextChange(this.el, 'seki-carousel', this.handleContextChange).unsubscribe;
50
+ await whenDefined('seki-carousel');
51
+ await this.updateState();
50
52
  }
51
53
  async updateState() {
52
54
  if (!this.parentCarousel)
@@ -55,7 +57,7 @@ const SekiCarouselNext$1 = /*@__PURE__*/ proxyCustomElement(class SekiCarouselNe
55
57
  this.disabled = !context.canScrollNext;
56
58
  }
57
59
  render() {
58
- return (h(Host, { key: 'cda7dd0b081d69e07d6500d8b6830368f5770e3a', class: { 'carousel-nav': true, 'carousel-nav--next': true } }, h("button", { key: 'ab3ddbdf211f90841ceef622701911554cd1c401', type: "button", class: "carousel-nav__button", disabled: this.disabled, "aria-label": "Next slide", onClick: this.handleClick }, h("svg", { key: 'a296c67e267f504ac3d7cecd996130b9b95c8523', class: "carousel-nav__icon", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("polyline", { key: '1fb366e06a5412c87c30c340ed95959f498ea9f3', points: "9 18 15 12 9 6" })))));
60
+ return (h(Host, { key: 'ec0cc2d2aee02283fb71b03ae501f7150adc4fd6', class: { 'carousel-nav': true, 'carousel-nav--next': true } }, h("button", { key: '2716d69d315b40127449d4d7979fec4ad418598d', type: "button", class: "carousel-nav__button", disabled: this.disabled, "aria-label": "Next slide", onClick: this.handleClick }, h("svg", { key: '820491a74df7479bcb96c4da9e4366bee6cce26b', class: "carousel-nav__icon", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("polyline", { key: '4d3220a8f9369961e1af6ede4921b1ae4b433908', points: "9 18 15 12 9 6" })))));
59
61
  }
60
62
  get el() { return this; }
61
63
  static get style() { return sekiCarouselNavigationCss; }
@@ -1,5 +1,6 @@
1
1
  import { p as proxyCustomElement, H, d as syncTheme, h, e as Host } from './p-BGFP3hxa.js';
2
2
  import { s as subscribeToContextChange } from './p-DJMgrCw3.js';
3
+ import { w as whenDefined } from './p-C9-yH6MD.js';
3
4
 
4
5
  const sekiCarouselNavigationCss = ":host{display:flex;align-items:center;justify-content:center;position:absolute;top:50%;transform:translateY(-50%);z-index:10}:host(.carousel-nav--prev){left:0.5rem}:host(.carousel-nav--next){right:0.5rem}.carousel-nav__button{display:flex;align-items:center;justify-content:center;width:var(--seki-carousel-arrow-size, 2.5rem);height:var(--seki-carousel-arrow-size, 2.5rem);padding:0;border:none;border-radius:50%;background:var(--seki-carousel-arrow-bg, var(--seki-background, hsl(0, 0%, 100%)));color:var(--seki-carousel-arrow-color, var(--seki-foreground, hsl(0, 0%, 3.9%)));cursor:pointer;backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);transition:background-color 0.2s ease, opacity 0.2s ease, transform 0.2s ease;box-shadow:0 2px 8px rgba(0, 0, 0, 0.1)}.carousel-nav__button:hover:not(:disabled){background:var(--seki-carousel-arrow-bg-hover, var(--seki-accent, hsl(0, 0%, 96.1%)));transform:scale(1.05)}.carousel-nav__button:focus-visible{outline:2px solid var(--seki-ring, hsl(0, 0%, 3.9%));outline-offset:2px}.carousel-nav__button:disabled{opacity:0.5;cursor:not-allowed;pointer-events:none}.carousel-nav__icon{width:1.25rem;height:1.25rem;flex-shrink:0}@media (max-width: 480px){:host(.carousel-nav--prev){left:0.25rem}:host(.carousel-nav--next){right:0.25rem}.carousel-nav__button{width:2rem;height:2rem}.carousel-nav__icon{width:1rem;height:1rem}}@media (prefers-reduced-motion: reduce){.carousel-nav__button{transition:none}.carousel-nav__button:hover:not(:disabled){transform:none}}";
5
6
 
@@ -19,6 +20,7 @@ const SekiCarouselPrevious$1 = /*@__PURE__*/ proxyCustomElement(class SekiCarous
19
20
  this.handleClick = async () => {
20
21
  if (this.disabled || !this.parentCarousel)
21
22
  return;
23
+ await whenDefined('seki-carousel');
22
24
  await this.parentCarousel.scrollPrev();
23
25
  };
24
26
  }
@@ -41,12 +43,12 @@ const SekiCarouselPrevious$1 = /*@__PURE__*/ proxyCustomElement(class SekiCarous
41
43
  async subscribeToCarousel() {
42
44
  if (!this.parentCarousel)
43
45
  return;
44
- // Initial state
45
- await this.updateState();
46
- // Re-sync on every carousel context change — including embla's async init
47
- // and reInit, not just user navigation — so the button never freezes at its
48
- // premature mount-time disabled state (#274).
46
+ // Subscribe first so a context change can never be missed, then wait for
47
+ // <seki-carousel> to be *defined* — in the per-tag custom-elements build its
48
+ // @Methods do not exist until then (#314).
49
49
  this.unsubscribe = subscribeToContextChange(this.el, 'seki-carousel', this.handleContextChange).unsubscribe;
50
+ await whenDefined('seki-carousel');
51
+ await this.updateState();
50
52
  }
51
53
  async updateState() {
52
54
  if (!this.parentCarousel)
@@ -55,7 +57,7 @@ const SekiCarouselPrevious$1 = /*@__PURE__*/ proxyCustomElement(class SekiCarous
55
57
  this.disabled = !context.canScrollPrev;
56
58
  }
57
59
  render() {
58
- return (h(Host, { key: '90cf829ea5c684141c0014b3b1388aabe15f3852', class: { 'carousel-nav': true, 'carousel-nav--prev': true } }, h("button", { key: '80dcc7bf4cb81588e1cc2f570165af98c7263295', type: "button", class: "carousel-nav__button", disabled: this.disabled, "aria-label": "Previous slide", onClick: this.handleClick }, h("svg", { key: '0dd255a633d1fc835a9fbbfcefa967373fc8975c', class: "carousel-nav__icon", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("polyline", { key: '6e1b90ac947f0949bc4a2f34e1b7972ddde631bd', points: "15 18 9 12 15 6" })))));
60
+ return (h(Host, { key: '8ab6f4c404f5cf04e7256c3e4d364a8377121280', class: { 'carousel-nav': true, 'carousel-nav--prev': true } }, h("button", { key: '9048cad871a4f793b3cc3ec1ba45543c9b137652', type: "button", class: "carousel-nav__button", disabled: this.disabled, "aria-label": "Previous slide", onClick: this.handleClick }, h("svg", { key: '14c6000381fbb99e71ce69ae5627d82d7ec8c8ee', class: "carousel-nav__icon", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("polyline", { key: '7d65b0ee40aeb412642ce27e2c0e46e90bd5d985', points: "15 18 9 12 15 6" })))));
59
61
  }
60
62
  get el() { return this; }
61
63
  static get style() { return sekiCarouselNavigationCss; }