@editora/ui-core 0.1.10 → 0.1.12

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.
@@ -1,7 +1,7 @@
1
1
  import { E as b } from "./ElementBase-909688f3.mjs";
2
- import { c as g } from "./portal-1cf392ca.mjs";
3
- import { c as h } from "./dismissable-layer-9c7e6b58.mjs";
4
- import { a as f } from "./positioner-fbd61bf1.mjs";
2
+ import { c as f } from "./portal-1cf392ca.mjs";
3
+ import { c as g } from "./dismissable-layer-9c7e6b58.mjs";
4
+ import { a as h } from "./positioner-fbd61bf1.mjs";
5
5
  import "./listbox-308789a0.mjs";
6
6
  import "./collection-a1aac0c6.mjs";
7
7
  import "./collection.esm.js";
@@ -24,11 +24,17 @@ const m = 160, x = `
24
24
  --ui-split-button-menu-separator: color-mix(in srgb, var(--ui-split-button-menu-color) 10%, transparent);
25
25
  --ui-split-button-menu-muted: color-mix(in srgb, var(--ui-split-button-menu-color) 58%, transparent);
26
26
  --ui-split-button-menu-danger: var(--ui-color-danger, #dc2626);
27
- --ui-split-button-menu-list-gap: 0px;
27
+ --ui-split-button-menu-option-border: transparent;
28
+ --ui-split-button-menu-option-border-strong: color-mix(in srgb, var(--ui-split-button-bg) 24%, transparent);
29
+ --ui-split-button-menu-option-shadow: none;
30
+ --ui-split-button-menu-affordance-bg: transparent;
31
+ --ui-split-button-menu-affordance-border: color-mix(in srgb, var(--ui-split-button-menu-color) 24%, transparent);
32
+ --ui-split-button-menu-affordance-size: 18px;
33
+ --ui-split-button-menu-list-gap: 2px;
28
34
  --ui-split-button-menu-list-padding-top: 2px;
29
- --ui-split-button-menu-item-min-height: 42px;
35
+ --ui-split-button-menu-item-min-height: 44px;
30
36
  --ui-split-button-menu-item-radius: 10px;
31
- --ui-split-button-menu-item-padding: 10px 12px;
37
+ --ui-split-button-menu-item-padding: 10px 10px;
32
38
  --ui-split-button-focus: var(--ui-color-focus-ring, #2563eb);
33
39
  display: inline-flex;
34
40
  position: relative;
@@ -122,6 +128,7 @@ const m = 160, x = `
122
128
  --ui-split-button-menu-shadow: 0 12px 28px rgba(15, 23, 42, 0.08);
123
129
  --ui-split-button-menu-accent: #eef4ff;
124
130
  --ui-split-button-menu-accent-strong: #e0ecff;
131
+ --ui-split-button-menu-option-border: transparent;
125
132
  }
126
133
 
127
134
  :host([variant="contrast"]) {
@@ -165,12 +172,12 @@ const m = 160, x = `
165
172
  .menu {
166
173
  position: absolute;
167
174
  display: grid;
168
- gap: 6px;
169
- min-width: 220px;
175
+ gap: 8px;
176
+ min-width: 240px;
170
177
  max-width: min(360px, calc(100vw - 16px));
171
178
  max-height: min(420px, calc(100vh - 16px));
172
179
  overflow: auto;
173
- padding: 10px 8px 8px;
180
+ padding: 8px;
174
181
  border: var(--ui-split-button-menu-border);
175
182
  border-radius: calc(var(--ui-split-button-menu-radius) + 2px);
176
183
  background: var(--ui-split-button-menu-bg);
@@ -206,9 +213,8 @@ const m = 160, x = `
206
213
  content: "";
207
214
  position: absolute;
208
215
  inset: 0 0 auto 0;
209
- block-size: 3px;
210
- background: linear-gradient(90deg, var(--ui-split-button-bg), color-mix(in srgb, var(--ui-split-button-bg) 68%, white));
211
- opacity: 0.96;
216
+ block-size: 1px;
217
+ background: color-mix(in srgb, var(--ui-split-button-menu-color) 10%, transparent);
212
218
  pointer-events: none;
213
219
  }
214
220
 
