@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.
- package/ai/component-catalog.json +28 -12
- package/ai/component-composition.json +21 -3
- package/ai/components/content-item.md +4 -1
- package/ai/components/list.md +4 -2
- package/ai/components/token-search-field.md +3 -0
- package/ai/components/workbench.md +1 -0
- package/ai/public-api-signatures-v1.md +24 -11
- package/ai/webawesome-jsx-signatures-v1.md +1 -1
- package/dist/catalog.d.ts +1 -1
- package/dist/catalog.js +3 -3
- package/dist/catalog.js.map +1 -1
- package/dist/{chunk-UCKKT6KO.js → chunk-2EKHENQK.js} +7 -1
- package/dist/chunk-2EKHENQK.js.map +1 -0
- package/dist/{chunk-RTJNJTG3.js → chunk-5SYE4CCT.js} +42 -5
- package/dist/chunk-5SYE4CCT.js.map +1 -0
- package/dist/{chunk-IA4D5XNT.js → chunk-FJSZYEBM.js} +2 -2
- package/dist/{chunk-IA4D5XNT.js.map → chunk-FJSZYEBM.js.map} +1 -1
- package/dist/{chunk-ZRWXFDDS.js → chunk-J3KGJ6P6.js} +1 -1
- package/dist/{chunk-ZRWXFDDS.js.map → chunk-J3KGJ6P6.js.map} +1 -1
- package/dist/{chunk-7AKGPBCC.js → chunk-NCSWXG7G.js} +8 -4
- package/dist/chunk-NCSWXG7G.js.map +1 -0
- package/dist/{chunk-R75GGNWY.js → chunk-P4UXSYIJ.js} +58 -8
- package/dist/chunk-P4UXSYIJ.js.map +1 -0
- package/dist/{chunk-KFYANKJI.js → chunk-PWQAVNON.js} +3 -3
- package/dist/{chunk-KFYANKJI.js.map → chunk-PWQAVNON.js.map} +1 -1
- package/dist/{chunk-OBAFAH5B.js → chunk-TJK44RQC.js} +33 -8
- package/dist/chunk-TJK44RQC.js.map +1 -0
- package/dist/{chunk-NAPE7WUS.js → chunk-W2AC6Q2A.js} +9 -1
- package/dist/chunk-W2AC6Q2A.js.map +1 -0
- package/dist/collapsible-panel.js +2 -2
- package/dist/content-item.d.ts +7 -3
- package/dist/content-item.js +1 -1
- package/dist/grid.d.ts +5 -1
- package/dist/grid.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +6 -6
- package/dist/list.d.ts +5 -1
- package/dist/list.js +1 -1
- package/dist/popup-menu-register.js +181 -5
- package/dist/popup-menu-register.js.map +1 -1
- package/dist/popup-menu.d.ts +2 -1
- package/dist/popup-menu.js +1 -1
- package/dist/styles/catalog/components/catalog-example.css +4 -0
- package/dist/styles/content-item.css +11 -2
- package/dist/styles/grid.css +7 -0
- package/dist/styles/popup-menu.css +9 -0
- package/dist/styles/segmented-control.css +3 -0
- package/dist/styles/token-search-field.css +51 -5
- package/dist/styles/toolbar-control-group.css +14 -0
- package/dist/styles/workbench.css +7 -25
- package/dist/{token-search-field-DvgFLhLL.d.ts → token-search-field-CVGwDn2y.d.ts} +30 -6
- package/dist/token-search-field.d.ts +1 -1
- package/dist/token-search-field.js +1 -1
- package/dist/token-search-model.d.ts +1 -1
- package/dist/wire-catalog.js +1 -1
- package/dist/wire-content-items.d.ts +3 -1
- package/dist/wire-content-items.js +30 -6
- package/dist/wire-content-items.js.map +1 -1
- package/dist/wire-token-search-fields.d.ts +1 -1
- package/dist/wire-token-search-fields.js +1 -1
- package/dist/wire-workbench.js +1 -1
- package/dist/workbench.js +1 -1
- package/docs/accessibility.md +29 -4
- package/docs/catalog.md +6 -2
- package/docs/component-contract.md +34 -2
- package/docs/component-selection.md +16 -0
- package/docs/layout.md +42 -10
- package/docs/surface-scaffold.md +6 -3
- package/docs/ux-demo.md +1 -0
- package/docs/workbench.md +5 -1
- package/package.json +1 -1
- package/dist/chunk-7AKGPBCC.js.map +0 -1
- package/dist/chunk-NAPE7WUS.js.map +0 -1
- package/dist/chunk-OBAFAH5B.js.map +0 -1
- package/dist/chunk-R75GGNWY.js.map +0 -1
- package/dist/chunk-RTJNJTG3.js.map +0 -1
- 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-
|
|
8
|
+
// src/install-dropdown-show-focus.ts
|
|
9
9
|
var installed = /* @__PURE__ */ new WeakSet();
|
|
10
|
-
|
|
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
|
|
93
|
+
var installed4 = /* @__PURE__ */ new WeakSet();
|
|
26
94
|
function installPopupMenuSubmenuFocus(prototype) {
|
|
27
|
-
if (
|
|
28
|
-
|
|
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":"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","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"]}
|
package/dist/popup-menu.d.ts
CHANGED
|
@@ -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
|
|
package/dist/popup-menu.js
CHANGED
|
@@ -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-
|
|
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:
|
|
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"] {
|
package/dist/styles/grid.css
CHANGED
|
@@ -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
|
|
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
|
|
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-
|
|
705
|
-
|
|
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"]
|
|
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
|
|
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,
|
|
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 };
|