@rcarls/rc-search-bar 0.3.2 → 0.4.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.
@@ -3,11 +3,28 @@ declare global {
3
3
  interface HTMLElementTagNameMap {
4
4
  'rc-search-bar': RCSearchBar;
5
5
  }
6
+ interface HTMLElementEventMap {
7
+ 'rc-search-bar-input': CustomEvent<RCSearchBarInputDetail>;
8
+ 'rc-search-bar-clear': CustomEvent<Record<string, never>>;
9
+ 'rc-search-bar-toggle': CustomEvent<RCSearchBarToggleDetail>;
10
+ 'rc-search-bar-suggestion-select': CustomEvent<RCSearchBarSuggestionSelectDetail>;
11
+ }
6
12
  }
7
13
  export interface RCSearchBarInputDetail {
8
14
  /** The native input's value at dispatch time. */
9
15
  value: string;
10
16
  }
17
+ export interface RCSearchBarToggleDetail {
18
+ /** Whether the search view is open after the user action. */
19
+ open: boolean;
20
+ }
21
+ export interface RCSearchBarSuggestionSelectDetail {
22
+ /** Value written to the native search input. */
23
+ value: string;
24
+ /** Human-readable option label, when different from value. */
25
+ label: string;
26
+ }
27
+ export type RCSearchBarVariant = 'bar' | 'view';
11
28
  /**
12
29
  * Search field wrapper for a native <input type="search"> with icon chrome, clear button,
13
30
  * and debounced events.
@@ -29,10 +46,28 @@ export interface RCSearchBarInputDetail {
29
46
  * @slot leading - Decorative leading icon; mark it `aria-hidden="true"`
30
47
  * @slot trailing - Optional trailing content after the clear button
31
48
  * @slot clear-icon - Optional glyph replacing the default clear glyph
49
+ * @slot suggestions - Rich search view suggestions; takes precedence over
50
+ * datalist-derived suggestions.
32
51
  *
33
52
  * @fires rc-search-bar-input - Debounced after typing, immediate on clear;
34
53
  * `detail: { value }`
35
54
  * @fires rc-search-bar-clear - When the clear button is activated
55
+ * @fires rc-search-bar-toggle - When user interaction opens or closes the
56
+ * search view; `detail: { open }`
57
+ * @fires rc-search-bar-suggestion-select - When a datalist-derived suggestion
58
+ * is activated; `detail: { value, label }`
59
+ *
60
+ * @attr variant - Presentation mode: docked search bar or expandable search view.
61
+ * @attr debounce - Debounce window in ms for `rc-search-bar-input`; `0` dispatches synchronously.
62
+ * @attr clear-label - Accessible label for the clear button.
63
+ * @attr allow-native-clear - When set, leaves the browser's native WebKit cancel button visible.
64
+ * @attr show-clear-on-focus - When set, the clear button is visible whenever the input is focused.
65
+ * @attr disabled - Disables the component and mirrors the state to the slotted input.
66
+ * @attr placeholder - Placeholder mirrored onto the native input; a consumer `placeholder`
67
+ * attribute on the input itself is always honored instead.
68
+ * @attr open - Whether the search view panel is open. Host writes are silent.
69
+ * @attr default-open - Initial uncontrolled search view open state.
70
+ * @attr default-value - Initial uncontrolled value hint, applied once.
36
71
  *
37
72
  * @cssprop [--rc-search-bar-border=1px solid ButtonBorder] - Wrapper border; set to `none` in M3 theme (uses elevation instead)
38
73
  * @cssprop [--rc-search-bar-shadow=none] - Wrapper box-shadow for elevation; M3 theme sets Level 1 at rest
@@ -47,13 +82,28 @@ export interface RCSearchBarInputDetail {
47
82
  * @cssprop [--rc-search-bar-input-font-size] - Input font size (inherits when unset)
48
83
  * @cssprop [--rc-search-bar-input-font-family] - Input font family (inherits when unset)
49
84
  * @cssprop [--rc-search-bar-input-color] - Input text color (inherits when unset)
85
+ * @cssprop [--rc-search-bar-view-bg=var(--rc-search-bar-bg)] - Search view panel background
86
+ * @cssprop [--rc-search-bar-view-color=var(--rc-search-bar-color)] - Search view panel text color
87
+ * @cssprop [--rc-search-bar-view-radius=var(--rc-search-bar-radius)] - Search view panel radius
88
+ * @cssprop [--rc-search-bar-view-shadow=var(--rc-search-bar-shadow)] - Search view panel shadow
89
+ * @cssprop [--rc-search-bar-view-border=var(--rc-search-bar-border)] - Search view panel border
90
+ * @cssprop [--rc-search-bar-view-offset=0.25rem] - Gap between the search bar and the view panel below it
91
+ * @cssprop [--rc-search-bar-view-padding-block=0.5rem] - Search view suggestion list block padding
92
+ * @cssprop [--rc-search-bar-suggestion-min-block-size=2.75rem] - Datalist-derived suggestion row minimum block size
93
+ * @cssprop [--rc-search-bar-suggestion-padding-inline=1rem] - Datalist-derived suggestion inline padding
94
+ * @cssprop [--rc-search-bar-suggestion-hover-bg=ButtonFace] - Datalist-derived suggestion hover/focus background
50
95
  * @csspart root - The wrapper element
51
96
  * @csspart leading - Wrapper around the leading icon slot
52
97
  * @csspart trailing - Wrapper around the trailing slot
53
98
  * @csspart clear - The clear button
99
+ * @csspart view - Search view panel
100
+ * @csspart suggestions - Suggestions container
101
+ * @csspart suggestion - Datalist-derived suggestion button
54
102
  */
