@inglorious/ui 7.2.0 → 7.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inglorious/ui",
|
|
3
|
-
"version": "7.2.
|
|
3
|
+
"version": "7.2.1",
|
|
4
4
|
"description": "A design system for Inglorious Web with render-function components and customizable themes",
|
|
5
5
|
"author": "Matteo Antony Mistretta <antony.mistretta@gmail.com> (https://ingloriouscoderz.it)",
|
|
6
6
|
"license": "MIT",
|
|
@@ -39,6 +39,13 @@
|
|
|
39
39
|
background: var(--iw-input-bg-hover);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
/* The control is focusable so it can be opened from the keyboard. */
|
|
43
|
+
&:focus-visible {
|
|
44
|
+
outline: none;
|
|
45
|
+
border-color: var(--iw-input-border-focus);
|
|
46
|
+
box-shadow: var(--iw-input-shadow-focus);
|
|
47
|
+
}
|
|
48
|
+
|
|
42
49
|
&.iw-combobox-control-open {
|
|
43
50
|
border-color: var(--iw-input-border-focus);
|
|
44
51
|
box-shadow: var(--iw-input-shadow-focus);
|
|
@@ -116,11 +116,18 @@ export const Combobox = {
|
|
|
116
116
|
/**
|
|
117
117
|
* Renders the clickable control element that shows the current selection and toggles the dropdown.
|
|
118
118
|
* Handles placeholder, clear button, and the open/disabled state.
|
|
119
|
+
*
|
|
120
|
+
* The control is the only way into a closed combobox, so it has to be
|
|
121
|
+
* focusable: it was a plain div with a click handler, which meant tabbing
|
|
122
|
+
* skipped the field entirely and none of the keyboard handling was reachable.
|
|
123
|
+
* It keeps focus while the dropdown is open unless a search input takes it.
|
|
119
124
|
* @param {ComboboxProps} props
|
|
120
125
|
* @returns {TemplateResult}
|
|
121
126
|
*/
|
|
122
127
|
renderControl(props) {
|
|
128
|
+
const controlId = props.id ? `${props.id}-control` : undefined
|
|
123
129
|
return html`<div
|
|
130
|
+
id=${controlId ?? ""}
|
|
124
131
|
class="iw-combobox-control ${classMap({
|
|
125
132
|
"iw-combobox-control-open": props.isOpen,
|
|
126
133
|
"iw-combobox-control-disabled": props.isDisabled,
|
|
@@ -129,6 +136,12 @@ export const Combobox = {
|
|
|
129
136
|
Array.isArray(props.selectedValue) &&
|
|
130
137
|
props.selectedValue.length,
|
|
131
138
|
})}"
|
|
139
|
+
role="combobox"
|
|
140
|
+
aria-haspopup="listbox"
|
|
141
|
+
aria-expanded=${props.isOpen ? "true" : "false"}
|
|
142
|
+
aria-controls=${controlId ? `${controlId}-listbox` : ""}
|
|
143
|
+
tabindex=${props.isDisabled ? -1 : 0}
|
|
144
|
+
@keydown=${(event) => handleControlKeyDown(props, event)}
|
|
132
145
|
@click=${() => !props.isDisabled && props.onToggle?.()}
|
|
133
146
|
>
|
|
134
147
|
${when(
|
|
@@ -247,7 +260,9 @@ export const Combobox = {
|
|
|
247
260
|
const filteredOptions = filterOptions(props.options, props.searchTerm)
|
|
248
261
|
|
|
249
262
|
return html`<div
|
|
263
|
+
id=${props.id ? `${props.id}-control-listbox` : ""}
|
|
250
264
|
class="iw-combobox-dropdown"
|
|
265
|
+
role="listbox"
|
|
251
266
|
${ref((el) => trackOutsideClick(props, el))}
|
|
252
267
|
>
|
|
253
268
|
${when(props.isSearchable, () => this.renderSearchInput?.(props))}
|
|
@@ -316,6 +331,9 @@ export const Combobox = {
|
|
|
316
331
|
const isFocused = index === props.focusedIndex
|
|
317
332
|
|
|
318
333
|
return html`<div
|
|
334
|
+
id=${props.id ? `${props.id}-option-${index}` : ""}
|
|
335
|
+
role="option"
|
|
336
|
+
aria-selected=${isSelected ? "true" : "false"}
|
|
319
337
|
class="iw-combobox-dropdown-options-option ${classMap({
|
|
320
338
|
"iw-combobox-dropdown-options-option-selected": isSelected,
|
|
321
339
|
"iw-combobox-dropdown-options-option-focused": isFocused,
|
|
@@ -364,6 +382,31 @@ export const Combobox = {
|
|
|
364
382
|
},
|
|
365
383
|
}
|
|
366
384
|
|
|
385
|
+
/**
|
|
386
|
+
* Opens a closed combobox from the keyboard, and navigates an open one.
|
|
387
|
+
*
|
|
388
|
+
* The control keeps DOM focus whenever the combobox is not searchable — there
|
|
389
|
+
* is no search input to hand focus to — so while open it drives the same
|
|
390
|
+
* navigation handleKeyDown() gives the search input, rather than toggling.
|
|
391
|
+
* @param {ComboboxProps} props
|
|
392
|
+
* @param {KeyboardEvent} event
|
|
393
|
+
*/
|
|
394
|
+
function handleControlKeyDown(props, event) {
|
|
395
|
+
if (props.isDisabled) return
|
|
396
|
+
|
|
397
|
+
if (props.isOpen) {
|
|
398
|
+
handleKeyDown(props, event)
|
|
399
|
+
return
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
if (event.key !== "Enter" && event.key !== " " && event.key !== "ArrowDown") {
|
|
403
|
+
return
|
|
404
|
+
}
|
|
405
|
+
// Space would otherwise scroll the page out from under the dropdown.
|
|
406
|
+
event.preventDefault()
|
|
407
|
+
props.onToggle?.()
|
|
408
|
+
}
|
|
409
|
+
|
|
367
410
|
/**
|
|
368
411
|
* Handle key navigation.
|
|
369
412
|
* @param {ComboboxProps} props
|