@@ -216,26 +222,30 @@ const m = 160, x = `
216
222
  display: grid;
217
223
  gap: var(--ui-split-button-menu-list-gap);
218
224
  padding: var(--ui-split-button-menu-list-padding-top) 0 0;
225
+ position: relative;
226
+ z-index: 1;
219
227
  }
220
228
 
221
229
  .menu-header {
222
230
  display: grid;
223
- gap: 3px;
224
- padding: 2px 8px 6px;
231
+ gap: 4px;
232
+ padding: 4px 6px 2px;
233
+ position: relative;
234
+ z-index: 1;
225
235
  }
226
236
 
227
237
  .menu-heading {
228
238
  margin: 0;
229
239
  min-inline-size: 0;
230
240
  font: 700 13px/1.25 "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
231
- letter-spacing: 0.01em;
241
+ letter-spacing: 0.015em;
232
242
  color: var(--ui-split-button-menu-color);
233
243
  }
234
244
 
235
245
  .menu-description {
236
246
  margin: 0;
237
247
  min-inline-size: 0;
238
- font: 500 12px/1.45 "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
248
+ font: 500 12px/1.5 "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
239
249
  letter-spacing: 0.01em;
240
250
  color: var(--ui-split-button-menu-muted);
241
251
  }
@@ -245,15 +255,15 @@ const m = 160, x = `
245
255
  appearance: none;
246
256
  -webkit-appearance: none;
247
257
  display: grid;
248
- grid-template-columns: minmax(0, 1fr) auto;
258
+ grid-template-columns: auto minmax(0, 1fr) auto;
249
259
  inline-size: 100%;
250
260
  gap: 12px;
251
- align-items: center;
261
+ align-items: start;
252
262
  position: relative;
253
263
  min-height: var(--ui-split-button-menu-item-min-height);
254
264
  margin: 0;
255
265
  padding: var(--ui-split-button-menu-item-padding);
256
- border: 0;
266
+ border: 1px solid var(--ui-split-button-menu-option-border);
257
267
  border-radius: var(--ui-split-button-menu-item-radius);
258
268
  background: transparent;
259
269
  color: inherit;
@@ -264,7 +274,14 @@ const m = 160, x = `
264
274
  letter-spacing: 0.01em;
265
275
  cursor: pointer;
266
276
  outline: none;
267
- transition: background-color 140ms ease, color 140ms ease, transform 140ms ease, box-shadow 140ms ease;
277
+ overflow: hidden;
278
+ isolation: isolate;
279
+ transition:
280
+ background-color 140ms ease,
281
+ border-color 140ms ease,
282
+ color 140ms ease,
283
+ transform 140ms ease,
284
+ box-shadow 140ms ease;
268
285
  }
269
286
 
270
287
  .menu [slot="menuitem"] + [slot="menuitem"],
@@ -272,26 +289,49 @@ const m = 160, x = `
272
289
  box-shadow: inset 0 1px 0 var(--ui-split-button-menu-separator);
273
290
  }
274
291
 
