@rcarls/rc-combobox 0.0.0-next-20260921045401

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 ADDED
@@ -0,0 +1,212 @@
1
+ # @rcarls/rc-combobox
2
+
3
+ ## 0.0.0-next-20260921045401
4
+
5
+ ### Minor Changes
6
+
7
+ - 079e025: Standardize component styling contracts for the breaking 0.7 release.
8
+
9
+ BREAKING CHANGE: Rename the Markdown editor's `--rme-*` properties to
10
+ `--rc-markdown-editor-*`, `--rc-app-bar-background` to `--rc-app-bar-bg`,
11
+ `--rc-textarea-radius` to `--rc-textarea-border-radius`, the transfer-list
12
+ `--rc-transfer-list-panel-*` properties to `--rc-transfer-list-listbox-*`,
13
+ `--rc-chip-group-webkit-scrollbar-display` to
14
+ `--rc-chip-group-scrollbar-display`, and `--rc-text` to `--rc-field-text`.
15
+ Compatibility aliases are intentionally not provided.
16
+
17
+ BREAKING CHANGE: Replace `--rc-select-chip-padding-inline` and
18
+ `--rc-combobox-chip-padding-inline` with explicit `*-padding-inline-start` and
19
+ `*-padding-inline-end` tokens. Generated removable chips now reserve the full
20
+ remove target and its edge offset, so their indicator cannot overlap label text.
21
+
22
+ Add canonical app-bar elevation, transfer-list listbox radius, and textarea
23
+ line-action tokens. Add logical `rc-chip` inline-padding properties so themes
24
+ can implement Material's icon-aware spacing without overriding authored child
25
+ styles. Make `rc-field` consume the shared semantic token layer,
26
+ and place the `rc-chip` and `rc-search-bar` light-DOM structural styles in the
27
+ `rc-base` cascade layer so normal consumer rules override them.
28
+
29
+ Prevent decorative, `aria-hidden` trailing list content from intercepting a
30
+ whole-row action target, and keep segmented-list item geometry from leaking
31
+ into nested standard lists.
32
+
33
+ Remove unused Material navigation-rail toggle tokens and obsolete list-item
34
+ theme tokens. Register the segmented-button private theme seam and enforce
35
+ token ownership, documentation, removed-name, selector-budget, and cascade
36
+ layer contracts through the component architecture audit.
37
+
38
+ - 4341311: Add reusable fullscreen dialogs and declarative dialog popup mode to `rc-select` and
39
+ `rc-combobox`. Dialog selection and creation are staged until Done, while close and Escape
40
+ discard the draft. Fullscreen surfaces follow the visual viewport under browser zoom and
41
+ software keyboards, and anchored popups now clamp to the visual viewport.
42
+ - 94dc987: `rc-menu-button`'s, `rc-select`'s, and `rc-combobox`'s popup/listbox now fade
43
+ in and out through CSS alone, using `@starting-style` and a discrete
44
+ `display`/`overlay` transition, driven by new `--rc-menu-button-popup-duration`,
45
+ `--rc-select-listbox-duration`, and `--rc-combobox-listbox-duration`
46
+ properties. `showPopover()`/`hidePopover()` (via `openPopup()`/`closePopup()`)
47
+ stay synchronous, and nothing waits on the transition finishing.
48
+
49
+ These animate opacity only, not a scale or slide transform: all three
50
+ position their popup with the shared `AnchorController`, which applies its
51
+ own viewport-clamping `translate` and reads `getBoundingClientRect()` to
52
+ compute the next correction. A second, CSS-driven transform on the same
53
+ element and property would fight that positioning math on every open, not
54
+ only during an edge case.
55
+
56
+ `rc-fab-menu` already had a scale-based entrance for its popup (verified safe
57
+ here: unlike the general `AnchorController` case, this popup isn't
58
+ collision-clamped), but no exit animation at all and no directional easing.
59
+ Both are added: the popup now fades and scales back out on close, and enter
60
+ uses a decelerating curve while exit uses an accelerating one.
61
+
62
+ ### Patch Changes
63
+
64
+ - 011f3c6: Keep combobox chips clear of their trailing toggle, reset native selects inside
65
+ `rc-field`, keep controlled carousel accessibility state synchronized, and align
66
+ Material chips, menus, lists, disclosures, nested editors, and bottom-sheet
67
+ motion with their MD3 defaults.
68
+ - 8363cb8: Fix a real user-driven "create new option" selection not dispatching native `input`/`change` on
69
+ the slotted `<select>` (`focus()`/`blur()` forwarding and `required` mirroring were already
70
+ correct through inheritance from `rc-select`'s new control-provider support). `aria-required`
71
+ now reflects on the input trigger.
72
+ - Updated dependencies [50d5610]
73
+ - Updated dependencies [079e025]
74
+ - Updated dependencies [4341311]
75
+ - Updated dependencies [94dc987]
76
+ - Updated dependencies [8a30e96]
77
+ - @rcarls/rc-common@0.0.0-next-20260921045401
78
+ - @rcarls/rc-chip-group@0.0.0-next-20260921045401
79
+ - @rcarls/rc-select@0.0.0-next-20260921045401
80
+ - @rcarls/rc-listbox@0.0.0-next-20260921045401
81
+
82
+ ## 0.6.0
83
+
84
+ ### Minor Changes
85
+
86
+ - ffcbf11: Add adaptive chip-group layouts, native-backed filter chips, and shared
87
+ input-chip rendering. Native-backed chips preserve controlled host state,
88
+ follow form resets when uncontrolled, and accept native link actions. Groups
89
+ restore author-owned chip variants when coordination ends. Keep search input
90
+ chrome inside the search surface and align contextual icon sizes with Material 3.
91
+
92
+ ### Patch Changes
93
+
94
+ - Updated dependencies [ffcbf11]
95
+ - Updated dependencies [6683eb9]
96
+ - Updated dependencies [ee7ba6c]
97
+ - Updated dependencies [30eb232]
98
+ - @rcarls/rc-chip-group@0.6.0
99
+ - @rcarls/rc-select@0.6.0
100
+ - @rcarls/rc-common@0.6.0
101
+ - @rcarls/rc-listbox@0.6.0
102
+
103
+ ## 0.5.0
104
+
105
+ ### Patch Changes
106
+
107
+ - Updated dependencies [4ae2ef0]
108
+ - Updated dependencies [689340c]
109
+ - @rcarls/rc-common@0.5.0
110
+ - @rcarls/rc-listbox@0.5.0
111
+ - @rcarls/rc-select@0.5.0
112
+
113
+ ## 0.4.2
114
+
115
+ ### Patch Changes
116
+
117
+ - @rcarls/rc-common@0.4.2
118
+ - @rcarls/rc-listbox@0.4.2
119
+ - @rcarls/rc-select@0.4.2
120
+
121
+ ## 0.4.1
122
+
123
+ ### Patch Changes
124
+
125
+ - @rcarls/rc-common@0.4.1
126
+ - @rcarls/rc-listbox@0.4.1
127
+ - @rcarls/rc-select@0.4.1
128
+
129
+ ## 0.4.0
130
+
131
+ ### Patch Changes
132
+
133
+ - acc913e: Document the `chips` and `listbox` CSS parts, the `filter-strategy` attribute, and the
134
+ `--rc-combobox-chip-gap`, `--rc-combobox-chip-border`, `--rc-combobox-listbox-border`, and
135
+ `--rc-combobox-shadow` custom properties in the generated API reference. Also correct the
136
+ `allow-create` attribute tag to non-bracket form (it has a real settable `allowCreate`
137
+ property) and fix stale README/docs prose that claimed a `default-value` HTML attribute exists
138
+ for the inherited `defaultValue` property, which has no attribute mapping.
139
+ - fa9bed0: Fix the toggle button's size custom property so it is `--rc-combobox-toggle-size`, matching
140
+ every other `--rc-combobox-*` token in the package. It previously reused rc-select's
141
+ `--rc-select-toggle-indicator-size`, so setting `--rc-combobox-toggle-size` on `<rc-combobox>`
142
+ silently did nothing.
143
+ - Updated dependencies [e57277f]
144
+ - Updated dependencies [8944083]
145
+ - Updated dependencies [ccca8e2]
146
+ - Updated dependencies [9c3bc6f]
147
+ - Updated dependencies [037b1b3]
148
+ - @rcarls/rc-common@0.4.0
149
+ - @rcarls/rc-listbox@0.4.0
150
+ - @rcarls/rc-select@0.4.0
151
+
152
+ ## 0.3.2
153
+
154
+ ### Patch Changes
155
+
156
+ - Updated dependencies [88b4086]
157
+ - @rcarls/rc-common@0.3.2
158
+ - @rcarls/rc-select@0.3.2
159
+ - @rcarls/rc-listbox@0.3.2
160
+
161
+ ## 0.3.1
162
+
163
+ ### Patch Changes
164
+
165
+ - @rcarls/rc-common@0.3.1
166
+ - @rcarls/rc-listbox@0.3.1
167
+ - @rcarls/rc-select@0.3.1
168
+
169
+ ## 0.3.0
170
+
171
+ ### Added
172
+
173
+ - Add typed action option support for `allow-create` flows.
174
+
175
+ ### Changed
176
+
177
+ - Change the required native `<select>` child to the default slot.
178
+ - Normalize embedded listbox option styling around `--rc-listbox-*` custom properties.
179
+ - Replace the text chevron with an inline SVG chevron.
180
+ - Update package metadata, README intro, and docs links.
181
+
182
+ ### Fixed
183
+
184
+ - Reflect `allowCreate` as the `allow-create` attribute instead of `allowcreate`.
185
+
186
+ ### Migration
187
+
188
+ - Rename the `allowcreate` attribute to `allow-create`.
189
+
190
+ ```diff
191
+ - <rc-combobox allowcreate>
192
+ + <rc-combobox allow-create>
193
+ ```
194
+
195
+ - Remove `slot="select"` from the native `<select>` child.
196
+
197
+ ```diff
198
+ - <rc-combobox><select slot="select" name="tags">...</select></rc-combobox>
199
+ + <rc-combobox><select name="tags">...</select></rc-combobox>
200
+ ```
201
+
202
+ ### Dependencies
203
+
204
+ - Sync internal dependencies to 0.3.0.
205
+
206
+ ## 0.2.0
207
+
208
+ ### Patch Changes
209
+
210
+ - @rcarls/rc-common@0.2.0
211
+ - @rcarls/rc-listbox@0.2.0
212
+ - @rcarls/rc-select@0.2.0
package/README.md ADDED
@@ -0,0 +1,212 @@
1
+ # `@rcarls/rc-combobox`
2
+
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/).
6
+
7
+ Docs:
8
+ [https://richardcarls.github.io/rc-webcomponents/components/rc-combobox](https://richardcarls.github.io/rc-webcomponents/components/rc-combobox).
9
+
10
+ Extends `rc-select` with a text input and wraps a native slotted `<select>`.
11
+
12
+ ## Installation
13
+
14
+ PowerShell:
15
+
16
+ ```powershell
17
+ yarn.cmd add @rcarls/rc-combobox
18
+ ```
19
+
20
+ Bash/zsh:
21
+
22
+ ```bash
23
+ yarn add @rcarls/rc-combobox
24
+ ```
25
+
26
+ ## Import
27
+
28
+ ```ts
29
+ import '@rcarls/rc-combobox/define';
30
+ ```
31
+
32
+ ## Basic Usage
33
+
34
+ ```html
35
+ <label>
36
+ Fruit
37
+ <rc-combobox placeholder="Search fruit">
38
+ <select name="fruit">
39
+ <option value="apple">Apple</option>
40
+ <option value="banana">Banana</option>
41
+ <option value="cherry">Cherry</option>
42
+ </select>
43
+ </rc-combobox>
44
+ </label>
45
+ ```
46
+
47
+ ## Allow Create
48
+
49
+ Add `allow-create` to show a **"Create 'X'"** option when the typed text has no exact match.
50
+ Selecting it inserts the new option into the native `<select>`, selects it, and
51
+ fires `rc-combobox-create`.
52
+
53
+ ```html
54
+ <rc-combobox allow-create placeholder="Add tag">
55
+ <select name="tags" multiple></select>
56
+ </rc-combobox>
57
+ ```
58
+
59
+ ## Dialog Popup
60
+
61
+ Use `popup-mode="dialog"` when an anchored option list would leave too little usable
62
+ viewport, such as on a phone with the software keyboard open. The trigger opens a native modal
63
+ dialog with the current chips, a dedicated search input, the option list, and a Done action.
64
+ Selections and newly created values are staged while the dialog is open. Done commits them in
65
+ one selection change; the leading close action, Escape, and imperative close discard them.
66
+
67
+ ```html
68
+ <rc-combobox popup-mode="dialog" allow-create placeholder="Add categories">
69
+ <select name="categories" multiple>
70
+ <option value="quick">Quick meal</option>
71
+ <option value="vegetarian">Vegetarian</option>
72
+ </select>
73
+ </rc-combobox>
74
+ ```
75
+
76
+ Choose the mode declaratively from your application’s viewport policy. The component latches
77
+ the mode for an open interaction, so changing `popupMode` does not replace an active popup.
78
+
79
+ ### Validation
80
+
81
+ `rc-combobox-create` is cancelable. Call `event.preventDefault()` to block insertion when the
82
+ text fails validation. In dialog mode the event is deferred until Done, before the selection
83
+ commit. The default behavior (insert + select) runs otherwise.
84
+
85
+ ```js
86
+ combobox.addEventListener('rc-combobox-create', (event) => {
87
+ if (event.detail.text.trim().length < 2) {
88
+ event.preventDefault();
89
+ showError('Tag must be at least 2 characters.');
90
+ }
91
+ });
92
+ ```
93
+
94
+ ### React: managing options as state
95
+
96
+ Call `preventDefault()` and add the new item to your React state instead. After React renders
97
+ the new `<option>`, set `el.value` in a `useEffect` to select it:
98
+
99
+ ```tsx
100
+ const [options, setOptions] = useState(initialOptions);
101
+ const pendingValue = useRef<string | null>(null);
102
+ const comboRef = useRef<HTMLElement & { value: string | string[] | undefined }>(null);
103
+
104
+ useEffect(() => {
105
+ const el = comboRef.current;
106
+ if (!el) return;
107
+ const handleCreate = (e: Event) => {
108
+ e.preventDefault();
109
+ const { text } = (e as CustomEvent<{ text: string }>).detail;
110
+ const value = text.trim().toLowerCase().replace(/\s+/g, '-');
111
+ setOptions((prev) => [...prev, { value, label: text.trim() }]);
112
+ pendingValue.current = value;
113
+ };
114
+ el.addEventListener('rc-combobox-create', handleCreate);
115
+ return () => el.removeEventListener('rc-combobox-create', handleCreate);
116
+ }, []);
117
+
118
+ // Runs after React renders the new <option>; component has already processed slotchange.
119
+ useEffect(() => {
120
+ const value = pendingValue.current;
121
+ if (!value || !comboRef.current) return;
122
+ pendingValue.current = null;
123
+ const el = comboRef.current;
124
+ const current = Array.isArray(el.value) ? el.value : el.value ? [el.value] : [];
125
+ if (!current.includes(value)) {
126
+ el.value = [...current, value];
127
+ }
128
+ }, [options]);
129
+ ```
130
+
131
+ ### Form usage: ephemeral options until committed
132
+
133
+ By default, created options are added to the native `<select>` and appear in `FormData` on submit
134
+ but are discarded on page reload. To persist them on submit, track them alongside the option list:
135
+
136
+ ```js
137
+ const pending = new Set();
138
+
139
+ combobox.addEventListener('rc-combobox-create', (event) => {
140
+ pending.add(event.detail.text.trim());
141
+ // Default runs, so the option is inserted and selected.
142
+ });
143
+
144
+ form.addEventListener('submit', (event) => {
145
+ event.preventDefault();
146
+ const data = new FormData(form);
147
+ const selected = data.getAll('tags');
148
+ const newValues = selected.filter((v) => pending.has(v));
149
+ // Save newValues to the server; they become persisted options next load.
150
+ });
151
+ ```
152
+
153
+ ## Controlled vs Uncontrolled
154
+
155
+ **Uncontrolled (default):** set `<option selected>` or the `defaultValue` property for the
156
+ initial value; the component owns selection thereafter. Listen to `rc-select-change` to observe
157
+ changes. `defaultValue` accepts `string | string[]` and has no HTML attribute form; set it as a
158
+ JS property.
159
+
160
+ **Controlled:** write `el.value` (the property) to drive selection programmatically. Writes are
161
+ silent, so no `rc-select-change` is dispatched. Update `el.value` in response to `rc-select-change`
162
+ to keep external state in sync.
163
+
164
+ ```js
165
+ combobox.value = 'banana'; // single
166
+ combobox.value = ['apple', 'cherry']; // multiple
167
+ ```
168
+
169
+ For `allow-create`, the same split applies to options:
170
+
171
+ - **Uncontrolled options:** let the default behavior add the new `<option>` to
172
+ the native `<select>`.
173
+ - **Controlled options:** call `event.preventDefault()` on
174
+ `rc-combobox-create` and manage `<option>` elements yourself (for example, in
175
+ React state), then set `el.value` to include the new value.
176
+
177
+ ## API
178
+
179
+ | Property | Type | Description |
180
+ | ---------------- | ------------------------------------ | -------------------------------------------------------------------------- |
181
+ | `allowCreate` | `boolean` | Shows a create option for unmatched input. |
182
+ | `filterStrategy` | `'prefix' \| 'contains' \| function` | Controls option filtering. |
183
+ | `popupMode` | `'popover' \| 'dialog'` | Chooses an anchored popup or modal dialog. Defaults to `'popover'`. |
184
+ | `open` | `boolean` | Inherited from `rc-select`; reflects whether the popup is open. |
185
+ | `multiple` | `boolean` | Inherited from `rc-select`; enables multiple selection and chip rendering. |
186
+ | `disabled` | `boolean` | Inherited from `rc-select`; disables the input and popup trigger. |
187
+ | `placeholder` | `string` | Inherited from `rc-select`; input placeholder when no value is selected. |
188
+ | `display` | `'auto' \| 'chips' \| 'compact'` | Inherited from `rc-select`; controls multiple-value presentation. |
189
+ | `value` | `string \| string[]` | Inherited committed selection. Host writes are silent. |
190
+ | `defaultValue` | `string \| string[] \| undefined` | Inherited JS-only initial value for uncontrolled usage. |
191
+ | `options` | `ListboxOption[] \| undefined` | Inherited JS-only option-data override. |
192
+ | `selectedValues` | `string[]` | Inherited read-only snapshot of selected values. |
193
+
194
+ The inherited `openPopup()` and `closePopup()` methods control the popup
195
+ imperatively. Like other host-driven writes, these calls do not dispatch a
196
+ selection-change event.
197
+
198
+ ## Events
199
+
200
+ | Event | Detail | Description |
201
+ | -------------------- | ------------------------------- | ------------------------------------------------------- |
202
+ | `rc-combobox-create` | `{ text: string }` | Cancelable event fired before a new option is inserted. |
203
+ | `rc-select-change` | `{ value: string \| string[] }` | Inherited selection-change event. |
204
+ | `rc-select-open` | none | Inherited event fired when the popup opens. |
205
+ | `rc-select-close` | none | Inherited event fired when the popup closes. |
206
+
207
+ ## Accessibility
208
+
209
+ - Input uses `role="combobox"` with `aria-autocomplete="list"`.
210
+ - Dialog mode exposes a dialog-valued combobox trigger and moves filtering into the modal.
211
+ - Popup navigation uses `aria-activedescendant`.
212
+ - The slotted native `<select>` remains the form value source.