@kerfjs/ui 5.0.0-beta.63 → 5.0.0-beta.65

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 (77) hide show
  1. package/ai/component-catalog.json +28 -12
  2. package/ai/component-composition.json +21 -3
  3. package/ai/components/content-item.md +4 -1
  4. package/ai/components/list.md +4 -2
  5. package/ai/components/token-search-field.md +3 -0
  6. package/ai/components/workbench.md +1 -0
  7. package/ai/public-api-signatures-v1.md +24 -11
  8. package/ai/webawesome-jsx-signatures-v1.md +1 -1
  9. package/dist/catalog.d.ts +1 -1
  10. package/dist/catalog.js +3 -3
  11. package/dist/catalog.js.map +1 -1
  12. package/dist/{chunk-UCKKT6KO.js → chunk-2EKHENQK.js} +7 -1
  13. package/dist/chunk-2EKHENQK.js.map +1 -0
  14. package/dist/{chunk-RTJNJTG3.js → chunk-5SYE4CCT.js} +42 -5
  15. package/dist/chunk-5SYE4CCT.js.map +1 -0
  16. package/dist/{chunk-IA4D5XNT.js → chunk-FJSZYEBM.js} +2 -2
  17. package/dist/{chunk-IA4D5XNT.js.map → chunk-FJSZYEBM.js.map} +1 -1
  18. package/dist/{chunk-ZRWXFDDS.js → chunk-J3KGJ6P6.js} +1 -1
  19. package/dist/{chunk-ZRWXFDDS.js.map → chunk-J3KGJ6P6.js.map} +1 -1
  20. package/dist/{chunk-7AKGPBCC.js → chunk-NCSWXG7G.js} +8 -4
  21. package/dist/chunk-NCSWXG7G.js.map +1 -0
  22. package/dist/{chunk-R75GGNWY.js → chunk-P4UXSYIJ.js} +58 -8
  23. package/dist/chunk-P4UXSYIJ.js.map +1 -0
  24. package/dist/{chunk-KFYANKJI.js → chunk-PWQAVNON.js} +3 -3
  25. package/dist/{chunk-KFYANKJI.js.map → chunk-PWQAVNON.js.map} +1 -1
  26. package/dist/{chunk-OBAFAH5B.js → chunk-TJK44RQC.js} +33 -8
  27. package/dist/chunk-TJK44RQC.js.map +1 -0
  28. package/dist/{chunk-NAPE7WUS.js → chunk-W2AC6Q2A.js} +9 -1
  29. package/dist/chunk-W2AC6Q2A.js.map +1 -0
  30. package/dist/collapsible-panel.js +2 -2
  31. package/dist/content-item.d.ts +7 -3
  32. package/dist/content-item.js +1 -1
  33. package/dist/grid.d.ts +5 -1
  34. package/dist/grid.js +1 -1
  35. package/dist/index.d.ts +1 -1
  36. package/dist/index.js +6 -6
  37. package/dist/list.d.ts +5 -1
  38. package/dist/list.js +1 -1
  39. package/dist/popup-menu-register.js +181 -5
  40. package/dist/popup-menu-register.js.map +1 -1
  41. package/dist/popup-menu.d.ts +2 -1
  42. package/dist/popup-menu.js +1 -1
  43. package/dist/styles/catalog/components/catalog-example.css +4 -0
  44. package/dist/styles/content-item.css +11 -2
  45. package/dist/styles/grid.css +7 -0
  46. package/dist/styles/popup-menu.css +9 -0
  47. package/dist/styles/segmented-control.css +3 -0
  48. package/dist/styles/token-search-field.css +51 -5
  49. package/dist/styles/toolbar-control-group.css +14 -0
  50. package/dist/styles/workbench.css +7 -25
  51. package/dist/{token-search-field-DvgFLhLL.d.ts → token-search-field-CVGwDn2y.d.ts} +30 -6
  52. package/dist/token-search-field.d.ts +1 -1
  53. package/dist/token-search-field.js +1 -1
  54. package/dist/token-search-model.d.ts +1 -1
  55. package/dist/wire-catalog.js +1 -1
  56. package/dist/wire-content-items.d.ts +3 -1
  57. package/dist/wire-content-items.js +30 -6
  58. package/dist/wire-content-items.js.map +1 -1
  59. package/dist/wire-token-search-fields.d.ts +1 -1
  60. package/dist/wire-token-search-fields.js +1 -1
  61. package/dist/wire-workbench.js +1 -1
  62. package/dist/workbench.js +1 -1
  63. package/docs/accessibility.md +29 -4
  64. package/docs/catalog.md +6 -2
  65. package/docs/component-contract.md +34 -2
  66. package/docs/component-selection.md +16 -0
  67. package/docs/layout.md +42 -10
  68. package/docs/surface-scaffold.md +6 -3
  69. package/docs/ux-demo.md +1 -0
  70. package/docs/workbench.md +5 -1
  71. package/package.json +1 -1
  72. package/dist/chunk-7AKGPBCC.js.map +0 -1
  73. package/dist/chunk-NAPE7WUS.js.map +0 -1
  74. package/dist/chunk-OBAFAH5B.js.map +0 -1
  75. package/dist/chunk-R75GGNWY.js.map +0 -1
  76. package/dist/chunk-RTJNJTG3.js.map +0 -1
  77. package/dist/chunk-UCKKT6KO.js.map +0 -1
@@ -5,12 +5,50 @@ import WaDropdownItem from '@awesome.me/webawesome/dist/components/dropdown-item
5
5
  import '@awesome.me/webawesome/dist/components/tooltip/tooltip.js';
6
6
  import WaDropdown from '@awesome.me/webawesome/dist/components/dropdown/dropdown.js';
7
7
 
8
- // src/install-popup-menu-keyboard.ts
8
+ // src/install-dropdown-show-focus.ts
9
9
  var installed = /* @__PURE__ */ new WeakSet();