275
- .menu [slot="menuitem"]::before,
276
- .menu [data-menu-item]::before {
292
+ .menu [data-menu-affordance] {
293
+ inline-size: var(--ui-split-button-menu-affordance-size);
294
+ block-size: var(--ui-split-button-menu-affordance-size);
295
+ display: inline-grid;
296
+ place-items: center;
297
+ border-radius: 999px;
298
+ background: var(--ui-split-button-menu-affordance-bg);
299
+ border: 1.5px solid var(--ui-split-button-menu-affordance-border);
300
+ color: color-mix(in srgb, var(--ui-split-button-bg) 82%, var(--ui-split-button-menu-color));
301
+ transition:
302
+ background-color 140ms ease,
303
+ border-color 140ms ease,
304
+ color 140ms ease,
305
+ transform 140ms ease;
306
+ }
307
+
308
+ .menu [data-menu-affordance]::before {
277
309
  content: "";
278
- position: absolute;
279
- inset-inline-start: 0;
280
- inset-block: 8px;
281
- inline-size: 3px;
310
+ inline-size: 7px;
311
+ block-size: 7px;
282
312
  border-radius: 999px;
283
- background: transparent;
284
- transition: background-color 140ms ease;
313
+ background: currentColor;
314
+ opacity: 0;
315
+ transition: transform 140ms ease, opacity 140ms ease;
285
316
  }
286
317
 
287
- .menu [slot="menuitem"] > :first-child,
288
- .menu [data-menu-item] > :first-child,
318
+ .menu [slot="menuitem"] > :nth-child(2),
319
+ .menu [data-menu-item] > :nth-child(2),
289
320
  .menu [data-menu-label] {
290
321
  display: grid;
291
- gap: 2px;
322
+ gap: 3px;
292
323
  min-inline-size: 0;
293
324
  }
294
325
 
326
+ .menu [data-menu-text] {
327
+ padding-block-start: 1px;
328
+ }
329
+
330
+ .menu [slot="menuitem"][data-has-description="false"],
331
+ .menu [data-menu-item][data-has-description="false"] {
332
+ align-items: center;
333
+ }
334
+
295
335
  .menu [data-menu-label] {
296
336
  min-inline-size: 0;
297
337
  overflow: hidden;
@@ -301,25 +341,26 @@ const m = 160, x = `
301
341
  }
302
342
 
303
343
  .menu [data-menu-description] {
344
+ display: -webkit-box;
304
345
  min-inline-size: 0;
305
346
  overflow: hidden;
306
- text-overflow: ellipsis;
307
- white-space: nowrap;
308
- font: 500 12px/1.35 "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
347
+ -webkit-box-orient: vertical;
348
+ -webkit-line-clamp: 2;
349
+ white-space: normal;
350
+ font: 500 12px/1.45 "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
309
351
  color: var(--ui-split-button-menu-muted);
310
352
  }
311
353
 
312
- .menu [slot="menuitem"] > :last-child,
313
- .menu [data-menu-item] > :last-child,
314
354
  .menu [data-menu-shortcut] {
315
355
  justify-self: end;
356
+ align-self: center;
357
+ white-space: nowrap;
316
358
  font: 600 12px/1 "IBM Plex Mono", "SFMono-Regular", "SF Mono", Consolas, monospace;
317
359
  letter-spacing: 0.03em;
318
360
  color: var(--ui-split-button-menu-shortcut);
319
- padding: 5px 7px;
320
- border-radius: 8px;
321
- background: color-mix(in srgb, var(--ui-split-button-menu-color) 5%, transparent);
322
- box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ui-split-button-menu-color) 10%, transparent);
361
+ padding: 0;
362
+ background: none;
363
+ box-shadow: none;
323
364
  }
324
365
 
325
366
  .menu [slot="menuitem"][data-tone="danger"],
@@ -332,6 +373,11 @@ const m = 160, x = `
332
373
  color: color-mix(in srgb, var(--ui-split-button-menu-danger) 68%, transparent);
333
374
  }
334
375
 
376
+ .menu [slot="menuitem"][data-tone="danger"] [data-menu-affordance],
377
+ .menu [data-menu-item][data-tone="danger"] [data-menu-affordance] {
378
+ color: color-mix(in srgb, var(--ui-split-button-menu-danger) 88%, var(--ui-split-button-menu-color));
379
+ }
380
+
335
381
  .menu [slot="menuitem"][data-active="true"],
336
382
  .menu [data-menu-item][data-active="true"],
337
383
  .menu [slot="menuitem"]:hover,
@@ -339,7 +385,8 @@ const m = 160, x = `
339
385
  .menu [slot="menuitem"]:focus-visible,
340
386
  .menu [data-menu-item]:focus-visible {
341
387
  background: var(--ui-split-button-menu-accent);
342
- box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ui-split-button-bg) 16%, transparent);
388
+ border-color: var(--ui-split-button-menu-option-border-strong);
389
+ box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ui-split-button-bg) 10%, transparent);
343
390
  }
344
391
 
345
392
  .menu [slot="menuitem"][data-active="true"],
@@ -347,22 +394,46 @@ const m = 160, x = `
347
394
  background: var(--ui-split-button-menu-accent-strong);
348
395
  }
349
396
 
