@rcarls/rc-combobox 0.4.2 → 0.6.0
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/CHANGELOG.md +31 -0
- package/README.md +42 -23
- package/dist/{rc-combobox-BfEg1DVi.js → rc-combobox-CbI4E_hd.js} +15 -9
- package/dist/rc-combobox-CbI4E_hd.js.map +1 -0
- package/dist/rc-combobox-define.js +2 -1
- package/dist/rc-combobox-define.js.map +1 -1
- package/dist/rc-combobox.js +1 -1
- package/package.json +5 -4
- package/dist/rc-combobox-BfEg1DVi.js.map +0 -1
- package/dist/types/packages/rc-combobox/src/rc-combobox.test.d.ts +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
# @rcarls/rc-combobox
|
|
2
2
|
|
|
3
|
+
## 0.6.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- ffcbf11: Add adaptive chip-group layouts, native-backed filter chips, and shared
|
|
8
|
+
input-chip rendering. Native-backed chips preserve controlled host state,
|
|
9
|
+
follow form resets when uncontrolled, and accept native link actions. Groups
|
|
10
|
+
restore author-owned chip variants when coordination ends. Keep search input
|
|
11
|
+
chrome inside the search surface and align contextual icon sizes with Material 3.
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Updated dependencies [ffcbf11]
|
|
16
|
+
- Updated dependencies [6683eb9]
|
|
17
|
+
- Updated dependencies [ee7ba6c]
|
|
18
|
+
- Updated dependencies [30eb232]
|
|
19
|
+
- @rcarls/rc-chip-group@0.6.0
|
|
20
|
+
- @rcarls/rc-select@0.6.0
|
|
21
|
+
- @rcarls/rc-common@0.6.0
|
|
22
|
+
- @rcarls/rc-listbox@0.6.0
|
|
23
|
+
|
|
24
|
+
## 0.5.0
|
|
25
|
+
|
|
26
|
+
### Patch Changes
|
|
27
|
+
|
|
28
|
+
- Updated dependencies [4ae2ef0]
|
|
29
|
+
- Updated dependencies [689340c]
|
|
30
|
+
- @rcarls/rc-common@0.5.0
|
|
31
|
+
- @rcarls/rc-listbox@0.5.0
|
|
32
|
+
- @rcarls/rc-select@0.5.0
|
|
33
|
+
|
|
3
34
|
## 0.4.2
|
|
4
35
|
|
|
5
36
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
# `@rcarls/rc-combobox`
|
|
2
2
|
|
|
3
|
-
Editable combobox with filtering and optional allow-create behavior, configured
|
|
3
|
+
Editable combobox with filtering and optional allow-create behavior, configured
|
|
4
|
+
from native option data and following the
|
|
5
|
+
[WAI-ARIA Combobox pattern](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/).
|
|
4
6
|
|
|
5
|
-
Docs:
|
|
7
|
+
Docs:
|
|
8
|
+
[https://richardcarls.github.io/rc-webcomponents/components/rc-combobox](https://richardcarls.github.io/rc-webcomponents/components/rc-combobox).
|
|
6
9
|
|
|
7
10
|
Extends `rc-select` with a text input and wraps a native slotted `<select>`.
|
|
8
11
|
|
|
@@ -44,7 +47,8 @@ import '@rcarls/rc-combobox/define';
|
|
|
44
47
|
## Allow Create
|
|
45
48
|
|
|
46
49
|
Add `allow-create` to show a **"Create 'X'"** option when the typed text has no exact match.
|
|
47
|
-
Selecting it inserts the new option into the native `<select>`, selects it, and
|
|
50
|
+
Selecting it inserts the new option into the native `<select>`, selects it, and
|
|
51
|
+
fires `rc-combobox-create`.
|
|
48
52
|
|
|
49
53
|
```html
|
|
50
54
|
<rc-combobox allow-create placeholder="Add tag">
|
|
@@ -66,7 +70,7 @@ combobox.addEventListener('rc-combobox-create', (event) => {
|
|
|
66
70
|
});
|
|
67
71
|
```
|
|
68
72
|
|
|
69
|
-
### React
|
|
73
|
+
### React: managing options as state
|
|
70
74
|
|
|
71
75
|
Call `preventDefault()` and add the new item to your React state instead. After React renders
|
|
72
76
|
the new `<option>`, set `el.value` in a `useEffect` to select it:
|
|
@@ -103,7 +107,7 @@ useEffect(() => {
|
|
|
103
107
|
}, [options]);
|
|
104
108
|
```
|
|
105
109
|
|
|
106
|
-
### Form usage
|
|
110
|
+
### Form usage: ephemeral options until committed
|
|
107
111
|
|
|
108
112
|
By default, created options are added to the native `<select>` and appear in `FormData` on submit
|
|
109
113
|
but are discarded on page reload. To persist them on submit, track them alongside the option list:
|
|
@@ -113,7 +117,7 @@ const pending = new Set();
|
|
|
113
117
|
|
|
114
118
|
combobox.addEventListener('rc-combobox-create', (event) => {
|
|
115
119
|
pending.add(event.detail.text.trim());
|
|
116
|
-
// Default runs
|
|
120
|
+
// Default runs, so the option is inserted and selected.
|
|
117
121
|
});
|
|
118
122
|
|
|
119
123
|
form.addEventListener('submit', (event) => {
|
|
@@ -129,39 +133,54 @@ form.addEventListener('submit', (event) => {
|
|
|
129
133
|
|
|
130
134
|
**Uncontrolled (default):** set `<option selected>` or the `defaultValue` property for the
|
|
131
135
|
initial value; the component owns selection thereafter. Listen to `rc-select-change` to observe
|
|
132
|
-
changes. `defaultValue` accepts `string | string[]` and has no HTML attribute form
|
|
136
|
+
changes. `defaultValue` accepts `string | string[]` and has no HTML attribute form; set it as a
|
|
133
137
|
JS property.
|
|
134
138
|
|
|
135
139
|
**Controlled:** write `el.value` (the property) to drive selection programmatically. Writes are
|
|
136
|
-
silent
|
|
140
|
+
silent, so no `rc-select-change` is dispatched. Update `el.value` in response to `rc-select-change`
|
|
137
141
|
to keep external state in sync.
|
|
138
142
|
|
|
139
143
|
```js
|
|
140
|
-
combobox.value = 'banana';
|
|
141
|
-
combobox.value = ['apple', 'cherry'];
|
|
144
|
+
combobox.value = 'banana'; // single
|
|
145
|
+
combobox.value = ['apple', 'cherry']; // multiple
|
|
142
146
|
```
|
|
143
147
|
|
|
144
148
|
For `allow-create`, the same split applies to options:
|
|
145
149
|
|
|
146
|
-
- **Uncontrolled options:** let the default behavior add the new `<option>` to
|
|
147
|
-
|
|
148
|
-
|
|
150
|
+
- **Uncontrolled options:** let the default behavior add the new `<option>` to
|
|
151
|
+
the native `<select>`.
|
|
152
|
+
- **Controlled options:** call `event.preventDefault()` on
|
|
153
|
+
`rc-combobox-create` and manage `<option>` elements yourself (for example, in
|
|
154
|
+
React state), then set `el.value` to include the new value.
|
|
149
155
|
|
|
150
156
|
## API
|
|
151
157
|
|
|
152
|
-
| Property
|
|
153
|
-
|
|
|
154
|
-
| `allowCreate`
|
|
155
|
-
| `filterStrategy` | `'prefix' \| 'contains' \| function` | Controls option filtering.
|
|
156
|
-
| `
|
|
157
|
-
| `
|
|
158
|
+
| Property | Type | Description |
|
|
159
|
+
| ---------------- | ------------------------------------ | -------------------------------------------------------------------------- |
|
|
160
|
+
| `allowCreate` | `boolean` | Shows a create option for unmatched input. |
|
|
161
|
+
| `filterStrategy` | `'prefix' \| 'contains' \| function` | Controls option filtering. |
|
|
162
|
+
| `open` | `boolean` | Inherited from `rc-select`; reflects whether the popup is open. |
|
|
163
|
+
| `multiple` | `boolean` | Inherited from `rc-select`; enables multiple selection and chip rendering. |
|
|
164
|
+
| `disabled` | `boolean` | Inherited from `rc-select`; disables the input and popup trigger. |
|
|
165
|
+
| `placeholder` | `string` | Inherited from `rc-select`; input placeholder when no value is selected. |
|
|
166
|
+
| `display` | `'auto' \| 'chips' \| 'compact'` | Inherited from `rc-select`; controls multiple-value presentation. |
|
|
167
|
+
| `value` | `string \| string[]` | Inherited from `rc-select`; live selection. Host writes are silent. |
|
|
168
|
+
| `defaultValue` | `string \| string[] \| undefined` | Inherited JS-only initial value for uncontrolled usage. |
|
|
169
|
+
| `options` | `ListboxOption[] \| undefined` | Inherited JS-only option-data override. |
|
|
170
|
+
| `selectedValues` | `string[]` | Inherited read-only snapshot of selected values. |
|
|
171
|
+
|
|
172
|
+
The inherited `openPopup()` and `closePopup()` methods control the popup
|
|
173
|
+
imperatively. Like other host-driven writes, these calls do not dispatch a
|
|
174
|
+
selection-change event.
|
|
158
175
|
|
|
159
176
|
## Events
|
|
160
177
|
|
|
161
|
-
| Event
|
|
162
|
-
|
|
|
163
|
-
| `rc-combobox-create` | `{ text: string }`
|
|
164
|
-
| `rc-select-change`
|
|
178
|
+
| Event | Detail | Description |
|
|
179
|
+
| -------------------- | ------------------------------- | ------------------------------------------------------- |
|
|
180
|
+
| `rc-combobox-create` | `{ text: string }` | Cancelable event fired before a new option is inserted. |
|
|
181
|
+
| `rc-select-change` | `{ value: string \| string[] }` | Inherited selection-change event. |
|
|
182
|
+
| `rc-select-open` | none | Inherited event fired when the popup opens. |
|
|
183
|
+
| `rc-select-close` | none | Inherited event fired when the popup closes. |
|
|
165
184
|
|
|
166
185
|
## Accessibility
|
|
167
186
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { css as p, nothing as
|
|
1
|
+
import { css as p, nothing as u, html as d } from "lit";
|
|
2
2
|
import { property as h, query as b, state as g } from "lit/decorators.js";
|
|
3
3
|
import { RCSelect as v } from "@rcarls/rc-select";
|
|
4
4
|
const f = p`
|
|
@@ -42,7 +42,15 @@ const f = p`
|
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
[part='chips'] {
|
|
46
|
+
flex: 0 1 auto;
|
|
47
|
+
max-inline-size: 100%;
|
|
48
|
+
min-inline-size: 0;
|
|
49
|
+
--rc-chip-group-column-gap: var(--rc-combobox-gap, var(--rc-control-gap, 0.25em));
|
|
50
|
+
--rc-chip-group-row-gap: 0;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/* Input-chip chrome; rc-chip keeps the native button as the removal action. */
|
|
46
54
|
[part='chip'] {
|
|
47
55
|
display: inline-flex;
|
|
48
56
|
align-items: center;
|
|
@@ -71,7 +79,7 @@ const f = p`
|
|
|
71
79
|
}
|
|
72
80
|
}
|
|
73
81
|
|
|
74
|
-
/* Decorative × icon inside the chip — no interaction, aria-hidden */
|
|
82
|
+
/* Decorative × icon inside the chip — no interaction, aria-hidden. */
|
|
75
83
|
[part='chip-remove'] {
|
|
76
84
|
display: inline-flex;
|
|
77
85
|
align-items: center;
|
|
@@ -306,9 +314,7 @@ const l = class l extends v {
|
|
|
306
314
|
}
|
|
307
315
|
}
|
|
308
316
|
_focusLastChipRemove() {
|
|
309
|
-
const t =
|
|
310
|
-
this.renderRoot.querySelectorAll('button[part~="chip"]')
|
|
311
|
-
);
|
|
317
|
+
const t = this._$chipButtons();
|
|
312
318
|
t[t.length - 1]?.focus();
|
|
313
319
|
}
|
|
314
320
|
get _inputPlaceholder() {
|
|
@@ -316,9 +322,9 @@ const l = class l extends v {
|
|
|
316
322
|
}
|
|
317
323
|
render() {
|
|
318
324
|
const t = this.multiple && this._selectedValues.size > 0;
|
|
319
|
-
return
|
|
325
|
+
return d`
|
|
320
326
|
<div id="anchor" part="anchor" @click=${this._handleAnchorClick}>
|
|
321
|
-
${t ? this._renderChips() :
|
|
327
|
+
${t ? this._renderChips() : u}
|
|
322
328
|
|
|
323
329
|
<input
|
|
324
330
|
id="trigger"
|
|
@@ -395,4 +401,4 @@ o([
|
|
|
395
401
|
export {
|
|
396
402
|
r as R
|
|
397
403
|
};
|
|
398
|
-
//# sourceMappingURL=rc-combobox-
|
|
404
|
+
//# sourceMappingURL=rc-combobox-CbI4E_hd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rc-combobox-CbI4E_hd.js","sources":["../src/rc-combobox.styles.ts","../src/rc-combobox.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const comboboxStyles = css`\n :host {\n display: inline-block;\n }\n\n #anchor {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: var(--rc-combobox-gap, var(--rc-control-gap, 0.25em));\n min-block-size: var(--rc-combobox-control-block-size, var(--rc-control-block-size, auto));\n padding: var(--rc-combobox-padding-block, var(--rc-control-padding-block, 1px))\n var(--rc-combobox-padding-inline, var(--rc-control-padding-inline, 4px));\n min-width: 8em;\n cursor: text;\n border: var(\n --rc-combobox-border,\n var(--rc-border, 1px solid var(--rc-border-color, ButtonBorder))\n );\n border-radius: var(\n --rc-combobox-radius,\n var(--rc-control-radius, var(--rc-radius-sm, 0.125em))\n );\n background: var(--rc-field, Field);\n color: var(--rc-field-text, FieldText);\n font-family: var(--rc-font-family, inherit);\n font-size: var(--rc-font-size, inherit);\n line-height: var(--rc-line-height, normal);\n transition:\n background-color var(--rc-motion-duration, 120ms),\n border-color var(--rc-motion-duration, 120ms),\n box-shadow var(--rc-motion-duration, 120ms);\n\n /* Focus ring — anchor shows the ring when the internal input is focused */\n outline: none;\n &:focus-within {\n outline: var(--rc-focus-ring, auto);\n outline-offset: var(--rc-focus-ring-offset, 0);\n }\n }\n\n [part='chips'] {\n flex: 0 1 auto;\n max-inline-size: 100%;\n min-inline-size: 0;\n --rc-chip-group-column-gap: var(--rc-combobox-gap, var(--rc-control-gap, 0.25em));\n --rc-chip-group-row-gap: 0;\n }\n\n /* Input-chip chrome; rc-chip keeps the native button as the removal action. */\n [part='chip'] {\n display: inline-flex;\n align-items: center;\n gap: var(--rc-combobox-chip-gap, calc(var(--rc-control-gap, 0.25em) * 0.8));\n padding: var(--rc-combobox-chip-padding-block, 0.1em)\n var(--rc-combobox-chip-padding-inline, 0.3em);\n border: var(\n --rc-combobox-chip-border,\n var(--rc-border, 1px solid var(--rc-border-color, ButtonBorder))\n );\n border-radius: var(--rc-combobox-chip-radius, var(--rc-radius-md, 0.25em));\n background: var(--rc-button-bg, ButtonFace);\n color: var(--rc-button-text, ButtonText);\n font: inherit;\n font-size: 0.875em;\n cursor: pointer;\n\n &:hover {\n background: var(--rc-highlight, Highlight);\n color: var(--rc-highlight-text, HighlightText);\n }\n\n &:focus-visible {\n outline: var(--rc-focus-ring, auto);\n outline-offset: var(--rc-focus-ring-offset, 0);\n }\n }\n\n /* Decorative × icon inside the chip — no interaction, aria-hidden. */\n [part='chip-remove'] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 1em;\n font-size: 0.85em;\n pointer-events: none;\n }\n\n #trigger {\n flex: 1;\n min-width: 0;\n border: none;\n background: transparent;\n color: inherit;\n font: inherit;\n outline: none;\n padding: 0;\n cursor: text;\n }\n\n #trigger::placeholder {\n color: var(--rc-text-disabled, GrayText);\n }\n\n #toggle {\n flex-shrink: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n inline-size: var(--rc-combobox-toggle-size, 1.1em);\n border: none;\n background: transparent;\n color: inherit;\n cursor: default;\n font: inherit;\n\n &:focus-visible {\n outline: var(--rc-focus-ring, auto);\n outline-offset: var(--rc-focus-ring-offset, 0);\n }\n }\n\n /* Hide the default slot — visually suppresses the slotted native <select> */\n slot:not([name]) {\n display: none;\n }\n\n /* Listbox popup — positioned by AnchorController via adoptedStyleSheets */\n rc-listbox {\n max-height: var(--rc-combobox-max-height, 20em);\n overflow-y: auto;\n background: var(--rc-surface, Canvas);\n border: var(\n --rc-combobox-listbox-border,\n var(--rc-border, 1px solid var(--rc-border-color, ButtonBorder))\n );\n border-radius: var(--rc-combobox-listbox-radius, var(--rc-control-radius, 0));\n box-shadow: var(\n --rc-combobox-shadow,\n var(--rc-shadow, 0 2px 8px color-mix(in srgb, CanvasText 15%, transparent))\n );\n color: var(--rc-field-text, FieldText);\n padding-block: var(\n --rc-combobox-listbox-padding-block,\n var(--rc-control-padding-block, 0.25em)\n );\n --rc-listbox-option-gap: var(--rc-item-gap, 0.4em);\n --rc-listbox-option-padding-block: var(--rc-item-padding-block, 0.3em);\n --rc-listbox-option-padding-inline: var(--rc-item-padding-inline, 0.75em);\n --rc-listbox-hover-bg: var(--rc-highlight, Highlight);\n --rc-listbox-hover-color: var(--rc-highlight-text, HighlightText);\n --rc-listbox-active-bg: var(--rc-highlight, Highlight);\n --rc-listbox-active-color: var(--rc-highlight-text, HighlightText);\n --rc-listbox-selected-bg: var(--rc-highlight, Highlight);\n --rc-listbox-selected-color: var(--rc-highlight-text, HighlightText);\n --rc-listbox-disabled-opacity: var(--rc-disabled-opacity, 0.5);\n\n &:not(:popover-open) {\n display: none;\n }\n }\n\n rc-listbox [part~='option'][hidden] {\n display: none;\n }\n\n rc-listbox [part~='option'][data-active]:not([aria-disabled='true']) {\n outline: var(--rc-focus-ring, 2px solid var(--rc-accent, Highlight));\n outline-offset: -2px;\n }\n\n rc-listbox [part~='option'][aria-disabled='true'] {\n cursor: not-allowed;\n }\n\n rc-listbox [part~='option-checkmark'] {\n flex-shrink: 0;\n width: 1em;\n text-align: center;\n font-size: 0.85em;\n visibility: hidden;\n }\n\n rc-listbox [part~='option'][aria-selected='true'] [part~='option-checkmark'] {\n visibility: visible;\n }\n\n rc-listbox [part~='create-option'] {\n font-style: italic;\n border-top: 1px solid var(--rc-border-color, ButtonBorder);\n margin-top: 0.25em;\n padding-top: 0.3em;\n }\n`;\n\nexport default comboboxStyles;\n","import { html, nothing } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\n\nimport { RCSelect } from '@rcarls/rc-select';\nimport type { FilterStrategy, RCListboxChangeEvent } from '@rcarls/rc-listbox';\n\nimport { comboboxStyles } from './rc-combobox.styles.js';\n\nexport interface RCComboboxCreateEvent {\n /** The text typed by the user that didn't match any existing option. */\n text: string;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'rc-combobox': RCCombobox;\n }\n}\n\n/**\n * Editable combobox with filtering and optional allow-create behavior, configured from\n * native option data and following the WAI-ARIA Combobox pattern.\n *\n * Extends `rc-select` by replacing the trigger `<div>` with a text `<input>`\n * and adding: live filtering of the listbox, keyboard navigation from input,\n * and an optional \"Create '{text}'\" option for new entries.\n *\n * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-combobox rc-combobox docs}\n * @see {@link https://www.w3.org/WAI/ARIA/apg/patterns/combobox/ WAI-ARIA Combobox pattern}\n *\n * @slot - Required. A native `<select>` element for form submission.\n * @slot toggle-icon - Optional. Replaces the default chevron icon.\n *\n * @fires rc-select-change - Inherited selection change event.\n * @fires rc-combobox-create - When the \"Create\" option is activated.\n * `detail: { text: string }`. Cancelable — call `preventDefault()` to stop\n * the default insertion of the new option.\n *\n * @csspart anchor - Outer container (includes chips + input + toggle).\n * @csspart chips - The chip group container (multiple mode).\n * @csspart chip - Individual chip (multiple mode).\n * @csspart chip-label - Text label inside a chip.\n * @csspart chip-remove - Remove button inside a chip.\n * @csspart input - The text input element.\n * @csspart toggle - The chevron toggle button.\n * @csspart listbox - The `<rc-listbox>` popup element.\n *\n * @attr allow-create - When present, shows a \"Create 'X'\" option for unmatched input.\n * @attr filter-strategy - How option labels are matched against typed input: `'contains'`\n * (default), `'prefix'`, or a custom predicate set via the `filterStrategy` JS property.\n *\n * @cssprop [--rc-combobox-max-height=20em] - Maximum popup height.\n * @cssprop [--rc-combobox-control-block-size=var(--rc-control-block-size)] - Anchor block size.\n * @cssprop [--rc-combobox-padding-block=calc(var(--rc-control-padding-block) / 2)] - Anchor block-axis padding.\n * @cssprop [--rc-combobox-padding-inline=calc(var(--rc-control-padding-inline) / 2)] - Anchor inline-axis padding.\n * @cssprop [--rc-combobox-gap=var(--rc-control-gap)] - Gap between chips, input, and toggle.\n * @cssprop [--rc-combobox-radius=var(--rc-control-radius)] - Anchor border radius.\n * @cssprop [--rc-combobox-border=var(--rc-border)] - Anchor border.\n * @cssprop [--rc-combobox-listbox-radius=var(--rc-control-radius)] - Popup listbox border radius.\n * @cssprop [--rc-combobox-listbox-border=var(--rc-border)] - Popup listbox border.\n * @cssprop [--rc-combobox-shadow=var(--rc-shadow)] - Popup listbox box shadow.\n * @cssprop [--rc-combobox-listbox-padding-block=var(--rc-control-padding-block)] - Popup listbox block padding.\n * @cssprop [--rc-combobox-chip-radius=var(--rc-radius-md)] - Multi-select chip border radius.\n * @cssprop [--rc-combobox-chip-padding-block=0.1em] - Multi-select chip block-axis padding.\n * @cssprop [--rc-combobox-chip-padding-inline=0.3em] - Multi-select chip inline-axis padding.\n * @cssprop [--rc-combobox-chip-gap=calc(var(--rc-control-gap, 0.25em) * 0.8)] - Gap between chip\n * label and remove icon.\n * @cssprop [--rc-combobox-chip-border=var(--rc-border)] - Multi-select chip border.\n * @cssprop [--rc-combobox-toggle-size=1.1em] - Inline size of the toggle button's icon area.\n */\nexport class RCCombobox extends RCSelect {\n static override styles = comboboxStyles;\n\n /** When set, shows a \"Create '{text}'\" option for text that has no exact match. */\n @property({ type: Boolean, attribute: 'allow-create' })\n allowCreate = false;\n\n /**\n * How option labels are matched against typed input.\n *\n * - Forwarded to the internal `rc-listbox`.\n * - Defaults to `'contains'` (substring).\n * - Set to `'prefix'` for starts-with matching, or\n * - Pass a custom `(label, query) => boolean` predicate.\n *\n * Function values are JS-only; string values may be set via the `filter-strategy` attribute.\n */\n @property({ attribute: 'filter-strategy', reflect: false })\n filterStrategy: FilterStrategy = 'contains';\n\n @query('#trigger')\n protected override _$trigger!: HTMLInputElement;\n\n @state()\n private _filterText = '';\n\n // Guard against _handleInputFocus re-opening the popup immediately after close.\n private _closingPopup = false;\n\n override openPopup() {\n super.openPopup();\n this._$listbox?.filterOptions(this._filterText);\n }\n\n override closePopup(_returnFocus = true) {\n this._filterText = '';\n this._$listbox?.clearFilter();\n this._$listbox?.setCreateOption(null);\n this._closingPopup = true;\n\n super.closePopup(false);\n\n // Deferred past any native focus-return from hidePopover() in Firefox\n setTimeout(() => {\n this._closingPopup = false;\n }, 0);\n }\n\n private _handleInput(e: InputEvent) {\n this._filterText = (e.target as HTMLInputElement).value;\n\n if (!this.open && this._filterText) {\n this.openPopup();\n }\n\n this._$listbox?.filterOptions(this._filterText);\n this._updateCreateOption();\n\n if (this._$listbox?.navigableItems.length) {\n this._activeDescendantCtrl.navigateToFirst();\n } else {\n this._activeDescendantCtrl.clear();\n }\n }\n\n private _handleInputFocus() {\n if (!this.open && !this._closingPopup) {\n this.openPopup();\n }\n }\n\n private _handleToggleClick(e: MouseEvent) {\n e.stopPropagation();\n\n if (this.open) {\n this.closePopup();\n } else {\n this.openPopup();\n this._$trigger?.focus();\n }\n }\n\n private _handleAnchorClick(e: MouseEvent) {\n const $target = e.target as HTMLElement;\n\n if (\n $target.closest('[part~=\"chip\"]') ||\n ($target as HTMLElement & { id?: string }).id === 'toggle'\n ) {\n return;\n }\n\n this._$trigger?.focus();\n }\n\n private _updateCreateOption() {\n if (!this.allowCreate || !this._filterText.trim()) {\n this._$listbox?.setCreateOption(null);\n\n return;\n }\n\n const trimmed = this._filterText.trim().toLowerCase();\n const hasExact =\n this._$listbox?.allOptions.some((o) => o.label.toLowerCase() === trimmed) ?? false;\n\n this._$listbox?.setCreateOption(hasExact ? null : this._filterText.trim());\n }\n\n protected override _handleListboxChange(e: CustomEvent) {\n const detail = e.detail as RCListboxChangeEvent;\n\n if (detail.reason === 'action' && detail.action === 'create') {\n e.stopPropagation();\n void this._activateCreate(this._filterText.trim());\n\n return;\n }\n\n super._handleListboxChange(e);\n\n if (!this.multiple) {\n this._syncInputToSelection();\n } else {\n this._filterText = '';\n\n if (this._$trigger) {\n this._$trigger.value = '';\n }\n\n this._$listbox?.clearFilter();\n this._updateCreateOption();\n }\n }\n\n private async _activateCreate(text: string) {\n if (!text) {\n return;\n }\n\n const createEvent = new CustomEvent<RCComboboxCreateEvent>('rc-combobox-create', {\n bubbles: true,\n composed: true,\n cancelable: true,\n detail: { text },\n });\n\n if (!this.dispatchEvent(createEvent)) {\n return;\n }\n\n this._addOption({ value: text, label: text });\n\n if (this.multiple) {\n this._$listbox?.toggleOption(text);\n this._filterText = '';\n\n if (this._$trigger) {\n this._$trigger.value = '';\n }\n\n this._$listbox?.clearFilter();\n this._$listbox?.setCreateOption(null);\n\n return;\n }\n\n this._applySelection([text]);\n this._syncInputToSelection();\n this.closePopup(true);\n this._dispatchChange();\n }\n\n override set value(value: string | string[] | undefined) {\n super.value = value;\n this._syncInputToSelection();\n }\n\n override get value(): string | string[] {\n return super.value;\n }\n\n private _syncInputToSelection(): void {\n if (this.multiple) {\n return;\n }\n\n const value = this.selectedValues[0];\n const label = value ? this._labelFor(value) : '';\n\n this._filterText = label;\n\n if (this._$trigger) {\n this._$trigger.value = label;\n }\n }\n\n private _handleInputKeyDown(e: KeyboardEvent) {\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n\n if (!this.open) {\n this.openPopup();\n this._activeDescendantCtrl.navigateToFirst();\n } else {\n this._activeDescendantCtrl.navigate(1);\n }\n\n break;\n\n case 'ArrowUp':\n e.preventDefault();\n\n if (this.open) {\n this._activeDescendantCtrl.navigate(-1);\n }\n\n break;\n\n case 'Home':\n if (this.open) {\n e.preventDefault();\n\n this._activeDescendantCtrl.navigateToFirst();\n }\n break;\n\n case 'End':\n if (this.open) {\n e.preventDefault();\n\n this._activeDescendantCtrl.navigateToLast();\n }\n break;\n\n case 'Enter': {\n e.preventDefault();\n\n const active = this._activeDescendantCtrl.activeItem;\n\n if (active) {\n active.dispatchEvent(\n new PointerEvent('pointerdown', { bubbles: true, cancelable: true }),\n );\n } else if (this.open && this._$listbox?.navigableItems.length) {\n const $first = this._$listbox.navigableItems[0];\n\n $first?.dispatchEvent(\n new PointerEvent('pointerdown', { bubbles: true, cancelable: true }),\n );\n }\n\n break;\n }\n\n case 'Tab':\n if (this.open) {\n const $first = this._$listbox?.navigableItems[0];\n\n if ($first) {\n $first.dispatchEvent(\n new PointerEvent('pointerdown', { bubbles: true, cancelable: true }),\n );\n }\n\n this.closePopup(false);\n }\n\n break;\n\n case 'Escape':\n e.preventDefault();\n this._filterText = '';\n\n if (this._$trigger) {\n this._$trigger.value = '';\n }\n\n this.closePopup();\n break;\n\n case 'Backspace':\n if (this._filterText === '' && this.multiple && this._selectedValues.size > 0) {\n e.preventDefault();\n this._focusLastChipRemove();\n }\n\n break;\n\n case 'ArrowLeft':\n if (\n (e.target as HTMLInputElement).selectionStart === 0 &&\n this.multiple &&\n this._selectedValues.size > 0\n ) {\n e.preventDefault();\n this._focusLastChipRemove();\n }\n\n break;\n }\n }\n\n private _focusLastChipRemove() {\n const $buttons = this._$chipButtons();\n\n $buttons[$buttons.length - 1]?.focus();\n }\n\n private get _inputPlaceholder(): string {\n if (this.multiple && this._selectedValues.size > 0) {\n return '';\n }\n\n return this.placeholder;\n }\n\n protected override render() {\n const showChips = this.multiple && this._selectedValues.size > 0;\n\n return html`\n <div id=\"anchor\" part=\"anchor\" @click=${this._handleAnchorClick}>\n ${showChips ? this._renderChips() : nothing}\n\n <input\n id=\"trigger\"\n part=\"input\"\n type=\"text\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-expanded=${this.open ? 'true' : 'false'}\n aria-controls=\"listbox\"\n aria-autocomplete=\"list\"\n ?disabled=${this.disabled}\n placeholder=${this._inputPlaceholder}\n .value=${this._filterText}\n autocomplete=\"off\"\n spellcheck=\"false\"\n @input=${this._handleInput}\n @keydown=${this._handleInputKeyDown}\n @focus=${this._handleInputFocus}\n />\n\n <button\n id=\"toggle\"\n type=\"button\"\n part=\"toggle\"\n aria-hidden=\"true\"\n tabindex=\"-1\"\n @click=${this._handleToggleClick}\n >\n <slot name=\"toggle-icon\">\n <svg\n width=\"10\"\n height=\"6\"\n viewBox=\"0 0 10 6\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <polyline points=\"1,1 5,5 9,1\" />\n </svg>\n </slot>\n </button>\n </div>\n\n <rc-listbox\n id=\"listbox\"\n part=\"listbox\"\n popover=\"manual\"\n ?multiple=${this.multiple}\n checkmark\n .filterStrategy=${this.filterStrategy}\n @rc-listbox-change=${this._handleListboxChange}\n ></rc-listbox>\n\n <slot @slotchange=${this._handleSelectSlotChange}></slot>\n `;\n }\n}\n\nexport default RCCombobox;\n"],"names":["comboboxStyles","css","_RCCombobox","RCSelect","_returnFocus","e","$target","trimmed","hasExact","o","detail","text","createEvent","value","label","active","$first","$buttons","showChips","html","nothing","RCCombobox","__decorateClass","property","query","state"],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import "@rcarls/rc-listbox/define";
|
|
2
|
-
import
|
|
2
|
+
import "@rcarls/rc-chip-group/define";
|
|
3
|
+
import { R as o } from "./rc-combobox-CbI4E_hd.js";
|
|
3
4
|
customElements.get("rc-combobox") || customElements.define("rc-combobox", o);
|
|
4
5
|
export {
|
|
5
6
|
o as RCCombobox
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rc-combobox-define.js","sources":["../src/define.ts"],"sourcesContent":["import '@rcarls/rc-listbox/define';\nimport { RCCombobox } from './index.js';\n\ncustomElements.get('rc-combobox') || customElements.define('rc-combobox', RCCombobox);\n\nexport * from './index.js';\n"],"names":["RCCombobox"],"mappings":"
|
|
1
|
+
{"version":3,"file":"rc-combobox-define.js","sources":["../src/define.ts"],"sourcesContent":["import '@rcarls/rc-listbox/define';\nimport '@rcarls/rc-chip-group/define';\nimport { RCCombobox } from './index.js';\n\ncustomElements.get('rc-combobox') || customElements.define('rc-combobox', RCCombobox);\n\nexport * from './index.js';\n"],"names":["RCCombobox"],"mappings":";;;AAIA,eAAe,IAAI,aAAa,KAAK,eAAe,OAAO,eAAeA,CAAU;"}
|
package/dist/rc-combobox.js
CHANGED
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.6.0",
|
|
7
7
|
"description": "Editable combobox with filtering and optional allow-create behavior, configured from native option data.",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
@@ -45,9 +45,10 @@
|
|
|
45
45
|
"test:browser:firefox": "vitest --run --project=firefox"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@rcarls/rc-
|
|
49
|
-
"@rcarls/rc-
|
|
50
|
-
"@rcarls/rc-
|
|
48
|
+
"@rcarls/rc-chip-group": "0.6.0",
|
|
49
|
+
"@rcarls/rc-common": "0.6.0",
|
|
50
|
+
"@rcarls/rc-listbox": "0.6.0",
|
|
51
|
+
"@rcarls/rc-select": "0.6.0"
|
|
51
52
|
},
|
|
52
53
|
"devDependencies": {
|
|
53
54
|
"@custom-elements-manifest/analyzer": "0.11.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rc-combobox-BfEg1DVi.js","sources":["../src/rc-combobox.styles.ts","../src/rc-combobox.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const comboboxStyles = css`\n :host {\n display: inline-block;\n }\n\n #anchor {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: var(--rc-combobox-gap, var(--rc-control-gap, 0.25em));\n min-block-size: var(--rc-combobox-control-block-size, var(--rc-control-block-size, auto));\n padding: var(--rc-combobox-padding-block, var(--rc-control-padding-block, 1px))\n var(--rc-combobox-padding-inline, var(--rc-control-padding-inline, 4px));\n min-width: 8em;\n cursor: text;\n border: var(\n --rc-combobox-border,\n var(--rc-border, 1px solid var(--rc-border-color, ButtonBorder))\n );\n border-radius: var(\n --rc-combobox-radius,\n var(--rc-control-radius, var(--rc-radius-sm, 0.125em))\n );\n background: var(--rc-field, Field);\n color: var(--rc-field-text, FieldText);\n font-family: var(--rc-font-family, inherit);\n font-size: var(--rc-font-size, inherit);\n line-height: var(--rc-line-height, normal);\n transition:\n background-color var(--rc-motion-duration, 120ms),\n border-color var(--rc-motion-duration, 120ms),\n box-shadow var(--rc-motion-duration, 120ms);\n\n /* Focus ring — anchor shows the ring when the internal input is focused */\n outline: none;\n &:focus-within {\n outline: var(--rc-focus-ring, auto);\n outline-offset: var(--rc-focus-ring-offset, 0);\n }\n }\n\n /* Chips — the whole chip is the remove button for a larger touch target */\n [part='chip'] {\n display: inline-flex;\n align-items: center;\n gap: var(--rc-combobox-chip-gap, calc(var(--rc-control-gap, 0.25em) * 0.8));\n padding: var(--rc-combobox-chip-padding-block, 0.1em)\n var(--rc-combobox-chip-padding-inline, 0.3em);\n border: var(\n --rc-combobox-chip-border,\n var(--rc-border, 1px solid var(--rc-border-color, ButtonBorder))\n );\n border-radius: var(--rc-combobox-chip-radius, var(--rc-radius-md, 0.25em));\n background: var(--rc-button-bg, ButtonFace);\n color: var(--rc-button-text, ButtonText);\n font: inherit;\n font-size: 0.875em;\n cursor: pointer;\n\n &:hover {\n background: var(--rc-highlight, Highlight);\n color: var(--rc-highlight-text, HighlightText);\n }\n\n &:focus-visible {\n outline: var(--rc-focus-ring, auto);\n outline-offset: var(--rc-focus-ring-offset, 0);\n }\n }\n\n /* Decorative × icon inside the chip — no interaction, aria-hidden */\n [part='chip-remove'] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 1em;\n font-size: 0.85em;\n pointer-events: none;\n }\n\n #trigger {\n flex: 1;\n min-width: 0;\n border: none;\n background: transparent;\n color: inherit;\n font: inherit;\n outline: none;\n padding: 0;\n cursor: text;\n }\n\n #trigger::placeholder {\n color: var(--rc-text-disabled, GrayText);\n }\n\n #toggle {\n flex-shrink: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n inline-size: var(--rc-combobox-toggle-size, 1.1em);\n border: none;\n background: transparent;\n color: inherit;\n cursor: default;\n font: inherit;\n\n &:focus-visible {\n outline: var(--rc-focus-ring, auto);\n outline-offset: var(--rc-focus-ring-offset, 0);\n }\n }\n\n /* Hide the default slot — visually suppresses the slotted native <select> */\n slot:not([name]) {\n display: none;\n }\n\n /* Listbox popup — positioned by AnchorController via adoptedStyleSheets */\n rc-listbox {\n max-height: var(--rc-combobox-max-height, 20em);\n overflow-y: auto;\n background: var(--rc-surface, Canvas);\n border: var(\n --rc-combobox-listbox-border,\n var(--rc-border, 1px solid var(--rc-border-color, ButtonBorder))\n );\n border-radius: var(--rc-combobox-listbox-radius, var(--rc-control-radius, 0));\n box-shadow: var(\n --rc-combobox-shadow,\n var(--rc-shadow, 0 2px 8px color-mix(in srgb, CanvasText 15%, transparent))\n );\n color: var(--rc-field-text, FieldText);\n padding-block: var(\n --rc-combobox-listbox-padding-block,\n var(--rc-control-padding-block, 0.25em)\n );\n --rc-listbox-option-gap: var(--rc-item-gap, 0.4em);\n --rc-listbox-option-padding-block: var(--rc-item-padding-block, 0.3em);\n --rc-listbox-option-padding-inline: var(--rc-item-padding-inline, 0.75em);\n --rc-listbox-hover-bg: var(--rc-highlight, Highlight);\n --rc-listbox-hover-color: var(--rc-highlight-text, HighlightText);\n --rc-listbox-active-bg: var(--rc-highlight, Highlight);\n --rc-listbox-active-color: var(--rc-highlight-text, HighlightText);\n --rc-listbox-selected-bg: var(--rc-highlight, Highlight);\n --rc-listbox-selected-color: var(--rc-highlight-text, HighlightText);\n --rc-listbox-disabled-opacity: var(--rc-disabled-opacity, 0.5);\n\n &:not(:popover-open) {\n display: none;\n }\n }\n\n rc-listbox [part~='option'][hidden] {\n display: none;\n }\n\n rc-listbox [part~='option'][data-active]:not([aria-disabled='true']) {\n outline: var(--rc-focus-ring, 2px solid var(--rc-accent, Highlight));\n outline-offset: -2px;\n }\n\n rc-listbox [part~='option'][aria-disabled='true'] {\n cursor: not-allowed;\n }\n\n rc-listbox [part~='option-checkmark'] {\n flex-shrink: 0;\n width: 1em;\n text-align: center;\n font-size: 0.85em;\n visibility: hidden;\n }\n\n rc-listbox [part~='option'][aria-selected='true'] [part~='option-checkmark'] {\n visibility: visible;\n }\n\n rc-listbox [part~='create-option'] {\n font-style: italic;\n border-top: 1px solid var(--rc-border-color, ButtonBorder);\n margin-top: 0.25em;\n padding-top: 0.3em;\n }\n`;\n\nexport default comboboxStyles;\n","import { html, nothing } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\n\nimport { RCSelect } from '@rcarls/rc-select';\nimport type { FilterStrategy, RCListboxChangeEvent } from '@rcarls/rc-listbox';\n\nimport { comboboxStyles } from './rc-combobox.styles.js';\n\nexport interface RCComboboxCreateEvent {\n /** The text typed by the user that didn't match any existing option. */\n text: string;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'rc-combobox': RCCombobox;\n }\n}\n\n/**\n * Editable combobox with filtering and optional allow-create behavior, configured from\n * native option data and following the WAI-ARIA Combobox pattern.\n *\n * Extends `rc-select` by replacing the trigger `<div>` with a text `<input>`\n * and adding: live filtering of the listbox, keyboard navigation from input,\n * and an optional \"Create '{text}'\" option for new entries.\n *\n * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-combobox rc-combobox docs}\n * @see {@link https://www.w3.org/WAI/ARIA/apg/patterns/combobox/ WAI-ARIA Combobox pattern}\n *\n * @slot - Required. A native `<select>` element for form submission.\n * @slot toggle-icon - Optional. Replaces the default chevron icon.\n *\n * @fires rc-select-change - Inherited selection change event.\n * @fires rc-combobox-create - When the \"Create\" option is activated.\n * `detail: { text: string }`. Cancelable — call `preventDefault()` to stop\n * the default insertion of the new option.\n *\n * @csspart anchor - Outer container (includes chips + input + toggle).\n * @csspart chips - The chip group container (multiple mode).\n * @csspart chip - Individual chip (multiple mode).\n * @csspart chip-label - Text label inside a chip.\n * @csspart chip-remove - Remove button inside a chip.\n * @csspart input - The text input element.\n * @csspart toggle - The chevron toggle button.\n * @csspart listbox - The `<rc-listbox>` popup element.\n *\n * @attr allow-create - When present, shows a \"Create 'X'\" option for unmatched input.\n * @attr filter-strategy - How option labels are matched against typed input: `'contains'`\n * (default), `'prefix'`, or a custom predicate set via the `filterStrategy` JS property.\n *\n * @cssprop [--rc-combobox-max-height=20em] - Maximum popup height.\n * @cssprop [--rc-combobox-control-block-size=var(--rc-control-block-size)] - Anchor block size.\n * @cssprop [--rc-combobox-padding-block=calc(var(--rc-control-padding-block) / 2)] - Anchor block-axis padding.\n * @cssprop [--rc-combobox-padding-inline=calc(var(--rc-control-padding-inline) / 2)] - Anchor inline-axis padding.\n * @cssprop [--rc-combobox-gap=var(--rc-control-gap)] - Gap between chips, input, and toggle.\n * @cssprop [--rc-combobox-radius=var(--rc-control-radius)] - Anchor border radius.\n * @cssprop [--rc-combobox-border=var(--rc-border)] - Anchor border.\n * @cssprop [--rc-combobox-listbox-radius=var(--rc-control-radius)] - Popup listbox border radius.\n * @cssprop [--rc-combobox-listbox-border=var(--rc-border)] - Popup listbox border.\n * @cssprop [--rc-combobox-shadow=var(--rc-shadow)] - Popup listbox box shadow.\n * @cssprop [--rc-combobox-listbox-padding-block=var(--rc-control-padding-block)] - Popup listbox block padding.\n * @cssprop [--rc-combobox-chip-radius=var(--rc-radius-md)] - Multi-select chip border radius.\n * @cssprop [--rc-combobox-chip-padding-block=0.1em] - Multi-select chip block-axis padding.\n * @cssprop [--rc-combobox-chip-padding-inline=0.3em] - Multi-select chip inline-axis padding.\n * @cssprop [--rc-combobox-chip-gap=calc(var(--rc-control-gap, 0.25em) * 0.8)] - Gap between chip\n * label and remove icon.\n * @cssprop [--rc-combobox-chip-border=var(--rc-border)] - Multi-select chip border.\n * @cssprop [--rc-combobox-toggle-size=1.1em] - Inline size of the toggle button's icon area.\n */\nexport class RCCombobox extends RCSelect {\n static override styles = comboboxStyles;\n\n /** When set, shows a \"Create '{text}'\" option for text that has no exact match. */\n @property({ type: Boolean, attribute: 'allow-create' })\n allowCreate = false;\n\n /**\n * How option labels are matched against typed input.\n *\n * - Forwarded to the internal `rc-listbox`.\n * - Defaults to `'contains'` (substring).\n * - Set to `'prefix'` for starts-with matching, or\n * - Pass a custom `(label, query) => boolean` predicate.\n *\n * Function values are JS-only; string values may be set via the `filter-strategy` attribute.\n */\n @property({ attribute: 'filter-strategy', reflect: false })\n filterStrategy: FilterStrategy = 'contains';\n\n @query('#trigger')\n protected override _$trigger!: HTMLInputElement;\n\n @state()\n private _filterText = '';\n\n // Guard against _handleInputFocus re-opening the popup immediately after close.\n private _closingPopup = false;\n\n override openPopup() {\n super.openPopup();\n this._$listbox?.filterOptions(this._filterText);\n }\n\n override closePopup(_returnFocus = true) {\n this._filterText = '';\n this._$listbox?.clearFilter();\n this._$listbox?.setCreateOption(null);\n this._closingPopup = true;\n\n super.closePopup(false);\n\n // Deferred past any native focus-return from hidePopover() in Firefox\n setTimeout(() => {\n this._closingPopup = false;\n }, 0);\n }\n\n private _handleInput(e: InputEvent) {\n this._filterText = (e.target as HTMLInputElement).value;\n\n if (!this.open && this._filterText) {\n this.openPopup();\n }\n\n this._$listbox?.filterOptions(this._filterText);\n this._updateCreateOption();\n\n if (this._$listbox?.navigableItems.length) {\n this._activeDescendantCtrl.navigateToFirst();\n } else {\n this._activeDescendantCtrl.clear();\n }\n }\n\n private _handleInputFocus() {\n if (!this.open && !this._closingPopup) {\n this.openPopup();\n }\n }\n\n private _handleToggleClick(e: MouseEvent) {\n e.stopPropagation();\n\n if (this.open) {\n this.closePopup();\n } else {\n this.openPopup();\n this._$trigger?.focus();\n }\n }\n\n private _handleAnchorClick(e: MouseEvent) {\n const $target = e.target as HTMLElement;\n\n if (\n $target.closest('[part~=\"chip\"]') ||\n ($target as HTMLElement & { id?: string }).id === 'toggle'\n ) {\n return;\n }\n\n this._$trigger?.focus();\n }\n\n private _updateCreateOption() {\n if (!this.allowCreate || !this._filterText.trim()) {\n this._$listbox?.setCreateOption(null);\n\n return;\n }\n\n const trimmed = this._filterText.trim().toLowerCase();\n const hasExact =\n this._$listbox?.allOptions.some((o) => o.label.toLowerCase() === trimmed) ?? false;\n\n this._$listbox?.setCreateOption(hasExact ? null : this._filterText.trim());\n }\n\n protected override _handleListboxChange(e: CustomEvent) {\n const detail = e.detail as RCListboxChangeEvent;\n\n if (detail.reason === 'action' && detail.action === 'create') {\n e.stopPropagation();\n void this._activateCreate(this._filterText.trim());\n\n return;\n }\n\n super._handleListboxChange(e);\n\n if (!this.multiple) {\n this._syncInputToSelection();\n } else {\n this._filterText = '';\n\n if (this._$trigger) {\n this._$trigger.value = '';\n }\n\n this._$listbox?.clearFilter();\n this._updateCreateOption();\n }\n }\n\n private async _activateCreate(text: string) {\n if (!text) {\n return;\n }\n\n const createEvent = new CustomEvent<RCComboboxCreateEvent>('rc-combobox-create', {\n bubbles: true,\n composed: true,\n cancelable: true,\n detail: { text },\n });\n\n if (!this.dispatchEvent(createEvent)) {\n return;\n }\n\n this._addOption({ value: text, label: text });\n\n if (this.multiple) {\n this._$listbox?.toggleOption(text);\n this._filterText = '';\n\n if (this._$trigger) {\n this._$trigger.value = '';\n }\n\n this._$listbox?.clearFilter();\n this._$listbox?.setCreateOption(null);\n\n return;\n }\n\n this._applySelection([text]);\n this._syncInputToSelection();\n this.closePopup(true);\n this._dispatchChange();\n }\n\n override set value(value: string | string[] | undefined) {\n super.value = value;\n this._syncInputToSelection();\n }\n\n override get value(): string | string[] {\n return super.value;\n }\n\n private _syncInputToSelection(): void {\n if (this.multiple) {\n return;\n }\n\n const value = this.selectedValues[0];\n const label = value ? this._labelFor(value) : '';\n\n this._filterText = label;\n\n if (this._$trigger) {\n this._$trigger.value = label;\n }\n }\n\n private _handleInputKeyDown(e: KeyboardEvent) {\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n\n if (!this.open) {\n this.openPopup();\n this._activeDescendantCtrl.navigateToFirst();\n } else {\n this._activeDescendantCtrl.navigate(1);\n }\n\n break;\n\n case 'ArrowUp':\n e.preventDefault();\n\n if (this.open) {\n this._activeDescendantCtrl.navigate(-1);\n }\n\n break;\n\n case 'Home':\n if (this.open) {\n e.preventDefault();\n\n this._activeDescendantCtrl.navigateToFirst();\n }\n break;\n\n case 'End':\n if (this.open) {\n e.preventDefault();\n\n this._activeDescendantCtrl.navigateToLast();\n }\n break;\n\n case 'Enter': {\n e.preventDefault();\n const active = this._activeDescendantCtrl.activeItem;\n\n if (active) {\n active.dispatchEvent(\n new PointerEvent('pointerdown', { bubbles: true, cancelable: true }),\n );\n } else if (this.open && this._$listbox?.navigableItems.length) {\n const $first = this._$listbox.navigableItems[0];\n\n $first?.dispatchEvent(\n new PointerEvent('pointerdown', { bubbles: true, cancelable: true }),\n );\n }\n\n break;\n }\n\n case 'Tab':\n if (this.open) {\n const $first = this._$listbox?.navigableItems[0];\n\n if ($first) {\n $first.dispatchEvent(\n new PointerEvent('pointerdown', { bubbles: true, cancelable: true }),\n );\n }\n\n this.closePopup(false);\n }\n\n break;\n\n case 'Escape':\n e.preventDefault();\n this._filterText = '';\n\n if (this._$trigger) {\n this._$trigger.value = '';\n }\n\n this.closePopup();\n break;\n\n case 'Backspace':\n if (this._filterText === '' && this.multiple && this._selectedValues.size > 0) {\n e.preventDefault();\n this._focusLastChipRemove();\n }\n\n break;\n\n case 'ArrowLeft':\n if (\n (e.target as HTMLInputElement).selectionStart === 0 &&\n this.multiple &&\n this._selectedValues.size > 0\n ) {\n e.preventDefault();\n this._focusLastChipRemove();\n }\n\n break;\n }\n }\n\n private _focusLastChipRemove() {\n const $buttons = Array.from(\n this.renderRoot.querySelectorAll<HTMLButtonElement>('button[part~=\"chip\"]'),\n );\n\n $buttons[$buttons.length - 1]?.focus();\n }\n\n private get _inputPlaceholder(): string {\n if (this.multiple && this._selectedValues.size > 0) {\n return '';\n }\n\n return this.placeholder;\n }\n\n protected override render() {\n const showChips = this.multiple && this._selectedValues.size > 0;\n\n return html`\n <div id=\"anchor\" part=\"anchor\" @click=${this._handleAnchorClick}>\n ${showChips ? this._renderChips() : nothing}\n\n <input\n id=\"trigger\"\n part=\"input\"\n type=\"text\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-expanded=${this.open ? 'true' : 'false'}\n aria-controls=\"listbox\"\n aria-autocomplete=\"list\"\n ?disabled=${this.disabled}\n placeholder=${this._inputPlaceholder}\n .value=${this._filterText}\n autocomplete=\"off\"\n spellcheck=\"false\"\n @input=${this._handleInput}\n @keydown=${this._handleInputKeyDown}\n @focus=${this._handleInputFocus}\n />\n\n <button\n id=\"toggle\"\n type=\"button\"\n part=\"toggle\"\n aria-hidden=\"true\"\n tabindex=\"-1\"\n @click=${this._handleToggleClick}\n >\n <slot name=\"toggle-icon\">\n <svg\n width=\"10\"\n height=\"6\"\n viewBox=\"0 0 10 6\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <polyline points=\"1,1 5,5 9,1\" />\n </svg>\n </slot>\n </button>\n </div>\n\n <rc-listbox\n id=\"listbox\"\n part=\"listbox\"\n popover=\"manual\"\n ?multiple=${this.multiple}\n checkmark\n .filterStrategy=${this.filterStrategy}\n @rc-listbox-change=${this._handleListboxChange}\n ></rc-listbox>\n\n <slot @slotchange=${this._handleSelectSlotChange}></slot>\n `;\n }\n}\n\nexport default RCCombobox;\n"],"names":["comboboxStyles","css","_RCCombobox","RCSelect","_returnFocus","e","$target","trimmed","hasExact","o","detail","text","createEvent","value","label","active","$first","$buttons","showChips","html","nothing","RCCombobox","__decorateClass","property","query","state"],"mappings":"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"}
|
|
File without changes
|