55
103
  export declare class RCSearchBar extends LitElement {
56
104
  static styles: import('lit').CSSResult[];
105
+ /** Presentation mode: docked search bar or expandable search view. */
106
+ variant: RCSearchBarVariant;
57
107
  /** Debounce window in ms for `rc-search-bar-input`; `0` dispatches synchronously. */
58
108
  debounce: number;
59
109
  /** Accessible label for the clear button. */
@@ -76,6 +126,9 @@ export declare class RCSearchBar extends LitElement {
76
126
  * Consumer `placeholder` attribute is always honored.
77
127
  */
78
128
  placeholder?: string;
129
+ private _open;
130
+ private _defaultOpen;
131
+ private _openInitialized;
79
132
  private _value;
80
133
  private _defaultValue;
81
134
  private _valueSetByHost;
@@ -84,17 +137,27 @@ export declare class RCSearchBar extends LitElement {
84
137
  private _authorPlaceholder;
85
138
  private _$inputRef;
86
139
  private _debounceTimer;
140
+ private _$dataListRef;
87
141
  private _hasInput;
88
142
  private _hasValue;
89
143
  private _hasLeading;
90
144
  private _hasTrailing;
91
145
  private _inputDisabled;
146
+ private _hasSuggestionsSlot;
147
+ private _dataListSuggestions;
92
148
  private _disabledHost;
93
149
  private _focused;
94
150
  private readonly _onInputFocus;
95
151
  private readonly _onInputBlur;
96
152
  private readonly _disabledObserver;
153
+ private readonly _dataListObserver;
97
154
  private readonly _inputController;
155
+ /** Whether the search view panel is open. Host writes are silent. */
156
+ get open(): boolean;
157
+ set open(value: boolean);
158
+ /** Initial uncontrolled search view open state. */
159
+ get defaultOpen(): boolean;
160
+ set defaultOpen(value: boolean);
98
161
  /**
99
162
  * The current search value. Reads from the native input when present.
100
163
  * Host writes are silent (no events) and win over slotted author values.
@@ -116,14 +179,26 @@ export declare class RCSearchBar extends LitElement {
116
179
  private _bindInput;
117
180
  private _applyPlaceholder;
118
181
  private readonly _onNativeInput;
182
+ private readonly _onNativeKeyDown;
119
183
  private _scheduleInputEvent;
120
184
  private _cancelPendingInput;
121
185
  private _dispatchInput;
186
+ private _setUserOpen;
187
+ /** Opens the search view and fires `rc-search-bar-toggle` when it changes. */
188
+ showView(): void;
189
+ /** Closes the search view and fires `rc-search-bar-toggle` when it changes. */
190
+ closeView(): void;
191
+ /** Toggles the search view and fires `rc-search-bar-toggle` when it changes. */
192
+ toggleView(): void;
193
+ private _syncDataListSuggestions;
194
+ private _selectDataListSuggestion;
122
195
  private _handleClear;
123
196
  protected render(): import('lit').TemplateResult<1>;
124
197
  /** Programmatically clears the value and fires rc-search-bar-clear + rc-search-bar-input. */
125
198
  clear(): void;
199
+ private _renderSearchView;
126
200
  private _onLeadingSlotChange;
127
201
  private _onTrailingSlotChange;
202
+ private _onSuggestionsSlotChange;
128
203
  }
129
204
  export default RCSearchBar;
package/package.json CHANGED
@@ -3,8 +3,8 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.3.2",
7
- "description": "Search field wrapper for a native <input type=\"search\"> with icon chrome, clear button, and debounced events.",
6
+ "version": "0.4.0",
7
+ "description": "Search field/view wrapper for a native <input type=\"search\"> with suggestions and debounced events.",
8
8
  "repository": {
9
9
  "type": "git",
10
10
  "url": "git+https://github.com/richardcarls/rc-webcomponents.git",
@@ -1,326 +0,0 @@
1
- import { css as b, LitElement as f, html as v } from "lit";
2
- import { property as r, state as l } from "lit/decorators.js";
3
- import { classMap as d } from "lit/directives/class-map.js";
4
- import { NativeChildController as g, keyInteraction as m } from "@rcarls/rc-common";
5
- const y = b`
6
- :host {
7
- display: inline-flex;
8
- color-scheme: inherit;
9
- }
10
-
11
- [hidden] {
12
- display: none !important;
13
- }
14
-
15
- #root {
16
- display: flex;
17
- flex: 1 1 auto;
18
- align-items: center;
19
- min-inline-size: 0;
20
- gap: var(--rc-search-bar-gap, var(--rc-control-gap, 0.25em));
21
- block-size: var(--rc-search-bar-height, var(--rc-control-block-size, 2.5rem));
22
- padding-inline: var(--rc-search-bar-padding-inline, var(--rc-control-padding-inline, 0.75rem));
23
- border: var(--rc-search-bar-border, var(--rc-border, 1px solid var(--rc-border-color, ButtonBorder)));
24
- border-radius: var(--rc-search-bar-radius, var(--rc-control-radius, var(--rc-radius-sm, 0.125em)));
25
- box-shadow: var(--rc-search-bar-shadow, none);
26
- background: var(--rc-search-bar-bg, var(--rc-field, Field));
27
- color: var(--rc-search-bar-color, var(--rc-field-text, FieldText));
28
- font-family: var(--rc-font-family, inherit);
29
- font-size: var(--rc-font-size, inherit);
30
- line-height: var(--rc-line-height, normal);
31
- transition: background-color 120ms, border-color 120ms, box-shadow 120ms;
32
- }
33
-
34
- :host([data-interaction-mode='keyboard']) #root:focus-within {
35
- outline: var(--rc-focus-ring, auto);
36
- outline-offset: var(--rc-focus-ring-offset, 0);
37
- }
38
-
39
- /* No slotted search input: render no chrome at all. */
40
- #root.empty {
41
- block-size: auto;
42
- padding: 0;
43
- background: none;
44
- border: none;
45
- box-shadow: none;
46
- border-radius: 0;
47
- }
48
-
49
- #leading {
50
- display: flex;
51
- flex: none;
52
- align-items: center;
53
- color: var(--rc-search-bar-icon-color, GrayText);
54
- }
55
-
56
- #leading.empty {
57
- display: none;
58
- }
59
-
60
- ::slotted(input[type='search']) {
61
- flex: 1 1 auto;
62
- min-inline-size: 0;
63
- padding: 0;
64
- border: none;
65
- background: transparent;
66
- color: var(--rc-search-bar-input-color, inherit);
67
- font-family: var(--rc-search-bar-input-font-family, inherit);
68
- font-size: var(--rc-search-bar-input-font-size, inherit);
69
- outline: none;
70
- appearance: textfield;
71
- }
72
-
73
- #trailing {
74
- display: flex;
75
- flex: none;
76
- align-items: center;
77
- }
78
-
79
- #trailing.empty {
80
- display: none;
81
- }
82
-
83
- #clear {
84
- display: inline-grid;
85
- flex: none;
86
- place-items: center;
87
- min-inline-size: 24px;
88
- min-block-size: 24px;
89
- padding: 0;
90
- border: none;
91
- border-radius: 50%;
92
- background: none;
93
- color: var(--rc-search-bar-clear-color, GrayText);
94
- font: inherit;
95
- cursor: pointer;
96
- }
97
-
98
- #clear[inert] {
99
- visibility: hidden;
100
- }
101
-
102
- #clear:focus-visible {
103
- outline: var(--rc-focus-ring, auto);
104
- outline-offset: var(--rc-focus-ring-offset, 0);
105
- }
106
- `;
107
- var I = Object.defineProperty, C = Object.getOwnPropertyDescriptor, a = (c, e, t, s) => {
108
- for (var n = s > 1 ? void 0 : s ? C(e, t) : e, o = c.length - 1, h; o >= 0; o--)
109
- (h = c[o]) && (n = (s ? h(e, t, n) : h(n)) || n);
110
- return s && n && I(e, t, n), n;
111
- };
112
- const _ = new CSSStyleSheet();
113
- _.replaceSync(
114
- `rc-search-bar:not([allow-native-clear]) input[type="search"]::-webkit-search-cancel-button
115
- { -webkit-appearance: none; display: none; }`
116
- );
117
- let p = !1;
118
- function w() {
119
- p || (document.adoptedStyleSheets = [...document.adoptedStyleSheets, _], p = !0);
120
- }
121
- const u = class u extends f {
122
- constructor() {
123
- super(...arguments), this.debounce = 200, this.clearLabel = "Clear search", this.allowNativeClear = !1, this.showClearOnFocus = !1, this._value = void 0, this._defaultValue = void 0, this._valueSetByHost = !1, this._valueInitialized = !1, this._authorPlaceholder = !1, this._$inputRef = null, this._debounceTimer = void 0, this._hasInput = !1, this._hasValue = !1, this._hasLeading = !1, this._hasTrailing = !1, this._inputDisabled = !1, this._disabledHost = void 0, this._focused = !1, this._onInputFocus = () => {
124
- this._focused = !0;
125
- }, this._onInputBlur = () => {
126
- this._focused = !1;
127
- }, this._disabledObserver = new MutationObserver(() => {
128
- const e = this._$input();
129
- e && (this._inputDisabled = e.disabled);
130
- }), this._inputController = new g(this, {
131
- selector: ':scope > input[type="search"]',
132
- observe: !0,
133
- onChange: (e, t) => this._setupInput(e, t),
134
- onMissing: () => {
135
- }
136
- }), this._onNativeInput = (e) => {
137
- const t = e.currentTarget;
138
- this._valueInitialized = !0, this._hasValue = t.value.length > 0, this._scheduleInputEvent(t.value);
139
- };
140
- }
141
- get disabled() {
142
- return this._disabledHost ?? this._inputDisabled;
143
- }
144
- set disabled(e) {
145
- const t = this.disabled;
146
- this._disabledHost = e;
147
- const s = this._$input();
148
- s && (s.disabled = e), this.requestUpdate("disabled", t);
149
- }
150
- get value() {
151
- return this._$input()?.value ?? this._value ?? this._defaultValue ?? "";
152
- }
153
- set value(e) {
154
- const t = this.value;
155
- this._value = e, this._valueSetByHost = !0, this._valueInitialized = !0;
156
- const s = this._$input();
157
- s && (s.value = e), this._hasValue = e.length > 0, this.requestUpdate("value", t);
158
- }
159
- get defaultValue() {
160
- return this._defaultValue;
161
- }
162
- set defaultValue(e) {
163
- const t = this._defaultValue;
164
- this._defaultValue = e;
165
- const s = this._$input();
166
- s && e !== void 0 && !this._valueInitialized && (s.value = e, this._hasValue = e.length > 0), this.requestUpdate("defaultValue", t);
167
- }
168
- connectedCallback() {
169
- super.connectedCallback(), w();
170
- }
171
- disconnectedCallback() {
172
- super.disconnectedCallback(), this._focused = !1, this._cancelPendingInput();
173
- const e = this._$input();
174
- e?.removeEventListener("input", this._onNativeInput), e?.removeEventListener("focus", this._onInputFocus), e?.removeEventListener("blur", this._onInputBlur), this._disabledObserver.disconnect();
175
- }
176
- updated(e) {
177
- if (e.has("placeholder")) {
178
- const t = this._$input();
179
- t && this._applyPlaceholder(t);
180
- }
181
- }
182
- _$input() {
183
- return this._$inputRef?.deref() ?? null;
184
- }
185
- _handleSlotChange() {
186
- this._inputController.sync();
187
- }
188
- _setupInput(e, t) {
189
- if (t && t !== e && (t.removeEventListener("input", this._onNativeInput), t.removeEventListener("focus", this._onInputFocus), t.removeEventListener("blur", this._onInputBlur)), this._disabledObserver.disconnect(), this._focused = !1, this._$inputRef = e ? new WeakRef(e) : null, this._hasInput = e !== null, this._authorPlaceholder = e?.hasAttribute("placeholder") ?? !1, !e) {
190
- this._hasValue = !1;
191
- return;
192
- }
193
- queueMicrotask(() => {
194
- e.isConnected && (this._valueSetByHost ? e.value = this._value ?? "" : e.value ? this._valueInitialized = !0 : this._defaultValue !== void 0 && !this._valueInitialized && (e.value = this._defaultValue), this._applyPlaceholder(e), this._disabledHost !== void 0 && (e.disabled = this._disabledHost), this._inputDisabled = e.disabled, this._hasValue = e.value.length > 0, this._bindInput(e));
195
- });
196
- }
197
- _bindInput(e) {
198
- e.addEventListener("input", this._onNativeInput), e.addEventListener("focus", this._onInputFocus), e.addEventListener("blur", this._onInputBlur), this._disabledObserver.observe(e, { attributeFilter: ["disabled"] });
199
- }
200
- _applyPlaceholder(e) {
201
- this.placeholder === void 0 || this._authorPlaceholder || (e.placeholder = this.placeholder);
202
- }
203
- _scheduleInputEvent(e) {
204
- if (this._cancelPendingInput(), this.debounce <= 0) {
205
- this._dispatchInput(e);
206
- return;
207
- }
208
- this._debounceTimer = setTimeout(() => {
209
- this._debounceTimer = void 0, this._dispatchInput(e);
210
- }, this.debounce);
211
- }
212
- _cancelPendingInput() {
213
- this._debounceTimer !== void 0 && (clearTimeout(this._debounceTimer), this._debounceTimer = void 0);
214
- }
215
- _dispatchInput(e) {
216
- this.dispatchEvent(
217
- new CustomEvent("rc-search-bar-input", {
218
- bubbles: !0,
219
- composed: !0,
220
- detail: { value: e }
221
- })
222
- );
223
- }
224
- _handleClear() {
225
- const e = this._$input();
226
- e && (this._cancelPendingInput(), e.value = "", this._valueInitialized = !0, this._hasValue = !1, this.dispatchEvent(
227
- new CustomEvent("rc-search-bar-clear", {
228
- bubbles: !0,
229
- composed: !0,
230
- detail: {}
231
- })
232
- ), this._dispatchInput(""), e.focus());
233
- }
234
- render() {
235
- return v`
236
- <div id="root" part="root" class=${d({ empty: !this._hasInput })} ${m({ attributeTarget: this })}>
237
- <span
238
- id="leading"
239
- part="leading"
240
- class=${d({ empty: !this._hasLeading || !this._hasInput })}
241
- >
242
- <slot name="leading" @slotchange=${this._onLeadingSlotChange}></slot>
243
- </span>
244
-
245
- <slot @slotchange=${this._handleSlotChange}></slot>
246
-
247
- <button
248
- id="clear"
249
- part="clear"
250
- type="button"
251
- aria-label=${this.clearLabel}
252
- ?hidden=${!this._hasInput}
253
- ?inert=${this._hasInput && !this._hasValue && !(this.showClearOnFocus && this._focused)}
254
- ?disabled=${this._inputDisabled}
255
- @click=${this._handleClear}
256
- >
257
- <slot name="clear-icon"><span aria-hidden="true">&#10005;</span></slot>
258
- </button>
259
-
260
- <span id="trailing" part="trailing" class=${d({ empty: !this._hasTrailing })}>
261
- <slot name="trailing" @slotchange=${this._onTrailingSlotChange}></slot>
262
- </span>
263
- </div>
264
- `;
265
- }
266
- /** Programmatically clears the value and fires rc-search-bar-clear + rc-search-bar-input. */
267
- clear() {
268
- this._handleClear();
269
- }
270
- _onLeadingSlotChange(e) {
271
- const t = e.target;
272
- this._hasLeading = t.assignedElements().length > 0;
273
- }
274
- _onTrailingSlotChange(e) {
275
- const t = e.target;
276
- this._hasTrailing = t.assignedElements().length > 0;
277
- }
278
- };
279
- u.styles = [y];
280
- let i = u;
281
- a([
282
- r({ type: Number })
283
- ], i.prototype, "debounce", 2);
284
- a([
285
- r({ type: String, attribute: "clear-label" })
286
- ], i.prototype, "clearLabel", 2);
287
- a([
288
- r({ type: Boolean, attribute: "allow-native-clear", reflect: !0 })
289
- ], i.prototype, "allowNativeClear", 2);
290
- a([
291
- r({ type: Boolean, attribute: "show-clear-on-focus" })
292
- ], i.prototype, "showClearOnFocus", 2);
293
- a([
294
- r({ type: Boolean, reflect: !0 })
295
- ], i.prototype, "disabled", 1);
296
- a([
297
- r({ type: String })
298
- ], i.prototype, "placeholder", 2);
299
- a([
300
- l()
301
- ], i.prototype, "_hasInput", 2);
302
- a([
303
- l()
304
- ], i.prototype, "_hasValue", 2);
305
- a([
306
- l()
307
- ], i.prototype, "_hasLeading", 2);
308
- a([
309
- l()
310
- ], i.prototype, "_hasTrailing", 2);
311
- a([
312
- l()
313
- ], i.prototype, "_inputDisabled", 2);
314
- a([
315
- l()
316
- ], i.prototype, "_focused", 2);
317
- a([
318
- r({ attribute: !1 })
319
- ], i.prototype, "value", 1);
320
- a([
321
- r({ type: String, attribute: "default-value" })
322
- ], i.prototype, "defaultValue", 1);
323
- export {
324
- i as R
325
- };
326
- //# sourceMappingURL=rc-search-bar-DVczVFvA.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rc-search-bar-DVczVFvA.js","sources":["../src/rc-search-bar.styles.ts","../src/rc-search-bar.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const searchBarStyles = css`\n :host {\n display: inline-flex;\n color-scheme: inherit;\n }\n\n [hidden] {\n display: none !important;\n }\n\n #root {\n display: flex;\n flex: 1 1 auto;\n align-items: center;\n min-inline-size: 0;\n gap: var(--rc-search-bar-gap, var(--rc-control-gap, 0.25em));\n block-size: var(--rc-search-bar-height, var(--rc-control-block-size, 2.5rem));\n padding-inline: var(--rc-search-bar-padding-inline, var(--rc-control-padding-inline, 0.75rem));\n border: var(--rc-search-bar-border, var(--rc-border, 1px solid var(--rc-border-color, ButtonBorder)));\n border-radius: var(--rc-search-bar-radius, var(--rc-control-radius, var(--rc-radius-sm, 0.125em)));\n box-shadow: var(--rc-search-bar-shadow, none);\n background: var(--rc-search-bar-bg, var(--rc-field, Field));\n color: var(--rc-search-bar-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: background-color 120ms, border-color 120ms, box-shadow 120ms;\n }\n\n :host([data-interaction-mode='keyboard']) #root:focus-within {\n outline: var(--rc-focus-ring, auto);\n outline-offset: var(--rc-focus-ring-offset, 0);\n }\n\n /* No slotted search input: render no chrome at all. */\n #root.empty {\n block-size: auto;\n padding: 0;\n background: none;\n border: none;\n box-shadow: none;\n border-radius: 0;\n }\n\n #leading {\n display: flex;\n flex: none;\n align-items: center;\n color: var(--rc-search-bar-icon-color, GrayText);\n }\n\n #leading.empty {\n display: none;\n }\n\n ::slotted(input[type='search']) {\n flex: 1 1 auto;\n min-inline-size: 0;\n padding: 0;\n border: none;\n background: transparent;\n color: var(--rc-search-bar-input-color, inherit);\n font-family: var(--rc-search-bar-input-font-family, inherit);\n font-size: var(--rc-search-bar-input-font-size, inherit);\n outline: none;\n appearance: textfield;\n }\n\n #trailing {\n display: flex;\n flex: none;\n align-items: center;\n }\n\n #trailing.empty {\n display: none;\n }\n\n #clear {\n display: inline-grid;\n flex: none;\n place-items: center;\n min-inline-size: 24px;\n min-block-size: 24px;\n padding: 0;\n border: none;\n border-radius: 50%;\n background: none;\n color: var(--rc-search-bar-clear-color, GrayText);\n font: inherit;\n cursor: pointer;\n }\n\n #clear[inert] {\n visibility: hidden;\n }\n\n #clear:focus-visible {\n outline: var(--rc-focus-ring, auto);\n outline-offset: var(--rc-focus-ring-offset, 0);\n }\n`;\n\nexport default searchBarStyles;\n","import { LitElement, html, type PropertyValues } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\n\nimport { NativeChildController, keyInteraction, warnMissingDirectChild } from '@rcarls/rc-common';\n\nimport searchBarStyles from './rc-search-bar.styles';\n\nconst _uaClearSheet = new CSSStyleSheet();\n_uaClearSheet.replaceSync(\n `rc-search-bar:not([allow-native-clear]) input[type=\"search\"]::-webkit-search-cancel-button\n { -webkit-appearance: none; display: none; }`,\n);\nlet _uaClearSuppressed = false;\n\nfunction _suppressUaClear(): void {\n if (_uaClearSuppressed) {\n return;\n }\n\n document.adoptedStyleSheets = [...document.adoptedStyleSheets, _uaClearSheet];\n\n _uaClearSuppressed = true;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'rc-search-bar': RCSearchBar;\n }\n}\n\nexport interface RCSearchBarInputDetail {\n /** The native input's value at dispatch time. */\n value: string;\n}\n\n/**\n * Search field wrapper for a native <input type=\"search\"> with icon chrome, clear button,\n * and debounced events.\n *\n * The native input is required and stays in light DOM as the source of\n * truth, so form submission, `label[for]`/wrapping-label association, and\n * pre-upgrade behavior are preserved. Without a slotted search input the\n * component renders no chrome and stays inert.\n *\n * The native WebKit cancel button is suppressed by default via an\n * adopted document stylesheet. Set `allow-native-clear` to restore it.\n * When restored, the native button clears through the normal input path\n * (a debounced `rc-search-bar-input` with an empty value) and never fires\n * `rc-search-bar-clear`.\n *\n * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-search-bar rc-search-bar docs}\n *\n * @slot - The required native `<input type=\"search\">`\n * @slot leading - Decorative leading icon; mark it `aria-hidden=\"true\"`\n * @slot trailing - Optional trailing content after the clear button\n * @slot clear-icon - Optional glyph replacing the default clear glyph\n *\n * @fires rc-search-bar-input - Debounced after typing, immediate on clear;\n * `detail: { value }`\n * @fires rc-search-bar-clear - When the clear button is activated\n *\n * @cssprop [--rc-search-bar-border=1px solid ButtonBorder] - Wrapper border; set to `none` in M3 theme (uses elevation instead)\n * @cssprop [--rc-search-bar-shadow=none] - Wrapper box-shadow for elevation; M3 theme sets Level 1 at rest\n * @cssprop [--rc-search-bar-bg=Field] - Wrapper background\n * @cssprop [--rc-search-bar-color=FieldText] - Wrapper text color\n * @cssprop [--rc-search-bar-icon-color=GrayText] - Leading icon color\n * @cssprop [--rc-search-bar-clear-color=GrayText] - Clear button glyph color\n * @cssprop [--rc-search-bar-radius=var(--rc-control-radius,0.125em)] - Wrapper border radius\n * @cssprop [--rc-search-bar-height=var(--rc-control-block-size,2.5rem)] - Wrapper block size\n * @cssprop [--rc-search-bar-padding-inline=var(--rc-control-padding-inline,0.75rem)] - Wrapper horizontal padding\n * @cssprop [--rc-search-bar-gap=var(--rc-control-gap,0.25em)] - Gap between icon, input, and clear button\n * @cssprop [--rc-search-bar-input-font-size] - Input font size (inherits when unset)\n * @cssprop [--rc-search-bar-input-font-family] - Input font family (inherits when unset)\n * @cssprop [--rc-search-bar-input-color] - Input text color (inherits when unset)\n * @csspart root - The wrapper element\n * @csspart leading - Wrapper around the leading icon slot\n * @csspart trailing - Wrapper around the trailing slot\n * @csspart clear - The clear button\n */\nexport class RCSearchBar extends LitElement {\n static styles = [searchBarStyles];\n\n /** Debounce window in ms for `rc-search-bar-input`; `0` dispatches synchronously. */\n @property({ type: Number })\n debounce = 200;\n\n /** Accessible label for the clear button. */\n @property({ type: String, attribute: 'clear-label' })\n clearLabel = 'Clear search';\n\n /** When set, leaves the browser's native WebKit cancel button visible. */\n @property({ type: Boolean, attribute: 'allow-native-clear', reflect: true })\n allowNativeClear = false;\n\n /**\n * When set, the clear button is visible whenever the input is focused.\n *\n * Matching the Apple HIG \"cancel\" pattern.\n * Consider setting `clear-label=\"Cancel\"` in this mode.\n */\n @property({ type: Boolean, attribute: 'show-clear-on-focus' })\n showClearOnFocus = false;\n\n /** Disables the component and mirrors the state to the slotted input. */\n @property({ type: Boolean, reflect: true })\n get disabled(): boolean {\n // _disabledHost holds what the host last set; fall back to what the input\n // actually reports (kept in sync by the MutationObserver).\n return this._disabledHost ?? this._inputDisabled;\n }\n set disabled(value: boolean) {\n const old = this.disabled;\n this._disabledHost = value;\n\n const $input = this._$input();\n if ($input) {\n $input.disabled = value;\n }\n\n this.requestUpdate('disabled', old);\n }\n\n /**\n * Placeholder mirrored onto the native input.\n *\n * Consumer `placeholder` attribute is always honored.\n */\n @property({ type: String })\n placeholder?: string;\n\n private _value: string | undefined = undefined;\n\n private _defaultValue: string | undefined = undefined;\n\n private _valueSetByHost = false;\n\n /** True once an author value, host write, or user input owns the value. */\n private _valueInitialized = false;\n\n private _authorPlaceholder = false;\n\n private _$inputRef: WeakRef<HTMLInputElement> | null = null;\n\n private _debounceTimer: ReturnType<typeof setTimeout> | undefined = undefined;\n\n @state()\n private _hasInput = false;\n\n @state()\n private _hasValue = false;\n\n @state()\n private _hasLeading = false;\n\n @state()\n private _hasTrailing = false;\n\n @state()\n private _inputDisabled = false;\n\n // Tracks the last value written via the disabled setter so the getter and\n // Lit's reflect can return it before the input is slotted.\n private _disabledHost: boolean | undefined = undefined;\n\n @state()\n private _focused = false;\n\n private readonly _onInputFocus = (): void => {\n this._focused = true;\n };\n\n private readonly _onInputBlur = (): void => {\n this._focused = false;\n };\n\n private readonly _disabledObserver = new MutationObserver(() => {\n const $input = this._$input();\n\n if ($input) {\n this._inputDisabled = $input.disabled;\n }\n });\n\n private readonly _inputController = new NativeChildController<HTMLInputElement>(this, {\n selector: ':scope > input[type=\"search\"]',\n observe: true,\n onChange: ($input, $previousInput) => this._setupInput($input, $previousInput),\n onMissing: () => {\n if (import.meta.env.DEV) {\n warnMissingDirectChild(this, {\n selector: ':scope > input[type=\"search\"]',\n message:\n '[rc-search-bar] No direct child <input type=\"search\"> found. ' +\n 'Place a native search input inside <rc-search-bar>.',\n });\n }\n },\n });\n\n /**\n * The current search value. Reads from the native input when present.\n * Host writes are silent (no events) and win over slotted author values.\n */\n @property({ attribute: false })\n get value(): string {\n return this._$input()?.value ?? this._value ?? this._defaultValue ?? '';\n }\n set value(value: string) {\n const oldValue = this.value;\n\n this._value = value;\n this._valueSetByHost = true;\n this._valueInitialized = true;\n\n const $input = this._$input();\n\n if ($input) {\n $input.value = value;\n }\n\n this._hasValue = value.length > 0;\n\n this.requestUpdate('value', oldValue);\n }\n\n /**\n * Initial uncontrolled value hint. Applied once, and only when neither an\n * author `value`, a host `value` write, nor user input owns the value.\n */\n @property({ type: String, attribute: 'default-value' })\n get defaultValue(): string | undefined {\n return this._defaultValue;\n }\n\n set defaultValue(value: string | undefined) {\n const oldValue = this._defaultValue;\n\n this._defaultValue = value;\n\n const $input = this._$input();\n if ($input && value !== undefined && !this._valueInitialized) {\n $input.value = value;\n this._hasValue = value.length > 0;\n }\n\n this.requestUpdate('defaultValue', oldValue);\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n\n _suppressUaClear();\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n\n this._focused = false;\n this._cancelPendingInput();\n\n const $input = this._$input();\n\n $input?.removeEventListener('input', this._onNativeInput);\n $input?.removeEventListener('focus', this._onInputFocus);\n $input?.removeEventListener('blur', this._onInputBlur);\n\n this._disabledObserver.disconnect();\n }\n\n protected override updated(changed: PropertyValues<this>): void {\n if (changed.has('placeholder')) {\n const $input = this._$input();\n\n if ($input) {\n this._applyPlaceholder($input);\n }\n }\n }\n\n private _$input(): HTMLInputElement | null {\n return this._$inputRef?.deref() ?? null;\n }\n\n private _handleSlotChange(): void {\n this._inputController.sync();\n }\n\n private _setupInput(\n $input: HTMLInputElement | null,\n $previousInput: HTMLInputElement | null,\n ): void {\n if ($previousInput && $previousInput !== $input) {\n $previousInput.removeEventListener('input', this._onNativeInput);\n $previousInput.removeEventListener('focus', this._onInputFocus);\n $previousInput.removeEventListener('blur', this._onInputBlur);\n }\n\n this._disabledObserver.disconnect();\n this._focused = false;\n\n this._$inputRef = $input ? new WeakRef($input) : null;\n this._hasInput = $input !== null;\n this._authorPlaceholder = $input?.hasAttribute('placeholder') ?? false;\n\n if (!$input) {\n this._hasValue = false;\n\n return;\n }\n\n // Deferred reads keep framework render cycles (e.g. SolidJS) untouched.\n queueMicrotask(() => {\n if (!$input.isConnected) {\n return;\n }\n\n if (this._valueSetByHost) {\n $input.value = this._value ?? '';\n } else if ($input.value) {\n // An author-provided value wins over defaultValue.\n this._valueInitialized = true;\n } else if (this._defaultValue !== undefined && !this._valueInitialized) {\n $input.value = this._defaultValue;\n }\n\n this._applyPlaceholder($input);\n\n if (this._disabledHost !== undefined) {\n $input.disabled = this._disabledHost;\n }\n\n this._inputDisabled = $input.disabled;\n this._hasValue = $input.value.length > 0;\n\n if (\n import.meta.env.DEV &&\n !$input.labels?.length &&\n !$input.getAttribute('aria-label') &&\n !$input.getAttribute('aria-labelledby')\n ) {\n console.warn(\n '[rc-search-bar] Slotted <input type=\"search\"> has no accessible name.',\n 'Add aria-label, wrap in <label>, or use <label for=\"...\">.',\n $input,\n );\n }\n\n this._bindInput($input);\n });\n }\n\n private _bindInput($input: HTMLInputElement): void {\n $input.addEventListener('input', this._onNativeInput);\n $input.addEventListener('focus', this._onInputFocus);\n $input.addEventListener('blur', this._onInputBlur);\n\n this._disabledObserver.observe($input, { attributeFilter: ['disabled'] });\n }\n\n private _applyPlaceholder($input: HTMLInputElement): void {\n if (this.placeholder === undefined || this._authorPlaceholder) {\n return;\n }\n\n $input.placeholder = this.placeholder;\n }\n\n private readonly _onNativeInput = (e: Event): void => {\n const $input = e.currentTarget as HTMLInputElement;\n\n this._valueInitialized = true;\n this._hasValue = $input.value.length > 0;\n this._scheduleInputEvent($input.value);\n };\n\n private _scheduleInputEvent(value: string): void {\n this._cancelPendingInput();\n\n if (this.debounce <= 0) {\n this._dispatchInput(value);\n\n return;\n }\n\n this._debounceTimer = setTimeout(() => {\n this._debounceTimer = undefined;\n this._dispatchInput(value);\n }, this.debounce);\n }\n\n private _cancelPendingInput(): void {\n if (this._debounceTimer === undefined) {\n return;\n }\n\n clearTimeout(this._debounceTimer);\n this._debounceTimer = undefined;\n }\n\n private _dispatchInput(value: string): void {\n this.dispatchEvent(\n new CustomEvent<RCSearchBarInputDetail>('rc-search-bar-input', {\n bubbles: true,\n composed: true,\n detail: { value },\n }),\n );\n }\n\n private _handleClear(): void {\n const $input = this._$input();\n\n if (!$input) {\n return;\n }\n\n this._cancelPendingInput();\n\n $input.value = '';\n\n this._valueInitialized = true;\n this._hasValue = false;\n\n this.dispatchEvent(\n new CustomEvent('rc-search-bar-clear', {\n bubbles: true,\n composed: true,\n detail: {},\n }),\n );\n this._dispatchInput('');\n\n // Refocus before the re-render hides the button, so focus never drops\n // to <body>.\n $input.focus();\n }\n\n protected override render() {\n return html`\n <div id=\"root\" part=\"root\" class=${classMap({ empty: !this._hasInput })} ${keyInteraction({ attributeTarget: this })}>\n <span\n id=\"leading\"\n part=\"leading\"\n class=${classMap({ empty: !this._hasLeading || !this._hasInput })}\n >\n <slot name=\"leading\" @slotchange=${this._onLeadingSlotChange}></slot>\n </span>\n\n <slot @slotchange=${this._handleSlotChange}></slot>\n\n <button\n id=\"clear\"\n part=\"clear\"\n type=\"button\"\n aria-label=${this.clearLabel}\n ?hidden=${!this._hasInput}\n ?inert=${this._hasInput && !this._hasValue && !(this.showClearOnFocus && this._focused)}\n ?disabled=${this._inputDisabled}\n @click=${this._handleClear}\n >\n <slot name=\"clear-icon\"><span aria-hidden=\"true\">&#10005;</span></slot>\n </button>\n\n <span id=\"trailing\" part=\"trailing\" class=${classMap({ empty: !this._hasTrailing })}>\n <slot name=\"trailing\" @slotchange=${this._onTrailingSlotChange}></slot>\n </span>\n </div>\n `;\n }\n\n /** Programmatically clears the value and fires rc-search-bar-clear + rc-search-bar-input. */\n public clear(): void {\n this._handleClear();\n }\n\n private _onLeadingSlotChange(e: Event): void {\n const $slot = e.target as HTMLSlotElement;\n\n this._hasLeading = $slot.assignedElements().length > 0;\n }\n\n private _onTrailingSlotChange(e: Event): void {\n const $slot = e.target as HTMLSlotElement;\n\n this._hasTrailing = $slot.assignedElements().length > 0;\n }\n}\n\nexport default RCSearchBar;\n"],"names":["searchBarStyles","css","_uaClearSheet","_uaClearSuppressed","_suppressUaClear","_RCSearchBar","LitElement","$input","NativeChildController","$previousInput","value","old","oldValue","changed","html","classMap","keyInteraction","$slot","RCSearchBar","__decorateClass","property","state"],"mappings":"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"}