350
- .menu [slot="menuitem"][data-active="true"]::before,
351
- .menu [data-menu-item][data-active="true"]::before,
352
- .menu [slot="menuitem"]:hover::before,
353
- .menu [data-menu-item]:hover::before,
354
- .menu [slot="menuitem"]:focus-visible::before,
355
- .menu [data-menu-item]:focus-visible::before {
356
- background: var(--ui-split-button-bg);
397
+ .menu [slot="menuitem"][data-active="true"] [data-menu-affordance],
398
+ .menu [data-menu-item][data-active="true"] [data-menu-affordance],
399
+ .menu [slot="menuitem"]:hover [data-menu-affordance],
400
+ .menu [data-menu-item]:hover [data-menu-affordance],
401
+ .menu [slot="menuitem"]:focus-visible [data-menu-affordance],
402
+ .menu [data-menu-item]:focus-visible [data-menu-affordance] {
403
+ background: color-mix(in srgb, var(--ui-split-button-bg) 10%, transparent);
404
+ border-color: color-mix(in srgb, var(--ui-split-button-bg) 28%, transparent);
405
+ color: color-mix(in srgb, var(--ui-split-button-bg) 88%, var(--ui-split-button-menu-color));
406
+ }
407
+
408
+ .menu [slot="menuitem"][data-active="true"] [data-menu-affordance]::before,
409
+ .menu [data-menu-item][data-active="true"] [data-menu-affordance]::before,
410
+ .menu [slot="menuitem"]:hover [data-menu-affordance]::before,
411
+ .menu [data-menu-item]:hover [data-menu-affordance]::before,
412
+ .menu [slot="menuitem"]:focus-visible [data-menu-affordance]::before,
413
+ .menu [data-menu-item]:focus-visible [data-menu-affordance]::before {
414
+ opacity: 1;
415
+ transform: scale(1);
357
416
  }
358
417
 
359
- .menu [slot="menuitem"][data-tone="danger"][data-active="true"]::before,
360
- .menu [data-menu-item][data-tone="danger"][data-active="true"]::before,
361
- .menu [slot="menuitem"][data-tone="danger"]:hover::before,
362
- .menu [data-menu-item][data-tone="danger"]:hover::before,
363
- .menu [slot="menuitem"][data-tone="danger"]:focus-visible::before,
364
- .menu [data-menu-item][data-tone="danger"]:focus-visible::before {
365
- background: var(--ui-split-button-menu-danger);
418
+ .menu [slot="menuitem"][data-tone="danger"][data-active="true"],
419
+ .menu [data-menu-item][data-tone="danger"][data-active="true"],
420
+ .menu [slot="menuitem"][data-tone="danger"]:hover,
421
+ .menu [data-menu-item][data-tone="danger"]:hover,
422
+ .menu [slot="menuitem"][data-tone="danger"]:focus-visible,
423
+ .menu [data-menu-item][data-tone="danger"]:focus-visible {
424
+ border-color: color-mix(in srgb, var(--ui-split-button-menu-danger) 28%, transparent);
425
+ box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ui-split-button-menu-danger) 14%, transparent);
426
+ }
427
+
428
+ .menu [slot="menuitem"][data-tone="danger"][data-active="true"] [data-menu-affordance],
429
+ .menu [data-menu-item][data-tone="danger"][data-active="true"] [data-menu-affordance],
430
+ .menu [slot="menuitem"][data-tone="danger"]:hover [data-menu-affordance],
431
+ .menu [data-menu-item][data-tone="danger"]:hover [data-menu-affordance],
432
+ .menu [slot="menuitem"][data-tone="danger"]:focus-visible [data-menu-affordance],
433
+ .menu [data-menu-item][data-tone="danger"]:focus-visible [data-menu-affordance] {
434
+ background: color-mix(in srgb, var(--ui-split-button-menu-danger) 14%, #ffffff);
435
+ border-color: color-mix(in srgb, var(--ui-split-button-menu-danger) 30%, transparent);
436
+ color: var(--ui-split-button-menu-danger);
366
437
  }
367
438
 
368
439
  .menu [slot="menuitem"][disabled],
@@ -371,22 +442,26 @@ const m = 160, x = `
371
442
  .menu [data-menu-item][aria-disabled="true"] {
372
443
  opacity: 0.56;
373
444
  pointer-events: none;
445
+ transform: none;
446
+ box-shadow: none;
374
447
  }
375
448
 
376
449
  :host([menu-density="compact"]) {
377
- --ui-split-button-menu-list-gap: 0px;
450
+ --ui-split-button-menu-list-gap: 1px;
378
451
  --ui-split-button-menu-list-padding-top: 2px;
379
- --ui-split-button-menu-item-min-height: 40px;
452
+ --ui-split-button-menu-item-min-height: 38px;
380
453
  --ui-split-button-menu-item-radius: 8px;
381
- --ui-split-button-menu-item-padding: 9px 11px;
454
+ --ui-split-button-menu-item-padding: 8px 10px;
455
+ --ui-split-button-menu-affordance-size: 16px;
382
456
  }
383
457
 
384
458
  :host([menu-density="airy"]) {
385
- --ui-split-button-menu-list-gap: 6px;
459
+ --ui-split-button-menu-list-gap: 4px;
386
460
  --ui-split-button-menu-list-padding-top: 6px;
387
461
  --ui-split-button-menu-item-min-height: 50px;
388
462
  --ui-split-button-menu-item-radius: 14px;
389
- --ui-split-button-menu-item-padding: 12px 14px;
463
+ --ui-split-button-menu-item-padding: 12px 12px;
464
+ --ui-split-button-menu-affordance-size: 20px;
390
465
  }
391
466
 
392
467
  :host([menu-shape="flat"]) {
@@ -406,20 +481,24 @@ const m = 160, x = `
406
481
  }
407
482
  }