10
- function installPopupMenuKeyboard(prototype) {
10
+ var showEpoch = /* @__PURE__ */ new WeakMap();
11
+ function installDropdownShowFocus(prototype) {
11
12
  if (installed.has(prototype)) return;
12
13
  installed.add(prototype);
13
14
  const target = prototype;
15
+ const showMenu = target.showMenu;
16
+ target.showMenu = async function() {
17
+ const scoped = this.classList.contains("kui-popup-menu") || this.closest(".kui-popup-surface") !== null;
18
+ if (!scoped) return showMenu.call(this);
19
+ const epoch = (showEpoch.get(this) ?? 0) + 1;
20
+ showEpoch.set(this, epoch);
21
+ let navigatedItem;
22
+ const rememberFocus = (event) => {
23
+ const item = event.target;
24
+ if (this.menu?.classList.contains("show") && item instanceof HTMLElement && item.localName === "wa-dropdown-item" && this.contains(item)) {
25
+ navigatedItem = item;
26
+ }
27
+ };
28
+ this.addEventListener("focusin", rememberFocus);
29
+ try {
30
+ await showMenu.call(this);
31
+ } finally {
32
+ this.removeEventListener("focusin", rememberFocus);
33
+ }
34
+ if (showEpoch.get(this) !== epoch || !this.open || !this.popup?.active || !navigatedItem?.isConnected || !this.contains(navigatedItem))
35
+ return;
36
+ const siblings = navigatedItem.slot === "submenu" ? Array.from(navigatedItem.parentElement?.children ?? []).filter(
37
+ (item) => item.localName === "wa-dropdown-item"
38
+ ) : this.getItems();
39
+ siblings.forEach((item) => {
40
+ item.active = item === navigatedItem;
41
+ });
42
+ navigatedItem.focus({ preventScroll: true });
43
+ };
44
+ }
45
+
46
+ // src/install-popup-menu-keyboard.ts
47
+ var installed2 = /* @__PURE__ */ new WeakSet();
48
+ function installPopupMenuKeyboard(prototype) {
49
+ if (installed2.has(prototype)) return;
50
+ installed2.add(prototype);
51
+ const target = prototype;
14
52
  const makeSelection = target.makeSelection;
15
53
  target.makeSelection = function(item, event) {
16
54
  if (event instanceof KeyboardEvent && this.classList.contains("kui-popup-menu") && !item.disabled) {
@@ -21,17 +59,70 @@ function installPopupMenuKeyboard(prototype) {
21
59
  };
22
60
  }
23
61
 
62
+ // src/install-popup-menu-lifecycle.ts
63
+ var installed3 = /* @__PURE__ */ new WeakSet();
64
+ function installPopupMenuLifecycle(prototype) {
65
+ if (installed3.has(prototype)) return;
66
+ installed3.add(prototype);
67
+ const target = prototype;
68
+ const showMenu = target.showMenu;
69
+ const hideMenu = target.hideMenu;
70
+ const hiding = /* @__PURE__ */ new WeakMap();
71
+ target.showMenu = function() {
72
+ const transition = hiding.get(this);
73
+ if (transition && this.open && this.popup?.active && this.classList.contains("kui-popup-menu")) {
74
+ this.popup.active = false;
75
+ transition.reopened = true;
76
+ }
77
+ return showMenu.call(this);
78
+ };
79
+ target.hideMenu = async function() {
80
+ const scoped = this.classList.contains("kui-popup-menu");
81
+ const transition = { reopened: false };
82
+ if (scoped) hiding.set(this, transition);
83
+ await hideMenu.call(this);
84
+ if (scoped && hiding.get(this) === transition && this.open && this.isConnected && this.popup?.active && !transition.reopened) {
85
+ this.popup.active = false;
86
+ void this.showMenu();
87
+ }
88
+ if (hiding.get(this) === transition) hiding.delete(this);
89
+ };
90
+ }
91
+
24
92
  // src/install-popup-menu-submenu-focus.ts
25
- var installed2 = /* @__PURE__ */ new WeakSet();
93
+ var installed4 = /* @__PURE__ */ new WeakSet();
26
94
  function installPopupMenuSubmenuFocus(prototype) {
27
- if (installed2.has(prototype)) return;
28
- installed2.add(prototype);
95
+ if (installed4.has(prototype)) return;
96
+ installed4.add(prototype);
29
97
  const target = prototype;
30
98
  const openSubmenu = target.openSubmenu;
99
+ const closeSubmenu = target.closeSubmenu;
100
+ const submenuOpen = Object.getOwnPropertyDescriptor(prototype, "submenuOpen");
101
+ if (submenuOpen?.set) {
102
+ Object.defineProperty(prototype, "submenuOpen", {
103
+ ...submenuOpen,
104
+ set(value) {
105
+ const wasOpen = this.submenuOpen;
106
+ submenuOpen.set.call(this, value);
107
+ if (value && wasOpen && this.submenuElement?.hidden && this.closest("wa-dropdown.kui-popup-menu"))
108
+ void this.openSubmenu();
109
+ }
110
+ });
111
+ }
112
+ target.closeSubmenu = async function() {
113
+ const submenu = this.submenuElement;
114
+ await closeSubmenu.call(this);
115
+ if (this.submenuOpen && submenu?.hidden && this.isConnected && this.closest("wa-dropdown.kui-popup-menu"))
116
+ void this.openSubmenu();
117
+ };
31
118
  target.openSubmenu = async function() {
32
119
  const submenu = this.submenuElement;
33
120
  if (!this.closest("wa-dropdown.kui-popup-menu") || !submenu)
34
121
  return openSubmenu.call(this);
122
+ if (submenu.classList.contains("show")) {
123
+ if (!submenu.hidden) return;
124
+ submenu.classList.remove("show");
125
+ }
35
126
  let desired;
36
127
  const trackFocus = (event) => {
37
128
  const item = event.composedPath().find(
@@ -57,9 +148,94 @@ function installPopupMenuSubmenuFocus(prototype) {
57
148
  };
58
149
  }
59
150
 
151
+ // src/install-popup-menu-submenu-placement.ts
152
+ var installed5 = /* @__PURE__ */ new WeakSet();
153
+ var phoneWidth = "(max-width: 480px)";
154
+ var viewportInset = 8;
155
+ var menuGap = 4;
156
+ function phoneSubmenuPosition(parent, submenu, viewport, rtl) {
157
+ const width = Math.min(submenu.width, viewport.width - 2 * viewportInset);
158
+ const height = submenu.height;
159
+ const below = Math.max(
160
+ 0,
161
+ viewport.height - parent.bottom - menuGap - viewportInset
162
+ );
163
+ const above = Math.max(0, parent.top - menuGap - viewportInset);
164
+ const useBelow = height <= below || height > above && below >= above;
165
+ const availableHeight = useBelow ? below : above;
166
+ const left = rtl ? parent.right - width : parent.left;
167
+ return {
168
+ left: Math.max(
169
+ viewportInset,
170
+ Math.min(left, viewport.width - viewportInset - width)
171
+ ),
172
+ top: useBelow ? parent.bottom + menuGap : parent.top - menuGap - Math.min(height, availableHeight),
173
+ maxHeight: availableHeight,
174
+ maxWidth: viewport.width - 2 * viewportInset
175
+ };
176
+ }
177
+ function clearPhoneStyles(submenu) {
178
+ for (const property of [
179
+ "position",
180
+ "left",
181
+ "top",
182
+ "max-width",
183
+ "max-height",
184
+ "box-sizing",
185
+ "overflow-y"
186
+ ])
187
+ submenu.style.removeProperty(property);
188
+ }
189
+ function installPopupMenuSubmenuPlacement(prototype) {
190
+ if (installed5.has(prototype)) return;
191
+ installed5.add(prototype);
192
+ const target = prototype;
193
+ const positionSubmenu = target.positionSubmenu;
194
+ target.positionSubmenu = function(item) {
195
+ if (!this.classList.contains("kui-popup-menu")) {
196
+ positionSubmenu.call(this, item);
197
+ return;
198
+ }
199
+ const submenu = item.submenuElement;
200
+ if (!window.matchMedia(phoneWidth).matches || !submenu || !this.menu) {
201
+ if (submenu) clearPhoneStyles(submenu);
202
+ positionSubmenu.call(this, item);
203
+ return;
204
+ }
205
+ window.queueMicrotask(() => {
206
+ if (!this.isConnected || !item.submenuOpen || !window.matchMedia(phoneWidth).matches || !this.menu || !submenu.isConnected)
207
+ return;
208
+ const parentItem = item.parentElement?.localName === "wa-dropdown-item" ? item.parentElement : void 0;
209
+ const parentMenu = parentItem?.submenuElement ?? this.menu;
210
+ submenu.style.position = "fixed";
211
+ submenu.style.maxWidth = `calc(100vw - ${2 * viewportInset}px)`;
212
+ submenu.style.maxHeight = "none";
213
+ submenu.style.boxSizing = "border-box";
214
+ submenu.style.overflowY = "auto";
215
+ const placement = phoneSubmenuPosition(
216
+ parentMenu.getBoundingClientRect(),
217
+ submenu.getBoundingClientRect(),
218
+ { width: window.innerWidth, height: window.innerHeight },
219
+ window.getComputedStyle(this).direction === "rtl"
220
+ );
221
+ submenu.style.left = `${placement.left}px`;
222
+ submenu.style.top = `${placement.top}px`;
223
+ submenu.style.maxHeight = `${placement.maxHeight}px`;
224
+ submenu.style.maxWidth = `${placement.maxWidth}px`;
225
+ submenu.setAttribute(
226
+ "data-placement",
227
+ placement.top >= parentMenu.getBoundingClientRect().bottom ? "bottom-start" : "top-start"
228
+ );
229
+ });
230
+ };
231
+ }
232
+
60
233
  // src/popup-menu-register.ts
61
234
  installPopupMenuKeyboard(WaDropdown.prototype);
235
+ installPopupMenuLifecycle(WaDropdown.prototype);
236
+ installDropdownShowFocus(WaDropdown.prototype);
62
237
  installPopupMenuSubmenuFocus(WaDropdownItem.prototype);
238
+ installPopupMenuSubmenuPlacement(WaDropdown.prototype);
63
239
  installHelpTags();
64
240
  var popupMenuElementsRegistered = true;
65
241
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/install-popup-menu-keyboard.ts","../src/install-popup-menu-submenu-focus.ts","../src/popup-menu-register.ts"],"names":["installed"],"mappings":"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","file":"popup-menu-register.js","sourcesContent":["interface PopupMenuDropdown extends HTMLElement {\n makeSelection(\n item: HTMLElement & { disabled?: boolean },\n event?: Event,\n ): void;\n}\n\nconst installed = new WeakSet<object>();\n\n/**\n * Route a keyboard choice in a `PopupMenu` through the item's click. Web Awesome\n * selects a pointer choice from the item's click event but a keyboard choice\n * (Enter or Space) directly, so delegated `data-action` click handlers would\n * never run for keyboard users. Clicking the item makes Web Awesome select it\n * exactly as it does for a pointer — one `wa-select`, then close and focus\n * return — while the click reaches the application's delegation. Raw\n * `wa-dropdown`s outside `PopupMenu` are unaffected.\n */\nexport function installPopupMenuKeyboard(prototype: object): void {\n if (installed.has(prototype)) return;\n installed.add(prototype);\n const target = prototype as PopupMenuDropdown;\n const makeSelection = target.makeSelection;\n target.makeSelection = function (this: PopupMenuDropdown, item, event): void {\n if (\n event instanceof KeyboardEvent &&\n this.classList.contains('kui-popup-menu') &&\n !item.disabled\n ) {\n item.click();\n return;\n }\n makeSelection.call(this, item, event);\n };\n}\n","interface SubmenuItem extends HTMLElement {\n active: boolean;\n}\n\ninterface PopupMenuParentItem extends HTMLElement {\n submenuElement?: HTMLElement;\n submenuOpen: boolean;\n getSubmenuItems(): SubmenuItem[];\n openSubmenu(): Promise<void>;\n}\n\nconst installed = new WeakSet<object>();\n\n/** Preserve a rapid keyboard move past Web Awesome's late first-item focus. */\nexport function installPopupMenuSubmenuFocus(prototype: object): void {\n if (installed.has(prototype)) return;\n installed.add(prototype);\n const target = prototype as PopupMenuParentItem;\n const openSubmenu = target.openSubmenu;\n target.openSubmenu = async function (\n this: PopupMenuParentItem,\n ): Promise<void> {\n const submenu = this.submenuElement;\n if (!this.closest('wa-dropdown.kui-popup-menu') || !submenu)\n return openSubmenu.call(this);\n\n let desired: SubmenuItem | undefined;\n const trackFocus = (event: FocusEvent) => {\n const item = event\n .composedPath()\n .find(\n (node): node is SubmenuItem =>\n node instanceof HTMLElement &&\n node.localName === 'wa-dropdown-item' &&\n node.getAttribute('slot') === 'submenu',\n );\n if (item && this.getSubmenuItems().includes(item)) desired = item;\n };\n submenu.addEventListener('focusin', trackFocus);\n try {\n await openSubmenu.call(this);\n } finally {\n submenu.removeEventListener('focusin', trackFocus);\n }\n\n const items = this.getSubmenuItems();\n if (!desired || desired === items[0]) return;\n const selected = desired;\n // Web Awesome queues its first-item focus after the show animation. This\n // timer follows that one, restoring a user's later arrow choice only if\n // the queued focus actually reset it. Pointer/blur/close paths are left alone.\n window.setTimeout(() => {\n if (\n !this.isConnected ||\n !this.submenuOpen ||\n submenu.hidden ||\n document.activeElement !== items[0]\n )\n return;\n items.forEach((item) => (item.active = item === selected));\n selected.focus({ preventScroll: true });\n }, 0);\n };\n}\n","import '@awesome.me/webawesome/dist/components/button/button.js';\nimport '@awesome.me/webawesome/dist/components/divider/divider.js';\nimport '@awesome.me/webawesome/dist/components/dropdown-item/dropdown-item.js';\nimport '@awesome.me/webawesome/dist/components/tooltip/tooltip.js';\n\nimport WaDropdown from '@awesome.me/webawesome/dist/components/dropdown/dropdown.js';\nimport WaDropdownItem from '@awesome.me/webawesome/dist/components/dropdown-item/dropdown-item.js';\n\nimport { installHelpTags } from './install-help-tag.js';\nimport { installPopupMenuKeyboard } from './install-popup-menu-keyboard.js';\nimport { installPopupMenuSubmenuFocus } from './install-popup-menu-submenu-focus.js';\n\ninstallPopupMenuKeyboard(WaDropdown.prototype);\ninstallPopupMenuSubmenuFocus(WaDropdownItem.prototype);\ninstallHelpTags();\n\n/**\n * Marker export for tests and tooling; importing this module registers the\n * Web Awesome elements a `PopupMenu` renders (`wa-dropdown`,\n * `wa-dropdown-item`, `wa-button`, and `wa-divider`) and routes a keyboard\n * choice through the item's click so delegated `data-action`s run.\n */\nexport const popupMenuElementsRegistered = true;\n"]}
1
+ {"version":3,"sources":["../src/install-dropdown-show-focus.ts","../src/install-popup-menu-keyboard.ts","../src/install-popup-menu-lifecycle.ts","../src/install-popup-menu-submenu-focus.ts","../src/install-popup-menu-submenu-placement.ts","../src/popup-menu-register.ts"],"names":["installed"],"mappings":";;;;;;;;AAYA,IAAM,SAAA,uBAAgB,OAAA,EAAgB;AACtC,IAAM,SAAA,uBAAgB,OAAA,EAAmC;AAGlD,SAAS,yBAAyB,SAAA,EAAyB;AAChE,EAAA,IAAI,SAAA,CAAU,GAAA,CAAI,SAAS,CAAA,EAAG;AAC9B,EAAA,SAAA,CAAU,IAAI,SAAS,CAAA;AACvB,EAAA,MAAM,MAAA,GAAS,SAAA;AACf,EAAA,MAAM,WAAW,MAAA,CAAO,QAAA;AACxB,EAAA,MAAA,CAAO,WAAW,iBAAwD;AACxE,IAAA,MAAM,MAAA,GACJ,KAAK,SAAA,CAAU,QAAA,CAAS,gBAAgB,CAAA,IACxC,IAAA,CAAK,OAAA,CAAQ,oBAAoB,CAAA,KAAM,IAAA;AACzC,IAAA,IAAI,CAAC,MAAA,EAAQ,OAAO,QAAA,CAAS,KAAK,IAAI,CAAA;AAEtC,IAAA,MAAM,KAAA,GAAA,CAAS,SAAA,CAAU,GAAA,CAAI,IAAI,KAAK,CAAA,IAAK,CAAA;AAC3C,IAAA,SAAA,CAAU,GAAA,CAAI,MAAM,KAAK,CAAA;AACzB,IAAA,IAAI,aAAA;AACJ,IAAA,MAAM,aAAA,GAAgB,CAAC,KAAA,KAAsB;AAC3C,MAAA,MAAM,OAAO,KAAA,CAAM,MAAA;AACnB,MAAA,IACE,IAAA,CAAK,IAAA,EAAM,SAAA,CAAU,QAAA,CAAS,MAAM,CAAA,IACpC,IAAA,YAAgB,WAAA,IAChB,IAAA,CAAK,SAAA,KAAc,kBAAA,IACnB,IAAA,CAAK,QAAA,CAAS,IAAI,CAAA,EAClB;AACA,QAAA,aAAA,GAAgB,IAAA;AAAA,MAClB;AAAA,IACF,CAAA;AACA,IAAA,IAAA,CAAK,gBAAA,CAAiB,WAAW,aAAa,CAAA;AAC9C,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,CAAS,KAAK,IAAI,CAAA;AAAA,IAC1B,CAAA,SAAE;AACA,MAAA,IAAA,CAAK,mBAAA,CAAoB,WAAW,aAAa,CAAA;AAAA,IACnD;AACA,IAAA,IACE,UAAU,GAAA,CAAI,IAAI,MAAM,KAAA,IACxB,CAAC,KAAK,IAAA,IACN,CAAC,IAAA,CAAK,KAAA,EAAO,UACb,CAAC,aAAA,EAAe,eAChB,CAAC,IAAA,CAAK,SAAS,aAAa,CAAA;AAE5B,MAAA;AAEF,IAAA,MAAM,QAAA,GACJ,aAAA,CAAc,IAAA,KAAS,SAAA,GACnB,KAAA,CAAM,IAAA,CAAK,aAAA,CAAc,aAAA,EAAe,QAAA,IAAY,EAAE,CAAA,CAAE,MAAA;AAAA,MACtD,CAAC,IAAA,KACC,IAAA,CAAK,SAAA,KAAc;AAAA,KACvB,GACA,KAAK,QAAA,EAAS;AACpB,IAAA,QAAA,CAAS,OAAA,CAAQ,CAAC,IAAA,KAAS;AACzB,MAAA,IAAA,CAAK,SAAS,IAAA,KAAS,aAAA;AAAA,IACzB,CAAC,CAAA;AACD,IAAA,aAAA,CAAc,KAAA,CAAM,EAAE,aAAA,EAAe,IAAA,EAAM,CAAA;AAAA,EAC7C,CAAA;AACF;;;AC7DA,IAAMA,UAAAA,uBAAgB,OAAA,EAAgB;AAW/B,SAAS,yBAAyB,SAAA,EAAyB;AAChE,EAAA,IAAIA,UAAAA,CAAU,GAAA,CAAI,SAAS,CAAA,EAAG;AAC9B,EAAAA,UAAAA,CAAU,IAAI,SAAS,CAAA;AACvB,EAAA,MAAM,MAAA,GAAS,SAAA;AACf,EAAA,MAAM,gBAAgB,MAAA,CAAO,aAAA;AAC7B,EAAA,MAAA,CAAO,aAAA,GAAgB,SAAmC,IAAA,EAAM,KAAA,EAAa;AAC3E,IAAA,IACE,KAAA,YAAiB,iBACjB,IAAA,CAAK,SAAA,CAAU,SAAS,gBAAgB,CAAA,IACxC,CAAC,IAAA,CAAK,QAAA,EACN;AACA,MAAA,IAAA,CAAK,KAAA,EAAM;AACX,MAAA;AAAA,IACF;AACA,IAAA,aAAA,CAAc,IAAA,CAAK,IAAA,EAAM,IAAA,EAAM,KAAK,CAAA;AAAA,EACtC,CAAA;AACF;;;AC3BA,IAAMA,UAAAA,uBAAgB,OAAA,EAAgB;AAG/B,SAAS,0BAA0B,SAAA,EAAyB;AACjE,EAAA,IAAIA,UAAAA,CAAU,GAAA,CAAI,SAAS,CAAA,EAAG;AAC9B,EAAAA,UAAAA,CAAU,IAAI,SAAS,CAAA;AACvB,EAAA,MAAM,MAAA,GAAS,SAAA;AACf,EAAA,MAAM,WAAW,MAAA,CAAO,QAAA;AACxB,EAAA,MAAM,WAAW,MAAA,CAAO,QAAA;AACxB,EAAA,MAAM,MAAA,uBAAa,OAAA,EAAkD;AACrE,EAAA,MAAA,CAAO,WAAW,WAAkD;AAClE,IAAA,MAAM,UAAA,GAAa,MAAA,CAAO,GAAA,CAAI,IAAI,CAAA;AAClC,IAAA,IACE,UAAA,IACA,IAAA,CAAK,IAAA,IACL,IAAA,CAAK,KAAA,EAAO,UACZ,IAAA,CAAK,SAAA,CAAU,QAAA,CAAS,gBAAgB,CAAA,EACxC;AAGA,MAAA,IAAA,CAAK,MAAM,MAAA,GAAS,KAAA;AACpB,MAAA,UAAA,CAAW,QAAA,GAAW,IAAA;AAAA,IACxB;AACA,IAAA,OAAO,QAAA,CAAS,KAAK,IAAI,CAAA;AAAA,EAC3B,CAAA;AACA,EAAA,MAAA,CAAO,WAAW,iBAAwD;AACxE,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,SAAA,CAAU,QAAA,CAAS,gBAAgB,CAAA;AACvD,IAAA,MAAM,UAAA,GAAa,EAAE,QAAA,EAAU,KAAA,EAAM;AACrC,IAAA,IAAI,MAAA,EAAQ,MAAA,CAAO,GAAA,CAAI,IAAA,EAAM,UAAU,CAAA;AACvC,IAAA,MAAM,QAAA,CAAS,KAAK,IAAI,CAAA;AAIxB,IAAA,IACE,MAAA,IACA,MAAA,CAAO,GAAA,CAAI,IAAI,MAAM,UAAA,IACrB,IAAA,CAAK,IAAA,IACL,IAAA,CAAK,eACL,IAAA,CAAK,KAAA,EAAO,MAAA,IACZ,CAAC,WAAW,QAAA,EACZ;AACA,MAAA,IAAA,CAAK,MAAM,MAAA,GAAS,KAAA;AACpB,MAAA,KAAK,KAAK,QAAA,EAAS;AAAA,IACrB;AACA,IAAA,IAAI,OAAO,GAAA,CAAI,IAAI,MAAM,UAAA,EAAY,MAAA,CAAO,OAAO,IAAI,CAAA;AAAA,EACzD,CAAA;AACF;;;ACzCA,IAAMA,UAAAA,uBAAgB,OAAA,EAAgB;AAG/B,SAAS,6BAA6B,SAAA,EAAyB;AACpE,EAAA,IAAIA,UAAAA,CAAU,GAAA,CAAI,SAAS,CAAA,EAAG;AAC9B,EAAAA,UAAAA,CAAU,IAAI,SAAS,CAAA;AACvB,EAAA,MAAM,MAAA,GAAS,SAAA;AACf,EAAA,MAAM,cAAc,MAAA,CAAO,WAAA;AAC3B,EAAA,MAAM,eAAe,MAAA,CAAO,YAAA;AAC5B,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,wBAAA,CAAyB,SAAA,EAAW,aAAa,CAAA;AAC5E,EAAA,IAAI,aAAa,GAAA,EAAK;AACpB,IAAA,MAAA,CAAO,cAAA,CAAe,WAAW,aAAA,EAAe;AAAA,MAC9C,GAAG,WAAA;AAAA,MACH,IAA+B,KAAA,EAAgB;AAC7C,QAAA,MAAM,UAAU,IAAA,CAAK,WAAA;AACrB,QAAA,WAAA,CAAY,GAAA,CAAK,IAAA,CAAK,IAAA,EAAM,KAAK,CAAA;AAIjC,QAAA,IACE,SACA,OAAA,IACA,IAAA,CAAK,gBAAgB,MAAA,IACrB,IAAA,CAAK,QAAQ,4BAA4B,CAAA;AAEzC,UAAA,KAAK,KAAK,WAAA,EAAY;AAAA,MAC1B;AAAA,KACD,CAAA;AAAA,EACH;AACA,EAAA,MAAA,CAAO,eAAe,iBAEL;AACf,IAAA,MAAM,UAAU,IAAA,CAAK,cAAA;AACrB,IAAA,MAAM,YAAA,CAAa,KAAK,IAAI,CAAA;AAG5B,IAAA,IACE,IAAA,CAAK,eACL,OAAA,EAAS,MAAA,IACT,KAAK,WAAA,IACL,IAAA,CAAK,QAAQ,4BAA4B,CAAA;AAEzC,MAAA,KAAK,KAAK,WAAA,EAAY;AAAA,EAC1B,CAAA;AACA,EAAA,MAAA,CAAO,cAAc,iBAEJ;AACf,IAAA,MAAM,UAAU,IAAA,CAAK,cAAA;AACrB,IAAA,IAAI,CAAC,IAAA,CAAK,OAAA,CAAQ,4BAA4B,KAAK,CAAC,OAAA;AAClD,MAAA,OAAO,WAAA,CAAY,KAAK,IAAI,CAAA;AAK9B,IAAA,IAAI,OAAA,CAAQ,SAAA,CAAU,QAAA,CAAS,MAAM,CAAA,EAAG;AACtC,MAAA,IAAI,CAAC,QAAQ,MAAA,EAAQ;AACrB,MAAA,OAAA,CAAQ,SAAA,CAAU,OAAO,MAAM,CAAA;AAAA,IACjC;AAEA,IAAA,IAAI,OAAA;AACJ,IAAA,MAAM,UAAA,GAAa,CAAC,KAAA,KAAsB;AACxC,MAAA,MAAM,IAAA,GAAO,KAAA,CACV,YAAA,EAAa,CACb,IAAA;AAAA,QACC,CAAC,IAAA,KACC,IAAA,YAAgB,WAAA,IAChB,IAAA,CAAK,cAAc,kBAAA,IACnB,IAAA,CAAK,YAAA,CAAa,MAAM,CAAA,KAAM;AAAA,OAClC;AACF,MAAA,IAAI,QAAQ,IAAA,CAAK,eAAA,GAAkB,QAAA,CAAS,IAAI,GAAG,OAAA,GAAU,IAAA;AAAA,IAC/D,CAAA;AACA,IAAA,OAAA,CAAQ,gBAAA,CAAiB,WAAW,UAAU,CAAA;AAC9C,IAAA,IAAI;AACF,MAAA,MAAM,WAAA,CAAY,KAAK,IAAI,CAAA;AAAA,IAC7B,CAAA,SAAE;AACA,MAAA,OAAA,CAAQ,mBAAA,CAAoB,WAAW,UAAU,CAAA;AAAA,IACnD;AAEA,IAAA,MAAM,KAAA,GAAQ,KAAK,eAAA,EAAgB;AACnC,IAAA,IAAI,CAAC,OAAA,IAAW,OAAA,KAAY,KAAA,CAAM,CAAC,CAAA,EAAG;AACtC,IAAA,MAAM,QAAA,GAAW,OAAA;AAIjB,IAAA,MAAA,CAAO,WAAW,MAAM;AACtB,MAAA,IACE,CAAC,IAAA,CAAK,WAAA,IACN,CAAC,IAAA,CAAK,WAAA,IACN,OAAA,CAAQ,MAAA,IACR,QAAA,CAAS,aAAA,KAAkB,KAAA,CAAM,CAAC,CAAA;AAElC,QAAA;AACF,MAAA,KAAA,CAAM,QAAQ,CAAC,IAAA,KAAU,IAAA,CAAK,MAAA,GAAS,SAAS,QAAS,CAAA;AACzD,MAAA,QAAA,CAAS,KAAA,CAAM,EAAE,aAAA,EAAe,IAAA,EAAM,CAAA;AAAA,IACxC,GAAG,CAAC,CAAA;AAAA,EACN,CAAA;AACF;;;AClGA,IAAMA,UAAAA,uBAAgB,OAAA,EAAgB;AACtC,IAAM,UAAA,GAAa,oBAAA;AACnB,IAAM,aAAA,GAAgB,CAAA;AACtB,IAAM,OAAA,GAAU,CAAA;AAGT,SAAS,oBAAA,CACd,MAAA,EACA,OAAA,EACA,QAAA,EACA,GAAA,EACA;AACA,EAAA,MAAM,KAAA,GAAQ,KAAK,GAAA,CAAI,OAAA,CAAQ,OAAO,QAAA,CAAS,KAAA,GAAQ,IAAI,aAAa,CAAA;AACxE,EAAA,MAAM,SAAS,OAAA,CAAQ,MAAA;AACvB,EAAA,MAAM,QAAQ,IAAA,CAAK,GAAA;AAAA,IACjB,CAAA;AAAA,IACA,QAAA,CAAS,MAAA,GAAS,MAAA,CAAO,MAAA,GAAS,OAAA,GAAU;AAAA,GAC9C;AACA,EAAA,MAAM,QAAQ,IAAA,CAAK,GAAA,CAAI,GAAG,MAAA,CAAO,GAAA,GAAM,UAAU,aAAa,CAAA;AAC9D,EAAA,MAAM,QAAA,GAAW,MAAA,IAAU,KAAA,IAAU,MAAA,GAAS,SAAS,KAAA,IAAS,KAAA;AAChE,EAAA,MAAM,eAAA,GAAkB,WAAW,KAAA,GAAQ,KAAA;AAC3C,EAAA,MAAM,IAAA,GAAO,GAAA,GAAM,MAAA,CAAO,KAAA,GAAQ,QAAQ,MAAA,CAAO,IAAA;AACjD,EAAA,OAAO;AAAA,IACL,MAAM,IAAA,CAAK,GAAA;AAAA,MACT,aAAA;AAAA,MACA,KAAK,GAAA,CAAI,IAAA,EAAM,QAAA,CAAS,KAAA,GAAQ,gBAAgB,KAAK;AAAA,KACvD;AAAA,IACA,GAAA,EAAK,QAAA,GACD,MAAA,CAAO,MAAA,GAAS,OAAA,GAChB,MAAA,CAAO,GAAA,GAAM,OAAA,GAAU,IAAA,CAAK,GAAA,CAAI,MAAA,EAAQ,eAAe,CAAA;AAAA,IAC3D,SAAA,EAAW,eAAA;AAAA,IACX,QAAA,EAAU,QAAA,CAAS,KAAA,GAAQ,CAAA,GAAI;AAAA,GACjC;AACF;AAEA,SAAS,iBAAiB,OAAA,EAAsB;AAC9C,EAAA,KAAA,MAAW,QAAA,IAAY;AAAA,IACrB,UAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA,WAAA;AAAA,IACA,YAAA;AAAA,IACA,YAAA;AAAA,IACA;AAAA,GACF;AACE,IAAA,OAAA,CAAQ,KAAA,CAAM,eAAe,QAAQ,CAAA;AACzC;AAQO,SAAS,iCAAiC,SAAA,EAAyB;AACxE,EAAA,IAAIA,UAAAA,CAAU,GAAA,CAAI,SAAS,CAAA,EAAG;AAC9B,EAAAA,UAAAA,CAAU,IAAI,SAAS,CAAA;AACvB,EAAA,MAAM,MAAA,GAAS,SAAA;AACf,EAAA,MAAM,kBAAkB,MAAA,CAAO,eAAA;AAC/B,EAAA,MAAA,CAAO,eAAA,GAAkB,SAAmC,IAAA,EAAY;AACtE,IAAA,IAAI,CAAC,IAAA,CAAK,SAAA,CAAU,QAAA,CAAS,gBAAgB,CAAA,EAAG;AAC9C,MAAA,eAAA,CAAgB,IAAA,CAAK,MAAM,IAAI,CAAA;AAC/B,MAAA;AAAA,IACF;AACA,IAAA,MAAM,UAAU,IAAA,CAAK,cAAA;AACrB,IAAA,IAAI,CAAC,MAAA,CAAO,UAAA,CAAW,UAAU,CAAA,CAAE,WAAW,CAAC,OAAA,IAAW,CAAC,IAAA,CAAK,IAAA,EAAM;AACpE,MAAA,IAAI,OAAA,mBAA0B,OAAO,CAAA;AACrC,MAAA,eAAA,CAAgB,IAAA,CAAK,MAAM,IAAI,CAAA;AAC/B,MAAA;AAAA,IACF;AAIA,IAAA,MAAA,CAAO,eAAe,MAAM;AAC1B,MAAA,IACE,CAAC,IAAA,CAAK,WAAA,IACN,CAAC,IAAA,CAAK,eACN,CAAC,MAAA,CAAO,UAAA,CAAW,UAAU,EAAE,OAAA,IAC/B,CAAC,IAAA,CAAK,IAAA,IACN,CAAC,OAAA,CAAQ,WAAA;AAET,QAAA;AACF,MAAA,MAAM,aACJ,IAAA,CAAK,aAAA,EAAe,SAAA,KAAc,kBAAA,GAC7B,KAAK,aAAA,GACN,MAAA;AACN,MAAA,MAAM,UAAA,GAAa,UAAA,EAAY,cAAA,IAAkB,IAAA,CAAK,IAAA;AACtD,MAAA,OAAA,CAAQ,MAAM,QAAA,GAAW,OAAA;AACzB,MAAA,OAAA,CAAQ,KAAA,CAAM,QAAA,GAAW,CAAA,aAAA,EAAgB,CAAA,GAAI,aAAa,CAAA,GAAA,CAAA;AAC1D,MAAA,OAAA,CAAQ,MAAM,SAAA,GAAY,MAAA;AAC1B,MAAA,OAAA,CAAQ,MAAM,SAAA,GAAY,YAAA;AAC1B,MAAA,OAAA,CAAQ,MAAM,SAAA,GAAY,MAAA;AAC1B,MAAA,MAAM,SAAA,GAAY,oBAAA;AAAA,QAChB,WAAW,qBAAA,EAAsB;AAAA,QACjC,QAAQ,qBAAA,EAAsB;AAAA,QAC9B,EAAE,KAAA,EAAO,MAAA,CAAO,UAAA,EAAY,MAAA,EAAQ,OAAO,WAAA,EAAY;AAAA,QACvD,MAAA,CAAO,gBAAA,CAAiB,IAAI,CAAA,CAAE,SAAA,KAAc;AAAA,OAC9C;AACA,MAAA,OAAA,CAAQ,KAAA,CAAM,IAAA,GAAO,CAAA,EAAG,SAAA,CAAU,IAAI,CAAA,EAAA,CAAA;AACtC,MAAA,OAAA,CAAQ,KAAA,CAAM,GAAA,GAAM,CAAA,EAAG,SAAA,CAAU,GAAG,CAAA,EAAA,CAAA;AACpC,MAAA,OAAA,CAAQ,KAAA,CAAM,SAAA,GAAY,CAAA,EAAG,SAAA,CAAU,SAAS,CAAA,EAAA,CAAA;AAChD,MAAA,OAAA,CAAQ,KAAA,CAAM,QAAA,GAAW,CAAA,EAAG,SAAA,CAAU,QAAQ,CAAA,EAAA,CAAA;AAC9C,MAAA,OAAA,CAAQ,YAAA;AAAA,QACN,gBAAA;AAAA,QACA,UAAU,GAAA,IAAO,UAAA,CAAW,qBAAA,EAAsB,CAAE,SAChD,cAAA,GACA;AAAA,OACN;AAAA,IACF,CAAC,CAAA;AAAA,EACH,CAAA;AACF;;;ACzGA,wBAAA,CAAyB,WAAW,SAAS,CAAA;AAC7C,yBAAA,CAA0B,WAAW,SAAS,CAAA;AAC9C,wBAAA,CAAyB,WAAW,SAAS,CAAA;AAC7C,4BAAA,CAA6B,eAAe,SAAS,CAAA;AACrD,gCAAA,CAAiC,WAAW,SAAS,CAAA;AACrD,eAAA,EAAgB;AAQT,IAAM,2BAAA,GAA8B","file":"popup-menu-register.js","sourcesContent":["interface FocusableDropdownItem extends HTMLElement {\n active: boolean;\n}\n\ninterface FocusableDropdown extends HTMLElement {\n open: boolean;\n popup?: { active: boolean };\n menu?: HTMLElement;\n getItems(): FocusableDropdownItem[];\n showMenu(): Promise<void>;\n}\n\nconst installed = new WeakSet<object>();\nconst showEpoch = new WeakMap<FocusableDropdown, number>();\n\n/** Preserve item navigation that Web Awesome receives during its show animation. */\nexport function installDropdownShowFocus(prototype: object): void {\n if (installed.has(prototype)) return;\n installed.add(prototype);\n const target = prototype as FocusableDropdown;\n const showMenu = target.showMenu;\n target.showMenu = async function (this: FocusableDropdown): Promise<void> {\n const scoped =\n this.classList.contains('kui-popup-menu') ||\n this.closest('.kui-popup-surface') !== null;\n if (!scoped) return showMenu.call(this);\n\n const epoch = (showEpoch.get(this) ?? 0) + 1;\n showEpoch.set(this, epoch);\n let navigatedItem: FocusableDropdownItem | undefined;\n const rememberFocus = (event: FocusEvent) => {\n const item = event.target;\n if (\n this.menu?.classList.contains('show') &&\n item instanceof HTMLElement &&\n item.localName === 'wa-dropdown-item' &&\n this.contains(item)\n ) {\n navigatedItem = item as FocusableDropdownItem;\n }\n };\n this.addEventListener('focusin', rememberFocus);\n try {\n await showMenu.call(this);\n } finally {\n this.removeEventListener('focusin', rememberFocus);\n }\n if (\n showEpoch.get(this) !== epoch ||\n !this.open ||\n !this.popup?.active ||\n !navigatedItem?.isConnected ||\n !this.contains(navigatedItem)\n )\n return;\n\n const siblings =\n navigatedItem.slot === 'submenu'\n ? Array.from(navigatedItem.parentElement?.children ?? []).filter(\n (item): item is FocusableDropdownItem =>\n item.localName === 'wa-dropdown-item',\n )\n : this.getItems();\n siblings.forEach((item) => {\n item.active = item === navigatedItem;\n });\n navigatedItem.focus({ preventScroll: true });\n };\n}\n","interface PopupMenuDropdown extends HTMLElement {\n makeSelection(\n item: HTMLElement & { disabled?: boolean },\n event?: Event,\n ): void;\n}\n\nconst installed = new WeakSet<object>();\n\n/**\n * Route a keyboard choice in a `PopupMenu` through the item's click. Web Awesome\n * selects a pointer choice from the item's click event but a keyboard choice\n * (Enter or Space) directly, so delegated `data-action` click handlers would\n * never run for keyboard users. Clicking the item makes Web Awesome select it\n * exactly as it does for a pointer — one `wa-select`, then close and focus\n * return — while the click reaches the application's delegation. Raw\n * `wa-dropdown`s outside `PopupMenu` are unaffected.\n */\nexport function installPopupMenuKeyboard(prototype: object): void {\n if (installed.has(prototype)) return;\n installed.add(prototype);\n const target = prototype as PopupMenuDropdown;\n const makeSelection = target.makeSelection;\n target.makeSelection = function (this: PopupMenuDropdown, item, event): void {\n if (\n event instanceof KeyboardEvent &&\n this.classList.contains('kui-popup-menu') &&\n !item.disabled\n ) {\n item.click();\n return;\n }\n makeSelection.call(this, item, event);\n };\n}\n","interface PopupMenuDropdown extends HTMLElement {\n open: boolean;\n popup?: { active: boolean };\n showMenu(): Promise<void>;\n hideMenu(): Promise<void>;\n}\n\nconst installed = new WeakSet<object>();\n\n/** Restore Web Awesome dismissal listeners after a rapid close/reopen. */\nexport function installPopupMenuLifecycle(prototype: object): void {\n if (installed.has(prototype)) return;\n installed.add(prototype);\n const target = prototype as PopupMenuDropdown;\n const showMenu = target.showMenu;\n const hideMenu = target.hideMenu;\n const hiding = new WeakMap<PopupMenuDropdown, { reopened: boolean }>();\n target.showMenu = function (this: PopupMenuDropdown): Promise<void> {\n const transition = hiding.get(this);\n if (\n transition &&\n this.open &&\n this.popup?.active &&\n this.classList.contains('kui-popup-menu')\n ) {\n // Native showMenu would return early while the old popup is active,\n // leaving its document pointer listener absent during the hide.\n this.popup.active = false;\n transition.reopened = true;\n }\n return showMenu.call(this);\n };\n target.hideMenu = async function (this: PopupMenuDropdown): Promise<void> {\n const scoped = this.classList.contains('kui-popup-menu');\n const transition = { reopened: false };\n if (scoped) hiding.set(this, transition);\n await hideMenu.call(this);\n // WA removes its document listeners before awaiting the hide animation.\n // If Lit coalesces the intervening open request, restore the listeners\n // after hide; an explicit showMenu above has already done so immediately.\n if (\n scoped &&\n hiding.get(this) === transition &&\n this.open &&\n this.isConnected &&\n this.popup?.active &&\n !transition.reopened\n ) {\n this.popup.active = false;\n void this.showMenu();\n }\n if (hiding.get(this) === transition) hiding.delete(this);\n };\n}\n","interface SubmenuItem extends HTMLElement {\n active: boolean;\n}\n\ninterface PopupMenuParentItem extends HTMLElement {\n submenuElement?: HTMLElement;\n submenuOpen: boolean;\n getSubmenuItems(): SubmenuItem[];\n openSubmenu(): Promise<void>;\n closeSubmenu(): Promise<void>;\n}\n\nconst installed = new WeakSet<object>();\n\n/** Preserve a rapid keyboard move past Web Awesome's late first-item focus. */\nexport function installPopupMenuSubmenuFocus(prototype: object): void {\n if (installed.has(prototype)) return;\n installed.add(prototype);\n const target = prototype as PopupMenuParentItem;\n const openSubmenu = target.openSubmenu;\n const closeSubmenu = target.closeSubmenu;\n const submenuOpen = Object.getOwnPropertyDescriptor(prototype, 'submenuOpen');\n if (submenuOpen?.set) {\n Object.defineProperty(prototype, 'submenuOpen', {\n ...submenuOpen,\n set(this: PopupMenuParentItem, value: boolean) {\n const wasOpen = this.submenuOpen;\n submenuOpen.set!.call(this, value);\n // Web Awesome's pointer, click, and ArrowRight paths assign true. A\n // repeated assignment does not schedule updated(), so repair a stale\n // open flag over a hidden submenu at the point of that user action.\n if (\n value &&\n wasOpen &&\n this.submenuElement?.hidden &&\n this.closest('wa-dropdown.kui-popup-menu')\n )\n void this.openSubmenu();\n },\n });\n }\n target.closeSubmenu = async function (\n this: PopupMenuParentItem,\n ): Promise<void> {\n const submenu = this.submenuElement;\n await closeSubmenu.call(this);\n // A new open can start while Web Awesome awaits its hide animation. Its\n // late completion must not leave submenuOpen=true over a hidden submenu.\n if (\n this.submenuOpen &&\n submenu?.hidden &&\n this.isConnected &&\n this.closest('wa-dropdown.kui-popup-menu')\n )\n void this.openSubmenu();\n };\n target.openSubmenu = async function (\n this: PopupMenuParentItem,\n ): Promise<void> {\n const submenu = this.submenuElement;\n if (!this.closest('wa-dropdown.kui-popup-menu') || !submenu)\n return openSubmenu.call(this);\n\n // WA's animation helper never resolves if asked to add an animation class\n // already on the element. A second open while showing needs no new show;\n // a stale hidden popup needs the old show canceled before reopening.\n if (submenu.classList.contains('show')) {\n if (!submenu.hidden) return;\n submenu.classList.remove('show');\n }\n\n let desired: SubmenuItem | undefined;\n const trackFocus = (event: FocusEvent) => {\n const item = event\n .composedPath()\n .find(\n (node): node is SubmenuItem =>\n node instanceof HTMLElement &&\n node.localName === 'wa-dropdown-item' &&\n node.getAttribute('slot') === 'submenu',\n );\n if (item && this.getSubmenuItems().includes(item)) desired = item;\n };\n submenu.addEventListener('focusin', trackFocus);\n try {\n await openSubmenu.call(this);\n } finally {\n submenu.removeEventListener('focusin', trackFocus);\n }\n\n const items = this.getSubmenuItems();\n if (!desired || desired === items[0]) return;\n const selected = desired;\n // Web Awesome queues its first-item focus after the show animation. This\n // timer follows that one, restoring a user's later arrow choice only if\n // the queued focus actually reset it. Pointer/blur/close paths are left alone.\n window.setTimeout(() => {\n if (\n !this.isConnected ||\n !this.submenuOpen ||\n submenu.hidden ||\n document.activeElement !== items[0]\n )\n return;\n items.forEach((item) => (item.active = item === selected));\n selected.focus({ preventScroll: true });\n }, 0);\n };\n}\n","interface SubmenuItem extends HTMLElement {\n submenuElement?: HTMLElement;\n submenuOpen: boolean;\n}\n\ninterface PopupMenuDropdown extends HTMLElement {\n menu?: HTMLElement;\n positionSubmenu(item: SubmenuItem): void;\n}\n\nconst installed = new WeakSet<object>();\nconst phoneWidth = '(max-width: 480px)';\nconst viewportInset = 8;\nconst menuGap = 4;\n\n/** Place a phone-width submenu beside its parent menu in the vertical axis. */\nexport function phoneSubmenuPosition(\n parent: DOMRect,\n submenu: DOMRect,\n viewport: { width: number; height: number },\n rtl: boolean,\n) {\n const width = Math.min(submenu.width, viewport.width - 2 * viewportInset);\n const height = submenu.height;\n const below = Math.max(\n 0,\n viewport.height - parent.bottom - menuGap - viewportInset,\n );\n const above = Math.max(0, parent.top - menuGap - viewportInset);\n const useBelow = height <= below || (height > above && below >= above);\n const availableHeight = useBelow ? below : above;\n const left = rtl ? parent.right - width : parent.left;\n return {\n left: Math.max(\n viewportInset,\n Math.min(left, viewport.width - viewportInset - width),\n ),\n top: useBelow\n ? parent.bottom + menuGap\n : parent.top - menuGap - Math.min(height, availableHeight),\n maxHeight: availableHeight,\n maxWidth: viewport.width - 2 * viewportInset,\n };\n}\n\nfunction clearPhoneStyles(submenu: HTMLElement) {\n for (const property of [\n 'position',\n 'left',\n 'top',\n 'max-width',\n 'max-height',\n 'box-sizing',\n 'overflow-y',\n ])\n submenu.style.removeProperty(property);\n}\n\n/**\n * Web Awesome's horizontal flip can place a submenu over the parent menu on a\n * phone. Its own auto-update loop calls this method on scroll and resize, so\n * override only PopupMenu's narrow placement and leave native menu navigation\n * and selection intact.\n */\nexport function installPopupMenuSubmenuPlacement(prototype: object): void {\n if (installed.has(prototype)) return;\n installed.add(prototype);\n const target = prototype as PopupMenuDropdown;\n const positionSubmenu = target.positionSubmenu;\n target.positionSubmenu = function (this: PopupMenuDropdown, item): void {\n if (!this.classList.contains('kui-popup-menu')) {\n positionSubmenu.call(this, item);\n return;\n }\n const submenu = item.submenuElement;\n if (!window.matchMedia(phoneWidth).matches || !submenu || !this.menu) {\n if (submenu) clearPhoneStyles(submenu);\n positionSubmenu.call(this, item);\n return;\n }\n\n // The opening event starts positioning before Web Awesome unhides the\n // submenu. Measure in the next microtask, after showPopover has run.\n window.queueMicrotask(() => {\n if (\n !this.isConnected ||\n !item.submenuOpen ||\n !window.matchMedia(phoneWidth).matches ||\n !this.menu ||\n !submenu.isConnected\n )\n return;\n const parentItem =\n item.parentElement?.localName === 'wa-dropdown-item'\n ? (item.parentElement as SubmenuItem)\n : undefined;\n const parentMenu = parentItem?.submenuElement ?? this.menu;\n submenu.style.position = 'fixed';\n submenu.style.maxWidth = `calc(100vw - ${2 * viewportInset}px)`;\n submenu.style.maxHeight = 'none';\n submenu.style.boxSizing = 'border-box';\n submenu.style.overflowY = 'auto';\n const placement = phoneSubmenuPosition(\n parentMenu.getBoundingClientRect(),\n submenu.getBoundingClientRect(),\n { width: window.innerWidth, height: window.innerHeight },\n window.getComputedStyle(this).direction === 'rtl',\n );\n submenu.style.left = `${placement.left}px`;\n submenu.style.top = `${placement.top}px`;\n submenu.style.maxHeight = `${placement.maxHeight}px`;\n submenu.style.maxWidth = `${placement.maxWidth}px`;\n submenu.setAttribute(\n 'data-placement',\n placement.top >= parentMenu.getBoundingClientRect().bottom\n ? 'bottom-start'\n : 'top-start',\n );\n });\n };\n}\n","import '@awesome.me/webawesome/dist/components/button/button.js';\nimport '@awesome.me/webawesome/dist/components/divider/divider.js';\nimport '@awesome.me/webawesome/dist/components/dropdown-item/dropdown-item.js';\nimport '@awesome.me/webawesome/dist/components/tooltip/tooltip.js';\n\nimport WaDropdown from '@awesome.me/webawesome/dist/components/dropdown/dropdown.js';\nimport WaDropdownItem from '@awesome.me/webawesome/dist/components/dropdown-item/dropdown-item.js';\n\nimport { installDropdownShowFocus } from './install-dropdown-show-focus.js';\nimport { installHelpTags } from './install-help-tag.js';\nimport { installPopupMenuKeyboard } from './install-popup-menu-keyboard.js';\nimport { installPopupMenuLifecycle } from './install-popup-menu-lifecycle.js';\nimport { installPopupMenuSubmenuFocus } from './install-popup-menu-submenu-focus.js';\nimport { installPopupMenuSubmenuPlacement } from './install-popup-menu-submenu-placement.js';\n\ninstallPopupMenuKeyboard(WaDropdown.prototype);\ninstallPopupMenuLifecycle(WaDropdown.prototype);\ninstallDropdownShowFocus(WaDropdown.prototype);\ninstallPopupMenuSubmenuFocus(WaDropdownItem.prototype);\ninstallPopupMenuSubmenuPlacement(WaDropdown.prototype);\ninstallHelpTags();\n\n/**\n * Marker export for tests and tooling; importing this module registers the\n * Web Awesome elements a `PopupMenu` renders (`wa-dropdown`,\n * `wa-dropdown-item`, `wa-button`, and `wa-divider`) and routes a keyboard\n * choice through the item's click so delegated `data-action`s run.\n */\nexport const popupMenuElementsRegistered = true;\n"]}
@@ -92,7 +92,8 @@ declare function closePopupMenu(menu: PopupMenuElement): void;
92
92
  * `nestedDropdown`) or a `PopupSurface` sizes and insets it as usual. Items
93
93
  * dispatch through delegated `data-action`s; the app owns the commands and any
94
94
  * open-state reaction. Import `@kerfjs/ui/popup-menu/register` once to register
95
- * the Web Awesome elements.
95
+ * the Web Awesome elements. At viewport widths up to 480px, submenus appear
96
+ * above or below their parent menu so their rows do not cover the parent list.
96
97
  */
97
98
  declare function PopupMenu({ text, label, icon, items, placement, caret, disabled, rootAttributes, slot, context, }: PopupMenuProps): SafeHtml;
98
99
 
@@ -1,3 +1,3 @@
1
- export { PopupMenu, closePopupMenu, openPopupMenuAt } from './chunk-ZRWXFDDS.js';
1
+ export { PopupMenu, closePopupMenu, openPopupMenuAt } from './chunk-J3KGJ6P6.js';
2
2
 
3
3
  //# sourceMappingURL=popup-menu.js.map
@@ -162,3 +162,7 @@
162
162
  --kui-catalog-example-align: 0.5rem;
163
163
  margin-inline-start: var(--kui-catalog-example-align);
164
164
  }
165
+
166
+ .kui-catalog-example[data-align="text-trigger"] > wa-dropdown > wa-button {
167
+ margin-inline-start: 0.5rem;
168
+ }
@@ -23,6 +23,11 @@
23
23
  );
24
24
  }
25
25
 
26
+ .kui-content-item--flush {
27
+ padding-block: 0;
28
+ border-block-width: 0;
29
+ }
30
+
26
31
  /* A visible frame for a content item that marks a real distinction: the
27
32
  standard neutral border, same geometry (the border is always reserved). */
28
33
  .kui-content-item--framed {
@@ -42,11 +47,15 @@
42
47
  [data-selected="true"]
43
48
  ) {
44
49
  --kui-content-item-border: var(--kui-color-neutral-border-normal);
45
- --kui-content-item-background: var(--kui-color-neutral-fill-quiet);
50
+ --kui-content-item-background: var(--kui-color-neutral-fill-normal);
46
51
  }
47
52
 
48
53
  .kui-content-item[data-interactive="true"]:active:not([data-disabled="true"]) {
49
- --kui-content-item-background: var(--kui-color-neutral-fill-normal);
54
+ --kui-content-item-background: color-mix(
55
+ in srgb,
56
+ var(--kui-color-neutral-fill-normal) 75%,
57
+ var(--kui-color-neutral-fill-loud)
58
+ );
50
59
  }
51
60
 
52
61
  .kui-content-item[data-interactive="true"][data-selected="true"] {
@@ -21,6 +21,13 @@
21
21
  );
22
22
  }
23
23
 
24
+ .kui-grid[data-auto-fill="true"] {
25
+ grid-template-columns: repeat(
26
+ auto-fill,
27
+ minmax(min(100%, var(--_kui-grid-min-column-width)), 1fr)
28
+ );
29
+ }
30
+
24
31
  /* `fill`: the layout root of a definite-height parent (an app root or a
25
32
  fixed-height frame) takes its full height. Inside a flex layout use `flex`. */
26
33
  .kui-grid[data-fill="true"] {
@@ -48,6 +48,15 @@
48
48
  var(--_kui-popup-row-check-width)
49
49
  );
50
50
  }
51
+ /* Web Awesome's nested submenu owns its item host padding. Move its exposed
52
+ checkmark inside the panel and leave room for the label beside it. */
53
+ .kui-popup-menu
54
+ wa-dropdown-item[slot="submenu"][type="checkbox"]::part(checkmark) {
55
+ margin-inline-start: 0;
56
+ }
57
+ .kui-popup-menu wa-dropdown-item[slot="submenu"][type="checkbox"]::part(label) {
58
+ padding-inline-start: 1em;
59
+ }
51
60
  .kui-popup-menu wa-dropdown-item::part(label) {
52
61
  padding-block: var(--_kui-popup-row-label-padding-block);
53
62
  line-height: var(--_kui-popup-row-label-line-height);
@@ -119,6 +119,9 @@
119
119
  line-height: 1;
120
120
  white-space: nowrap;
121
121
  cursor: pointer;
122
+ /* Web Awesome's native button transition includes color. During a theme
123
+ switch that briefly puts the old text tone on the new filled track. */
124
+ transition-property: background, border, box-shadow;
122
125
  }
123
126
 
124
127
  .kui-segmented-control[data-size="small"] .kui-segmented-control__item {
@@ -1,3 +1,32 @@
1
+ .kui-token-search__field {
2
+ display: grid;
3
+ width: 100%;
4
+ min-width: 0;
5
+ gap: var(--wa-space-2xs, 0.25rem);
6
+ }
7
+
8
+ .kui-token-search__field-label {
9
+ padding-inline: 0.5625rem;
10
+ color: var(--kui-color-neutral-on-quiet, var(--wa-color-text-quiet));
11
+ font-size: var(--kui-font-xs, var(--wa-font-size-xs));
12
+ font-weight: 650;
13
+ letter-spacing: 0.04em;
14
+ line-height: var(--wa-line-height-condensed, 1.2);
15
+ text-transform: uppercase;
16
+ }
17
+
18
+ .kui-token-search__field-required {
19
+ margin-inline-start: 0.15em;
20
+ color: var(--wa-color-danger-on-normal, currentColor);
21
+ }
22
+
23
+ .kui-token-search__field-hint {
24
+ padding-inline: 0.5625rem;
25
+ color: var(--kui-color-text-quiet);
26
+ font-size: var(--kui-font-s);
27
+ line-height: var(--wa-line-height-normal, 1.6);
28
+ }
29
+
1
30
  .kui-token-search {
2
31
  --kui-token-search-background: var(--kui-color-surface);
3
32
  --kui-token-search-border: var(--kui-color-neutral-border-normal);
@@ -85,7 +114,8 @@
85
114
  }
86
115
 
87
116
  .kui-token-search__token button,
88
- .kui-token-search__clear {
117
+ .kui-token-search__clear,
118
+ .kui-token-search__trailing-action {
89
119
  appearance: none;
90
120
  display: inline-grid;
91
121
  padding: 0;
@@ -110,12 +140,15 @@
110
140
  .kui-token-search__token-remove:hover,
111
141
  .kui-token-search__token-remove:focus-visible,
112
142
  .kui-token-search__clear:hover,
113
- .kui-token-search__clear:focus-visible {
143
+ .kui-token-search__clear:focus-visible,
144
+ .kui-token-search__trailing-action:hover,
145
+ .kui-token-search__trailing-action:focus-visible {
114
146
  background: color-mix(in srgb, currentColor 12%, transparent);
115
147
  }
116
148
 
117
149
  .kui-token-search__token button:focus-visible,
118
- .kui-token-search__clear:focus-visible {
150
+ .kui-token-search__clear:focus-visible,
151
+ .kui-token-search__trailing-action:focus-visible {
119
152
  outline: var(--kui-focus-ring);
120
153
  outline-offset: 1px;
121
154
  }
@@ -130,7 +163,8 @@
130
163
  }
131
164
 
132
165
  .kui-token-search__clear,
133
- .kui-token-search__trailing {
166
+ .kui-token-search__trailing,
167
+ .kui-token-search__trailing-action {
134
168
  display: inline-grid;
135
169
  width: 1.5rem;
136
170
  height: var(--kui-token-search-line-size);
@@ -147,6 +181,11 @@
147
181
  grid-column: 4;
148
182
  }
149
183
 
184
+ .kui-token-search__trailing-action {
185
+ grid-column: 4;
186
+ border-radius: var(--kui-radius-pill);
187
+ }
188
+
150
189
  .kui-token-search__suggestions {
151
190
  display: grid;
152
191
  position: absolute;
@@ -178,6 +217,7 @@
178
217
  background: transparent;
179
218
  font: inherit;
180
219
  text-align: start;
220
+ justify-content: flex-start;
181
221
  cursor: pointer;
182
222
  }
183
223
 
@@ -192,7 +232,8 @@
192
232
  }
193
233
 
194
234
  .kui-token-search__clear svg,
195
- .kui-token-search__trailing svg {
235
+ .kui-token-search__trailing svg,
236
+ .kui-token-search__trailing-action svg {
196
237
  width: 0.85rem;
197
238
  height: 0.85rem;
198
239
  }
@@ -213,6 +254,11 @@
213
254
  border-color 0.2s ease;
214
255
  }
215
256
 
257
+ .kui-token-search[data-collapsible="true"][data-expanded="true"][data-fill="true"] {
258
+ width: 100%;
259
+ flex: 1 1 auto;
260
+ }
261
+
216
262
  .kui-token-search[data-collapsible="true"][data-expanded="true"]:has(
217
263
  .kui-token-search__suggestions
218
264
  ) {
@@ -156,6 +156,13 @@
156
156
  border-color 0.2s ease;
157
157
  }
158
158
 
159
+ .kui-toolbar-control-group[data-content="search"]:has(
160
+ > .kui-token-search[data-expanded="true"][data-fill="true"]
161
+ ) {
162
+ width: 100%;
163
+ flex: 1 1 auto;
164
+ }
165
+
159
166
  .kui-toolbar-control-group[data-content="search"]:has(
160
167
  .kui-token-search__suggestions
161
168
  ) {
@@ -165,6 +172,13 @@
165
172
  width: var(--kui-toolbar-group-size, calc(2px + 2.625rem));
166
173
  flex: 0 0 auto;
167
174
  }
175
+
176
+ .kui-toolbar-control-group[data-content="search"]:has(
177
+ > .kui-token-search[data-expanded="false"][data-fill="true"]
178
+ ) {
179
+ width: var(--kui-toolbar-group-size, calc(2px + 2.625rem));
180
+ flex: 0 0 auto;
181
+ }
168
182
  .kui-toolbar-control-group[data-content="text"]
169
183
  > :is(button, wa-button, .kui-toolbar-action-link),
170
184
  .kui-toolbar-control-group[data-content="mixed"]
@@ -669,17 +669,11 @@
669
669
  display: none;
670
670
  }
671
671
 
672
- .kui-workbench:has(
673
- > .kui-workbench__rail--left[data-responsive-overlay-active="true"]
674
- )
675
- > .kui-workbench__center {
672
+ .kui-workbench[data-numeric-overlays~="left"] > .kui-workbench__center {
676
673
  --kui-edge-inset-inline-start: var(--_kui-workbench-safe-inline-start);
677
674
  }
678
675
 
679
- .kui-workbench:has(
680
- > .kui-workbench__rail--right[data-responsive-overlay-active="true"]
681
- )
682
- > .kui-workbench__center {
676
+ .kui-workbench[data-numeric-overlays~="right"] > .kui-workbench__center {
683
677
  --kui-edge-inset-inline-end: var(--_kui-workbench-safe-inline-end);
684
678
  }
685
679
 
@@ -701,21 +695,13 @@
701
695
  background: var(--kui-color-surface);
702
696
  }
703
697
 
704
- .kui-workbench__main:has(
705
- + .kui-workbench__drawer[data-responsive-overlay-active="true"]
706
- ) {
698
+ .kui-workbench[data-numeric-overlays~="drawer"]
699
+ > .kui-workbench__center
700
+ > .kui-workbench__main {
707
701
  --_kui-workbench-content-edge-block-end: var(--_kui-workbench-safe-block-end);
708
702
  }
709
703
 
710
- .kui-workbench[data-overlay-backdrop="true"]:has(
711
- > .kui-workbench__rail[data-responsive-overlay-active="true"]:not(
712
- [data-collapsed="true"]
713
- ),
714
- > .kui-workbench__center
715
- > .kui-workbench__drawer[data-responsive-overlay-active="true"]:not(
716
- [data-collapsed="true"]
717
- )
718
- )
704
+ .kui-workbench[data-overlay-backdrop="true"][data-numeric-overlays~="open"]
719
705
  > .kui-workbench__backdrop {
720
706
  display: block;
721
707
  }
@@ -1024,11 +1010,7 @@
1024
1010
  --_kui-workbench-covered: hidden;
1025
1011
  }
1026
1012
 
1027
- .kui-workbench:has(
1028
- > .kui-workbench__rail[data-responsive-overlay-active="true"]:not(
1029
- [data-collapsed="true"]
1030
- )
1031
- )
1013
+ .kui-workbench[data-numeric-overlays~="rail-open"]
1032
1014
  > :is(.kui-workbench__center, .kui-workbench__restore) {
1033
1015
  --_kui-workbench-covered: hidden;
1034
1016
  }
@@ -60,6 +60,12 @@ interface TokenSearchToken {
60
60
  offset?: number;
61
61
  accessibleLabel?: string;
62
62
  }
63
+ interface TokenSearchTrailingAction {
64
+ icon: SafeHtml;
65
+ label: string;
66
+ action: string;
67
+ id?: string;
68
+ }
63
69
  type TokenSearchEditorAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
64
70
  'data-component'?: never;
65
71
  'data-key'?: never;
@@ -88,10 +94,9 @@ interface TokenSearchFieldBaseProps {
88
94
  tokenPlaceholder?: string;
89
95
  disabled?: boolean;
90
96
  autofocus?: boolean;
97
+ /** Let an expanded collapsible field consume the available inline width. */
98
+ fill?: boolean;
91
99
  leading?: KerfUiContent;
92
- trailing?: KerfUiContent;
93
- /** Standalone field chrome or the inset visual layer of a configured toolbar group. */
94
- presentation?: 'standalone' | 'toolbar-group';
95
100
  editAction?: string;
96
101
  removeAction?: string;
97
102
  clearAction?: string;
@@ -103,6 +108,25 @@ interface TokenSearchFieldBaseProps {
103
108
  /** Native named-slot assignment when composed inside a web component. */
104
109
  slot?: string;
105
110
  }
111
+ type TokenSearchTrailingProps = {
112
+ trailing?: KerfUiContent;
113
+ trailingAction?: never;
114
+ } | {
115
+ trailing?: never;
116
+ trailingAction: TokenSearchTrailingAction;
117
+ };
118
+ type TokenSearchPresentationProps = {
119
+ /** Standalone field chrome or the inset visual layer of a configured toolbar group. */
120
+ presentation?: 'standalone' | 'toolbar-group';
121
+ hint?: never;
122
+ required?: never;
123
+ } | {
124
+ /** Visible form label and optional hint around the full-width standalone control. */
125
+ presentation: 'form-field';
126
+ hint?: string;
127
+ /** Marks the editor required; the app validates its value. */
128
+ required?: boolean;
129
+ };
106
130
  type TokenSearchCollapsibleProps = {
107
131
  /** Allow an empty field to render as one iconic action. */
108
132
  collapsible: true;
@@ -116,15 +140,15 @@ type TokenSearchCollapsibleProps = {
116
140
  expandAction?: never;
117
141
  expandLabel?: never;
118
142
  };
119
- type TokenSearchFieldProps = TokenSearchFieldBaseProps & TokenSearchCollapsibleProps;
143
+ type TokenSearchFieldProps = TokenSearchFieldBaseProps & TokenSearchCollapsibleProps & TokenSearchTrailingProps & TokenSearchPresentationProps;
120
144
  interface TokenSearchFieldValue {
121
145
  query: string;
122
146
  tokens: TokenSearchToken[];
123
147
  }
124
- declare function TokenSearchField({ id, label, query, tokens, model, revision, placeholder, tokenPlaceholder, disabled, autofocus, collapsible, expanded, expandAction, expandLabel, leading, trailing, presentation, editAction, removeAction, clearAction, clearLabel, clearIcon, className, editorAttributes, slot, }: TokenSearchFieldProps): SafeHtml;
148
+ declare function TokenSearchField({ id, label, query, tokens, model, revision, placeholder, tokenPlaceholder, disabled, autofocus, fill, collapsible, expanded, expandAction, expandLabel, leading, trailing, trailingAction, presentation, hint, required, editAction, removeAction, clearAction, clearLabel, clearIcon, className, editorAttributes, slot, }: TokenSearchFieldProps): SafeHtml;
125
149
  /** Read editable text and ordered token offsets from a rendered TokenSearchField editor. */
126
150
  declare function readTokenSearchField(editor: HTMLElement, knownTokens?: readonly TokenSearchToken[]): TokenSearchFieldValue;
127
151
  /** Focus an editor and place its caret at a text offset, skipping atomic token chips. */
128
152
  declare function placeTokenSearchCaret(editor: HTMLElement, offset?: number): void;
129
153
 
130
- export { type TokenSearchEditorAttributes as T, TokenSearchField as a, type TokenSearchFieldProps as b, type TokenSearchFieldValue as c, type TokenSearchModel as d, type TokenSearchModelOptions as e, type TokenSearchResolvedToken as f, type TokenSearchRule as g, type TokenSearchState as h, type TokenSearchSuggestion as i, type TokenSearchToken as j, createTokenSearchModel as k, placeTokenSearchCaret as p, readTokenSearchField as r };
154
+ export { type TokenSearchEditorAttributes as T, TokenSearchField as a, type TokenSearchFieldProps as b, type TokenSearchFieldValue as c, type TokenSearchModel as d, type TokenSearchModelOptions as e, type TokenSearchResolvedToken as f, type TokenSearchRule as g, type TokenSearchState as h, type TokenSearchSuggestion as i, type TokenSearchToken as j, type TokenSearchTrailingAction as k, createTokenSearchModel as l, placeTokenSearchCaret as p, readTokenSearchField as r };