408
483
  `;
409
- function _(p, t) {
410
- const e = p.cloneNode(!0);
411
- return e.setAttribute("slot", "menuitem"), e.setAttribute("data-menu-item", "true"), e.setAttribute("data-index", String(t)), e.setAttribute("tabindex", "-1"), e.id || (e.id = `ui-split-button-item-${Math.random().toString(36).slice(2, 9)}`), e;
484
+ function _(d, e) {
485
+ const t = d.cloneNode(!0);
486
+ if (t.setAttribute("slot", "menuitem"), t.setAttribute("data-menu-item", "true"), t.setAttribute("data-index", String(e)), t.setAttribute("role", "menuitem"), t.setAttribute("tabindex", "-1"), t.classList.add("menu-option"), t.setAttribute("data-has-description", t.querySelector("[data-menu-description]") ? "true" : "false"), t.setAttribute("data-has-shortcut", t.querySelector("[data-menu-shortcut]") ? "true" : "false"), t.hasAttribute("disabled") && t.setAttribute("aria-disabled", "true"), !t.querySelector("[data-menu-affordance]")) {
487
+ const n = document.createElement("span");
488
+ n.setAttribute("data-menu-affordance", "true"), n.setAttribute("aria-hidden", "true"), t.prepend(n);
489
+ }
490
+ return t.id || (t.id = `ui-split-button-item-${Math.random().toString(36).slice(2, 9)}`), t;
412
491
  }
413
492
  class y extends b {
414
493
  constructor() {
415
- super(), this._portalEl = null, this._portalRoot = null, this._layer = null, this._positioner = null, this._listbox = null, this._triggerButton = null, this._toggleButton = null, this._menuItems = [], this._lastFocused = null, this._closeTimer = null, this._onPrimaryClick = this._onPrimaryClick.bind(this), this._onToggleClick = this._onToggleClick.bind(this), this._onKeyDown = this._onKeyDown.bind(this);
494
+ super(), this._portalEl = null, this._portalRoot = null, this._layer = null, this._positioner = null, this._listbox = null, this._triggerButton = null, this._toggleButton = null, this._menuItems = [], this._lastFocused = null, this._closeTimer = null, this._onPrimaryClick = this._onPrimaryClick.bind(this), this._onToggleClick = this._onToggleClick.bind(this), this._onKeyDown = this._onKeyDown.bind(this), this._onMenuPointerDown = this._onMenuPointerDown.bind(this), this._onMenuPointerMove = this._onMenuPointerMove.bind(this);
416
495
  }
417
496
  static get observedAttributes() {
418
497
  return ["label", "menu-label", "menu-heading", "menu-description", "variant", "density", "menu-density", "menu-shape", "disabled", "open"];
419
498
  }
420
499
  openMenu() {
421
- var t, e;
422
- this.hasAttribute("disabled") || this.hasAttribute("open") && ((t = this._portalEl) == null ? void 0 : t.getAttribute("data-state")) !== "closing" || !this._portalEl && this._collectMenuItems().length === 0 || (this._lastFocused = document.activeElement || this._toggleButton, this._clearCloseTimer(), this._portalEl && (this._setMenuState("opening"), this._portalEl.style.pointerEvents = "auto", (e = this._positioner) == null || e.update(), requestAnimationFrame(() => this._setMenuState("open"))), this.setAttribute("open", ""), queueMicrotask(() => {
500
+ var e, t;
501
+ this.hasAttribute("disabled") || this.hasAttribute("open") && ((e = this._portalEl) == null ? void 0 : e.getAttribute("data-state")) !== "closing" || !this._portalEl && this._collectMenuItems().length === 0 || (this._lastFocused = document.activeElement || this._toggleButton, this._clearCloseTimer(), this._portalEl && (this._setMenuState("opening"), this._portalEl.style.pointerEvents = "auto", (t = this._positioner) == null || t.update(), requestAnimationFrame(() => this._setMenuState("open"))), this.setAttribute("open", ""), queueMicrotask(() => {
423
502
  if (!this._portalEl)
424
503
  this._mountMenu();
425
504
  else
@@ -442,144 +521,155 @@ class y extends b {
442
521
  disconnectedCallback() {
443
522
  this._teardownMenu(!0), super.disconnectedCallback();
444
523
  }
445
- attributeChangedCallback(t, e, i) {
446
- if (e !== i) {
447
- if (t === "open") {
448
- i != null ? this.openMenu() : this._beginCloseMenu();
524
+ attributeChangedCallback(e, t, n) {
525
+ if (t !== n) {
526
+ if (e === "open") {
527
+ n != null ? this.openMenu() : this._beginCloseMenu();
449
528
  return;
450
529
  }
451
530
  this.isConnected && this.requestRender();
452
531
  }
453
532
  }
454
533
  render() {
455
- var i, n, o;
456
- const t = this.getAttribute("label") || "Run action", e = this.getAttribute("menu-label") || "Open action menu";
534
+ var n, i, o;
535
+ const e = this.getAttribute("label") || "Run action", t = this.getAttribute("menu-label") || "Open action menu";
457
536
  this.setContent(`
458
537
  <style>${x}</style>
459
538
  <div class="group" part="group">
460
- <button class="button" part="button" type="button">${t}</button>
461
- <button class="toggle" part="toggle" type="button" aria-label="${e}" aria-haspopup="menu" aria-expanded="${this.hasAttribute("open") ? "true" : "false"}">
539
+ <button class="button" part="button" type="button">${e}</button>
540
+ <button class="toggle" part="toggle" type="button" aria-label="${t}" aria-haspopup="menu" aria-expanded="${this.hasAttribute("open") ? "true" : "false"}">
462
541
  <svg viewBox="0 0 20 20" aria-hidden="true" focusable="false"><path d="m5 8 5 5 5-5" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg>
463
542
  </button>
464
543
  </div>
465
544
  <div class="slot-source"><slot name="menuitem"></slot></div>
466
- `), this._triggerButton = this.root.querySelector(".button"), this._toggleButton = this.root.querySelector(".toggle"), this._syncToggleState(), (i = this._triggerButton) == null || i.addEventListener("click", this._onPrimaryClick), (n = this._toggleButton) == null || n.addEventListener("click", this._onToggleClick), (o = this._toggleButton) == null || o.addEventListener("keydown", this._onKeyDown);
545
+ `), this._triggerButton = this.root.querySelector(".button"), this._toggleButton = this.root.querySelector(".toggle"), this._syncToggleState(), (n = this._triggerButton) == null || n.addEventListener("click", this._onPrimaryClick), (i = this._toggleButton) == null || i.addEventListener("click", this._onToggleClick), (o = this._toggleButton) == null || o.addEventListener("keydown", this._onKeyDown);
467
546
  }
468
- _onPrimaryClick(t) {
469
- this.hasAttribute("disabled") || this.dispatchEvent(new CustomEvent("primary-action", { detail: { originalEvent: t }, bubbles: !0, composed: !0 }));
547
+ _onPrimaryClick(e) {
548
+ this.hasAttribute("disabled") || this.dispatchEvent(new CustomEvent("primary-action", { detail: { originalEvent: e }, bubbles: !0, composed: !0 }));
470
549
  }
471
550
  _onToggleClick() {
472
551
  this.toggleMenu();
473
552
  }
474
- _onKeyDown(t) {
475
- (t.key === "ArrowDown" || t.key === "Enter" || t.key === " ") && (t.preventDefault(), this.openMenu());
553
+ _onKeyDown(e) {
554
+ (e.key === "ArrowDown" || e.key === "Enter" || e.key === " ") && (e.preventDefault(), this.openMenu());
476
555
  }
477
556
  _mountMenu() {
478
- var d;
557
+ var c;
479
558
  if (this._portalEl)
480
559
  return;
481
- const t = g();
482
- if (!t)
560
+ const e = f();
561
+ if (!e)
483
562
  return;
484
- this._portalRoot = t, this._portalRoot.classList.add("ui-split-button-portal");
485
- const e = document.createElement("div");
486
- e.className = "menu", e.setAttribute("role", "menu"), e.setAttribute("data-state", "opening"), e.tabIndex = -1, e.style.pointerEvents = "auto";
487
- const i = document.createElement("style");
488
- i.textContent = v;
489
- const n = this.getAttribute("menu-heading") || "", o = this.getAttribute("menu-description") || "", r = n || o ? (() => {
490
- const s = document.createElement("div");
491
- if (s.className = "menu-header", n) {
492
- const a = document.createElement("p");
493
- a.className = "menu-heading", a.textContent = n, s.appendChild(a);
563
+ this._portalRoot = e, this._portalRoot.classList.add("ui-split-button-portal");
564
+ const t = document.createElement("div");
565
+ t.className = "menu", t.setAttribute("role", "menu"), t.setAttribute("data-state", "opening"), t.tabIndex = -1, t.style.pointerEvents = "auto";
566
+ const n = document.createElement("style");
567
+ n.textContent = v;
568
+ const i = this.getAttribute("menu-heading") || "", o = this.getAttribute("menu-description") || "", r = i || o ? (() => {
569
+ const a = document.createElement("div");
570
+ if (a.className = "menu-header", i) {
571
+ const u = document.createElement("p");
572
+ u.className = "menu-heading", u.textContent = i, a.appendChild(u);
494
573
  }
495
574
  if (o) {
496
- const a = document.createElement("p");
497
- a.className = "menu-description", a.textContent = o, s.appendChild(a);
575
+ const u = document.createElement("p");
576
+ u.className = "menu-description", u.textContent = o, a.appendChild(u);
498
577
  }
499
- return s;
500
- })() : null, u = document.createElement("ui-listbox");
501
- if (u.setAttribute("item-selector", '[slot="menuitem"]'), u.setAttribute("item-role", "menuitem"), u.setAttribute("active-attribute", "data-active"), this._menuItems = this._collectMenuItems(), this._menuItems.length === 0) {
578
+ return a;
579
+ })() : null, s = document.createElement("ui-listbox");
580
+ if (s.setAttribute("item-selector", '[slot="menuitem"]'), s.setAttribute("item-role", "menuitem"), s.setAttribute("active-attribute", "data-active"), this._menuItems = this._collectMenuItems(), this._menuItems.length === 0) {
502
581
  this.removeAttribute("open");
503
582
  return;
504
583
  }
505
- const l = (d = this.root.querySelector(".group")) == null ? void 0 : d.getBoundingClientRect();
506
- l && Number.isFinite(l.width) && l.width > 0 && (e.style.minWidth = `${Math.max(236, Math.round(l.width))}px`), this._menuItems.forEach((s) => u.appendChild(s)), u.refresh(), e.append(i), r && e.appendChild(r), e.appendChild(u), this._portalRoot.appendChild(e), this._portalEl = e, this._listbox = u, this._positioner = f({
507
- floating: e,
508
- anchor: this._toggleButton || this,
584
+ const l = (c = this.root.querySelector(".group")) == null ? void 0 : c.getBoundingClientRect();
585
+ l && Number.isFinite(l.width) && l.width > 0 && (t.style.minWidth = `${Math.max(260, Math.round(l.width))}px`), this._menuItems.forEach((a) => s.appendChild(a)), s.refresh(), t.append(n), r && t.appendChild(r), t.appendChild(s), this._portalRoot.appendChild(t), this._portalEl = t, this._listbox = s, this._positioner = h({
586
+ floating: t,
587
+ anchor: this.root.querySelector(".group") || this._toggleButton || this,
509
588
  placement: "bottom-start",
510
589
  offset: 6,
511
590
  fitViewport: !0
512
- }), this._layer = h({
513
- node: e,
591
+ }), this._layer = g({
592
+ node: t,
514
593
  trigger: this._toggleButton,
515
594
  closeOnEscape: !0,
516
595
  closeOnPointerOutside: !0,
517
596
  onDismiss: () => this.closeMenu()
518
- }), u.addEventListener("click", (s) => this._onMenuClick(s)), u.addEventListener("keydown", (s) => this._onMenuKeyDown(s));
519
- const c = this._listbox.focusBoundary("first", { focus: !1, scroll: !1 });
520
- c && this._listbox.setActiveItem(c, { focus: !1, scroll: !1 }), this._syncToggleState(), requestAnimationFrame(() => this._setMenuState("open")), queueMicrotask(() => {
597
+ }), s.addEventListener("click", (a) => this._onMenuClick(a)), s.addEventListener("pointerdown", this._onMenuPointerDown), s.addEventListener("pointermove", this._onMenuPointerMove, { passive: !0 }), s.addEventListener("keydown", (a) => this._onMenuKeyDown(a));
598
+ const p = this._listbox.focusBoundary("first", { focus: !1, scroll: !1 });
599
+ p && this._listbox.setActiveItem(p, { focus: !1, scroll: !1 }), this._syncToggleState(), requestAnimationFrame(() => this._setMenuState("open")), queueMicrotask(() => {
521
600
  try {
522
- e.focus({ preventScroll: !0 });
601
+ t.focus({ preventScroll: !0 });
523
602
  } catch {
524
- e.focus();
603
+ t.focus();
525
604
  }
526
605
  });
527
606
  }
528
607
  _collectMenuItems() {
529
- const t = this.root.querySelector('slot[name="menuitem"]');
530
- return (t ? t.assignedElements({ flatten: !0 }) : []).filter((i) => i.getAttribute("slot") === "menuitem").map((i, n) => _(i, n));
531
- }
532
- _onMenuClick(t) {
533
- var n, o;
534
- const e = t.composedPath(), i = this._menuItems.find((r) => e.includes(r));
535
- if (!i) {
536
- const r = (o = (n = t.target) == null ? void 0 : n.closest) == null ? void 0 : o.call(n, "[data-menu-item]");
608
+ const e = this.root.querySelector('slot[name="menuitem"]');
609
+ return (e ? e.assignedElements({ flatten: !0 }) : []).filter((n) => n.getAttribute("slot") === "menuitem").map((n, i) => _(n, i));
610
+ }
611
+ _onMenuClick(e) {
612
+ var i, o;
613
+ const t = e.composedPath(), n = this._menuItems.find((r) => t.includes(r));
614
+ if (!n) {
615
+ const r = (o = (i = e.target) == null ? void 0 : i.closest) == null ? void 0 : o.call(i, "[data-menu-item]");
537
616
  r && this._selectMenuItem(r);
538
617
  return;
539
618
  }
540
- this._selectMenuItem(i);
619
+ this._selectMenuItem(n);
620
+ }
621
+ _onMenuPointerDown(e) {
622
+ var n, i;
623
+ (i = (n = e.target) == null ? void 0 : n.closest) != null && i.call(n, "[data-menu-item]") && e.preventDefault();
541
624
  }
542
- _onMenuKeyDown(t) {
625
+ _onMenuPointerMove(e) {
626
+ var n, i;
627
+ if (!this._listbox)
628
+ return;
629
+ const t = (i = (n = e.target) == null ? void 0 : n.closest) == null ? void 0 : i.call(n, "[data-menu-item]");
630
+ !t || t.hasAttribute("disabled") || t.getAttribute("aria-disabled") === "true" || this._listbox.getActiveItem() !== t && this._listbox.setActiveItem(t, { focus: !1, scroll: !1 });
631
+ }
632
+ _onMenuKeyDown(e) {
543
633
  if (this._listbox) {
544
- if (t.key === "Escape" || t.key === "Tab") {
545
- t.preventDefault(), this.closeMenu();
634
+ if (e.key === "Escape" || e.key === "Tab") {
635
+ e.preventDefault(), this.closeMenu();
546
636
  return;
547
637
  }
548
- if (t.key === "ArrowDown") {
549
- t.preventDefault(), this._listbox.move(1, { focus: !1, scroll: !0 });
638
+ if (e.key === "ArrowDown") {
639
+ e.preventDefault(), this._listbox.move(1, { focus: !1, scroll: !0 });
550
640
  return;
551
641
  }
552
- if (t.key === "ArrowUp") {
553
- t.preventDefault(), this._listbox.move(-1, { focus: !1, scroll: !0 });
642
+ if (e.key === "ArrowUp") {
643
+ e.preventDefault(), this._listbox.move(-1, { focus: !1, scroll: !0 });
554
644
  return;
555
645
  }
556
- if (t.key === "Home") {
557
- t.preventDefault(), this._listbox.focusBoundary("first", { focus: !1, scroll: !0 });
646
+ if (e.key === "Home") {
647
+ e.preventDefault(), this._listbox.focusBoundary("first", { focus: !1, scroll: !0 });
558
648
  return;
559
649
  }
560
- if (t.key === "End") {
561
- t.preventDefault(), this._listbox.focusBoundary("last", { focus: !1, scroll: !0 });
650
+ if (e.key === "End") {
651
+ e.preventDefault(), this._listbox.focusBoundary("last", { focus: !1, scroll: !0 });
562
652
  return;
563
653
  }
564
- if (t.key === "Enter" || t.key === " ") {
565
- t.preventDefault();
566
- const e = this._listbox.getActiveItem();
567
- e && this._selectMenuItem(e);
654
+ if (e.key === "Enter" || e.key === " ") {
655
+ e.preventDefault();
656
+ const t = this._listbox.getActiveItem();
657
+ t && this._selectMenuItem(t);
568
658
  }
569
659
  }
570
660
  }
571
661
  _syncToggleState() {
572
- var t;
573
- (t = this._toggleButton) == null || t.setAttribute("aria-expanded", this.hasAttribute("open") ? "true" : "false");
662
+ var e;
663
+ (e = this._toggleButton) == null || e.setAttribute("aria-expanded", this.hasAttribute("open") ? "true" : "false");
574
664
  }
575
- _selectMenuItem(t) {
576
- const e = Number(t.getAttribute("data-index") || -1);
665
+ _selectMenuItem(e) {
666
+ const t = Number(e.getAttribute("data-index") || -1);
577
667
  this.dispatchEvent(
578
668
  new CustomEvent("select", {
579
669
  detail: {
580
- index: e,
581
- value: t.getAttribute("data-value") || void 0,
582
- label: t.getAttribute("data-label") || (t.textContent || "").trim()
670
+ index: t,
671
+ value: e.getAttribute("data-value") || void 0,
672
+ label: e.getAttribute("data-label") || (e.textContent || "").trim()
583
673
  },
584
674
  bubbles: !0,
585
675
  composed: !0
@@ -591,16 +681,16 @@ class y extends b {
591
681
  this._closeTimer = null, this._teardownMenu(!0);
592
682
  }, m));
593
683
  }
594
- _setMenuState(t) {
595
- var e;
596
- (e = this._portalEl) == null || e.setAttribute("data-state", t);
684
+ _setMenuState(e) {
685
+ var t;
686
+ (t = this._portalEl) == null || t.setAttribute("data-state", e);
597
687
  }
598
688
  _clearCloseTimer() {
599
689
  this._closeTimer != null && (window.clearTimeout(this._closeTimer), this._closeTimer = null);
600
690
  }
601
- _teardownMenu(t = !1) {
602
- var e, i, n;
603
- if (this._clearCloseTimer(), (e = this._layer) == null || e.destroy(), this._layer = null, (i = this._positioner) == null || i.destroy(), this._positioner = null, this._listbox = null, (n = this._portalEl) != null && n.parentElement && this._portalEl.parentElement.removeChild(this._portalEl), this._portalEl = null, this._portalRoot = null, this._syncToggleState(), t) {
691
+ _teardownMenu(e = !1) {
692
+ var t, n, i;
693
+ if (this._clearCloseTimer(), (t = this._layer) == null || t.destroy(), this._layer = null, (n = this._positioner) == null || n.destroy(), this._positioner = null, this._listbox = null, (i = this._portalEl) != null && i.parentElement && this._portalEl.parentElement.removeChild(this._portalEl), this._portalEl = null, this._portalRoot = null, this._syncToggleState(), e) {
604
694
  const o = this._toggleButton || this._lastFocused;
605
695
  o && o.isConnected && queueMicrotask(() => {
606
696
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@editora/ui-core",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "description": "Framework-agnostic Web Components and primitives for the Editora UI ecosystem",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.esm.js",