@rcarls/rc-search-bar 0.6.0 → 0.7.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 CHANGED
@@ -1,5 +1,124 @@
1
1
  # @rcarls/rc-search-bar
2
2
 
3
+ ## 0.7.0
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
+ - 54d9ead: Localize every component's built-in text. Button names, role
39
+ descriptions, announcements, and default labels now resolve per key from
40
+ the element's `messages` property, then from text registered with
41
+ `registerMessages(locale, catalog)` in `@rcarls/rc-common`, then from the
42
+ English defaults. The locale is the element's own `lang`, else
43
+ `<html lang>`; an ancestor's `lang` is ignored, because it usually marks
44
+ content rather than the interface. Components re-render when that locale
45
+ changes or new text is registered. `RcMessageCatalog` types the catalog,
46
+ and each package adds its scope to it.
47
+
48
+ Numbers a component formats as text follow the same locale:
49
+ `rc-progress`'s default percentage and `rc-splitter`'s `aria-valuetext`
50
+ use `Intl.NumberFormat`. `TypeaheadController` matches prefixes with an
51
+ `Intl.Collator`, so case and accents are ignored the way the locale
52
+ ignores them, and takes a `locale` option. `ItemsCollectionController`'s
53
+ `setCreateOption(text, label?)` takes the option's visible text from its
54
+ caller.
55
+
56
+ `rc-transfer-list`'s direction arrows are now decorative: screen readers
57
+ read only the action name, and the arrows turn over in RTL.
58
+
59
+ **Breaking:** chrome-text properties are replaced by `messages`. Migrate:
60
+
61
+ - `rc-search-bar` `clear-label` / `clearLabel` → `messages.clear`
62
+ - `rc-adaptive-menu` `overflow-label` / `overflowLabel` → `messages.overflow`
63
+ - `rc-chip-group` `show-all-label` / `showAllLabel` and `show-less-label` /
64
+ `showLessLabel` → `messages.showAll` and `messages.showLess`
65
+ - `rc-select` and `rc-combobox` `dialog-confirm-label` /
66
+ `dialogConfirmLabel` and `dialog-cancel-label` / `dialogCancelLabel` →
67
+ `messages.done` and `messages.cancel`
68
+ - `rc-editor-toolbar` `label` → `messages.toolbar`
69
+
70
+ Per-instance names stay attributes, but now default to `undefined` and fall
71
+ back to a message: `label` on `rc-adaptive-menu`, `rc-chip-group`,
72
+ `rc-menubar`, and `rc-splitter`; `available-label` and `selected-label`
73
+ on `rc-transfer-list`; `low-label` and `high-label` on `rc-range-slider`.
74
+ Read the resolved name from the rendered `aria-label` instead of the
75
+ property.
76
+
77
+ ### Patch Changes
78
+
79
+ - 5c006de: Ship component CSS minified. Package builds now run the CSS in Lit `css` styles
80
+ and light-DOM structural styles through Lightning CSS, removing comments and
81
+ whitespace while keeping source maps that resolve to each template. Rendered
82
+ styles are unchanged.
83
+
84
+ `@rcarls/rc-common` adds `cssText`, an identity tag that marks a plain CSS
85
+ string for minification. `rc-chip`, `rc-disclosure`, and `rc-accordion` now
86
+ depend on `@rcarls/rc-common` for it.
87
+
88
+ - 2599c19: With `show-clear-on-focus`, Tab from the input now lands on the clear button and keeps focus there. The search bar stays focused while focus moves between its input and its own controls, so the button no longer turns inert while receiving focus and drops it to the page.
89
+ - Updated dependencies [e3dfa59]
90
+ - Updated dependencies [50d5610]
91
+ - Updated dependencies [9ee769c]
92
+ - Updated dependencies [1179f24]
93
+ - Updated dependencies [595fe37]
94
+ - Updated dependencies [38cd00c]
95
+ - Updated dependencies [5c006de]
96
+ - Updated dependencies [a6553ff]
97
+ - Updated dependencies [2205478]
98
+ - Updated dependencies [4341311]
99
+ - Updated dependencies [899bb5e]
100
+ - Updated dependencies [25fcfe0]
101
+ - Updated dependencies [51f6403]
102
+ - Updated dependencies [9caca6b]
103
+ - Updated dependencies [b764a3c]
104
+ - Updated dependencies [54d9ead]
105
+ - Updated dependencies [b9175e9]
106
+ - Updated dependencies [c8b762b]
107
+ - Updated dependencies [55e1e7f]
108
+ - Updated dependencies [f1ca82d]
109
+ - Updated dependencies [b87f27b]
110
+ - Updated dependencies [32ebead]
111
+ - Updated dependencies [bfefedd]
112
+ - Updated dependencies [c130173]
113
+ - Updated dependencies [11680b6]
114
+ - Updated dependencies [223d36c]
115
+ - Updated dependencies [7b91a44]
116
+ - Updated dependencies [aa04ead]
117
+ - Updated dependencies [ac65b5b]
118
+ - Updated dependencies [afcfef8]
119
+ - Updated dependencies [11ef1ad]
120
+ - @rcarls/rc-common@0.7.0
121
+
3
122
  ## 0.6.0
4
123
 
5
124
  ### Patch Changes
package/README.md CHANGED
@@ -43,9 +43,9 @@ import { RCSearchBar } from '@rcarls/rc-search-bar';
43
43
  </script>
44
44
  ```
45
45
 
46
- The component's shadow CSS already strips the slotted input's native border,
47
- background, and outline so it blends into the wrapper chrome without a consumer
48
- reset.
46
+ The component's `rc-base` light-DOM layer strips the slotted input's native
47
+ border, background, and outline so it blends into the wrapper chrome without a
48
+ consumer reset. Normal author rules outside a layer override that structural base.
49
49
 
50
50
  The native WebKit cancel button is suppressed automatically. Set
51
51
  `allow-native-clear` to restore it.
@@ -56,18 +56,18 @@ The native WebKit cancel button is suppressed automatically. Set
56
56
 
57
57
  ### Properties / attributes
58
58
 
59
- | Property | Attribute | Type | Default | Description |
60
- | ------------------ | --------------------- | --------------------- | ---------------- | --------------------------------------------------------------------------------------- |
61
- | `variant` | `variant` | `'bar' \| 'view'` | `'bar'` | Presentation mode: docked field or expandable search view |
62
- | `open` | `open` | `boolean` | `false` | Controlled search view open state; host writes are silent |
63
- | `defaultOpen` | `default-open` | `boolean` | `false` | Initial uncontrolled search view open state |
64
- | `value` | None | `string` | `''` | Current search value; reads from the native input, host writes are silent |
65
- | `defaultValue` | `default-value` | `string \| undefined` | `undefined` | Initial uncontrolled value hint, applied once |
66
- | `debounce` | `debounce` | `number` | `200` | Debounce window in ms for `rc-search-bar-input`; `0` dispatches synchronously |
67
- | `clearLabel` | `clear-label` | `string` | `'Clear search'` | Accessible label for the clear button |
68
- | `allowNativeClear` | `allow-native-clear` | `boolean` | `false` | When set, restores the browser's native WebKit cancel button |
69
- | `showClearOnFocus` | `show-clear-on-focus` | `boolean` | `false` | When set, shows the clear button on focus even with no value (Apple HIG cancel pattern) |
70
- | `placeholder` | `placeholder` | `string \| undefined` | `undefined` | Mirrored onto the input unless the author already set one |
59
+ | Property | Attribute | Type | Default | Description |
60
+ | ------------------ | --------------------- | ------------------------------------------- | ----------- | --------------------------------------------------------------------------------------- |
61
+ | `variant` | `variant` | `'bar' \| 'view'` | `'bar'` | Presentation mode: docked field or expandable search view |
62
+ | `open` | `open` | `boolean` | `false` | Controlled search view open state; host writes are silent |
63
+ | `defaultOpen` | `default-open` | `boolean` | `false` | Initial uncontrolled search view open state |
64
+ | `value` | None | `string` | `''` | Current search value; reads from the native input, host writes are silent |
65
+ | `defaultValue` | `default-value` | `string \| undefined` | `undefined` | Initial uncontrolled value hint, applied once |
66
+ | `debounce` | `debounce` | `number` | `200` | Debounce window in ms for `rc-search-bar-input`; `0` dispatches synchronously |
67
+ | `allowNativeClear` | `allow-native-clear` | `boolean` | `false` | When set, restores the browser's native WebKit cancel button |
68
+ | `showClearOnFocus` | `show-clear-on-focus` | `boolean` | `false` | When set, shows the clear button on focus even with no value (Apple HIG cancel pattern) |
69
+ | `placeholder` | `placeholder` | `string \| undefined` | `undefined` | Mirrored onto the input unless the author already set one |
70
+ | `messages` | None | `Partial<RCSearchBarMessages> \| undefined` | `undefined` | Built-in text overrides; see Localization |
71
71
 
72
72
  ### CSS custom properties
73
73
 
@@ -141,6 +141,14 @@ icons, supporting text, actions, or stronger AT/styling control.
141
141
 
142
142
  ---
143
143
 
144
+ ## Localization
145
+
146
+ Built-in text follows the element's own `lang`, else `<html lang>`, and never an
147
+ ancestor's `lang`, which usually marks content. Override it per element with the
148
+ `messages` property, or for every instance with `registerMessages()` from
149
+ `@rcarls/rc-common` under `rc-search-bar`. Keys: `clear`. See the
150
+ [rc-common Localization section](https://github.com/richardcarls/rc-webcomponents/tree/develop/packages/rc-common#localization).
151
+
144
152
  ## Accessibility notes
145
153
 
146
154
  - The component writes no ARIA to the input because `type="search"` already exposes
@@ -148,14 +156,14 @@ icons, supporting text, actions, or stronger AT/styling control.
148
156
  input with `label[for]`, a wrapping `<label>`, or `aria-label`.
149
157
  - The component adds no `role="search"` landmark; wrap in `<search>` or
150
158
  `<form role="search">` when the bar is the page's search landmark.
151
- - The clear button is a real `<button>` with a configurable `aria-label`
152
- (`clear-label`) and a ≥24×24 px hit target. Activating it returns focus to
159
+ - The clear button is a real `<button>` with a localizable `aria-label`
160
+ (the `clear` message) and a ≥24×24 px hit target. Activating it returns focus to
153
161
  the input before the button hides, so focus is never dropped.
154
162
  - The native WebKit cancel button is suppressed automatically via an adopted
155
163
  document stylesheet. Set `allow-native-clear` to restore it. When restored,
156
164
  it clears through the normal input path (a debounced `rc-search-bar-input`
157
165
  with an empty value) and never fires `rc-search-bar-clear`.
158
166
  - Set `show-clear-on-focus` to show the clear button whenever the input is
159
- focused (Apple HIG cancel pattern). Consider `clear-label="Cancel"` in this
160
- mode. The `rc-search-bar-clear` event fires even when the value is empty,
167
+ focused (Apple HIG cancel pattern). Consider setting the `clear` message to
168
+ `Cancel` in this mode. The `rc-search-bar-clear` event fires even when the value is empty,
161
169
  allowing the host to dismiss a search overlay.
@@ -44,9 +44,16 @@
44
44
  "kind": "javascript-module",
45
45
  "path": "src/rc-search-bar.ts",
46
46
  "declarations": [
47
+ {
48
+ "kind": "variable",
49
+ "name": "DEFAULT_SEARCH_BAR_MESSAGES",
50
+ "type": {
51
+ "text": "Readonly<RCSearchBarMessages>"
52
+ }
53
+ },
47
54
  {
48
55
  "kind": "class",
49
- "description": "Search field wrapper for a native <input type=\"search\"> with icon chrome, clear button,\nand debounced events.\n\nThe native input is required and stays in light DOM as the source of\ntruth, so form submission, `label[for]`/wrapping-label association, and\npre-upgrade behavior are preserved. Without a slotted search input the\ncomponent renders no chrome and stays inert.\n\nThe native WebKit cancel button is suppressed by default via an\nadopted document stylesheet. Set `allow-native-clear` to restore it.\nWhen 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`.",
56
+ "description": "Search field wrapper for a native <input type=\"search\"> with icon chrome, clear button,\nand debounced events.\n\nThe native input is required and stays in light DOM as the source of\ntruth, so form submission, `label[for]`/wrapping-label association, and\npre-upgrade behavior are preserved. Without a slotted search input the\ncomponent renders no chrome and stays inert.\n\nThe native WebKit cancel button is suppressed by default via an\nadopted document stylesheet. Set `allow-native-clear` to restore it.\nWhen 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\nBuilt-in text (the clear button name) follows the element's own `lang`, else\n`<html lang>`: per element through `messages`, or for every instance\nthrough `registerMessages()` from `@rcarls/rc-common` under `rc-search-bar`.",
50
57
  "name": "RCSearchBar",
51
58
  "cssProperties": [
52
59
  {
@@ -215,6 +222,21 @@
215
222
  }
216
223
  ],
217
224
  "members": [
225
+ {
226
+ "kind": "field",
227
+ "name": "messages",
228
+ "type": {
229
+ "text": "Partial<RCSearchBarMessages> | undefined"
230
+ },
231
+ "description": "Built-in text overrides; unset keys fall back to registered text, then English."
232
+ },
233
+ {
234
+ "kind": "field",
235
+ "name": "_messages",
236
+ "privacy": "private",
237
+ "readonly": true,
238
+ "default": "new MessagesController( this, 'rc-search-bar', DEFAULT_SEARCH_BAR_MESSAGES, { overrides: () => this.messages, }, )"
239
+ },
218
240
  {
219
241
  "kind": "field",
220
242
  "name": "_styledRoots",
@@ -263,16 +285,6 @@
263
285
  "description": "Debounce window in ms for `rc-search-bar-input`; `0` dispatches synchronously.",
264
286
  "attribute": "debounce"
265
287
  },
266
- {
267
- "kind": "field",
268
- "name": "clearLabel",
269
- "type": {
270
- "text": "string"
271
- },
272
- "default": "'Clear search'",
273
- "description": "Accessible label for the clear button.",
274
- "attribute": "clear-label"
275
- },
276
288
  {
277
289
  "kind": "field",
278
290
  "name": "allowNativeClear",
@@ -291,7 +303,7 @@
291
303
  "text": "boolean"
292
304
  },
293
305
  "default": "false",
294
- "description": "When set, the clear button is visible whenever the input is focused.\n\nMatching the Apple HIG \"cancel\" pattern.\nConsider setting `clear-label=\"Cancel\"` in this mode.",
306
+ "description": "When set, the clear button is visible whenever the input is focused.\n\nMatching the Apple HIG \"cancel\" pattern.\nConsider setting `messages.clear` to `Cancel` in this mode.",
295
307
  "attribute": "show-clear-on-focus"
296
308
  },
297
309
  {
@@ -506,6 +518,30 @@
506
518
  "privacy": "private",
507
519
  "readonly": true
508
520
  },
521
+ {
522
+ "kind": "field",
523
+ "name": "_onHostFocusOut",
524
+ "privacy": "private",
525
+ "readonly": true
526
+ },
527
+ {
528
+ "kind": "method",
529
+ "name": "_containsFocusTarget",
530
+ "privacy": "private",
531
+ "return": {
532
+ "type": {
533
+ "text": "boolean"
534
+ }
535
+ },
536
+ "parameters": [
537
+ {
538
+ "name": "target",
539
+ "type": {
540
+ "text": "EventTarget | null"
541
+ }
542
+ }
543
+ ]
544
+ },
509
545
  {
510
546
  "kind": "field",
511
547
  "name": "_disabledObserver",
@@ -916,15 +952,6 @@
916
952
  "default": "200",
917
953
  "fieldName": "debounce"
918
954
  },
919
- {
920
- "description": "Accessible label for the clear button.",
921
- "name": "clear-label",
922
- "type": {
923
- "text": "string"
924
- },
925
- "default": "'Clear search'",
926
- "fieldName": "clearLabel"
927
- },
928
955
  {
929
956
  "description": "When set, leaves the browser's native WebKit cancel button visible.",
930
957
  "name": "allow-native-clear",
@@ -935,7 +962,7 @@
935
962
  "fieldName": "allowNativeClear"
936
963
  },
937
964
  {
938
- "description": "When set, the clear button is visible whenever the input is focused.\n\nMatching the Apple HIG \"cancel\" pattern.\nConsider setting `clear-label=\"Cancel\"` in this mode.",
965
+ "description": "When set, the clear button is visible whenever the input is focused.\n\nMatching the Apple HIG \"cancel\" pattern.\nConsider setting `messages.clear` to `Cancel` in this mode.",
939
966
  "name": "show-clear-on-focus",
940
967
  "type": {
941
968
  "text": "boolean"
@@ -993,6 +1020,14 @@
993
1020
  }
994
1021
  ],
995
1022
  "exports": [
1023
+ {
1024
+ "kind": "js",
1025
+ "name": "DEFAULT_SEARCH_BAR_MESSAGES",
1026
+ "declaration": {
1027
+ "name": "DEFAULT_SEARCH_BAR_MESSAGES",
1028
+ "module": "src/rc-search-bar.ts"
1029
+ }
1030
+ },
996
1031
  {
997
1032
  "kind": "js",
998
1033
  "name": "RCSearchBar",
@@ -1,230 +1,36 @@
1
- import { css as v, LitElement as _, html as u, nothing as b } from "lit";
1
+ import { css as _, LitElement as v, html as d, nothing as b } from "lit";
2
2
  import { property as r, state as o } from "lit/decorators.js";
3
3
  import { classMap as h } from "lit/directives/class-map.js";
4
- import { NativeChildController as f, keyInteraction as g } from "@rcarls/rc-common";
5
- const m = v`
6
- :host {
7
- display: inline-flex;
8
- position: relative;
9
- color-scheme: inherit;
10
- }
11
-
12
- [hidden] {
13
- display: none !important;
14
- }
15
-
16
- #root {
17
- display: flex;
18
- flex: 1 1 auto;
19
- align-items: center;
20
- min-inline-size: 0;
21
- gap: var(--rc-search-bar-gap, var(--rc-control-gap, 0.25em));
22
- block-size: var(--rc-search-bar-height, var(--rc-control-block-size, 2.5rem));
23
- padding-inline: var(--rc-search-bar-padding-inline, var(--rc-control-padding-inline, 0.75rem));
24
- border: var(
25
- --rc-search-bar-border,
26
- var(--rc-border, 1px solid var(--rc-border-color, ButtonBorder))
27
- );
28
- border-radius: var(
29
- --rc-search-bar-radius,
30
- var(--rc-control-radius, var(--rc-radius-sm, 0.125em))
31
- );
32
- box-shadow: var(--rc-search-bar-shadow, none);
33
- background: var(--rc-search-bar-bg, var(--rc-field, Field));
34
- color: var(--rc-search-bar-color, var(--rc-field-text, FieldText));
35
- font-family: var(--rc-font-family, inherit);
36
- font-size: var(--rc-font-size, inherit);
37
- line-height: var(--rc-line-height, normal);
38
- transition:
39
- background-color 120ms,
40
- border-color 120ms,
41
- box-shadow 120ms;
42
- }
43
-
44
- :host([data-interaction-mode='keyboard']) #root:focus-within {
45
- outline: var(--rc-focus-ring, auto);
46
- outline-offset: var(--rc-focus-ring-offset, 0);
47
- }
48
-
49
- /* No slotted search input: render no chrome at all. */
50
- #root.empty {
51
- block-size: auto;
52
- padding: 0;
53
- background: none;
54
- border: none;
55
- box-shadow: none;
56
- border-radius: 0;
57
- }
58
-
59
- #leading {
60
- display: flex;
61
- flex: none;
62
- align-items: center;
63
- color: var(--rc-search-bar-icon-color, GrayText);
64
- }
65
-
66
- #leading.empty {
67
- display: none;
68
- }
69
-
70
- ::slotted(input[type='search']) {
71
- flex: 1 1 auto;
72
- min-inline-size: 0;
73
- padding: 0;
74
- border: none;
75
- background: transparent;
76
- color: var(--rc-search-bar-input-color, inherit);
77
- font-family: var(--rc-search-bar-input-font-family, inherit);
78
- font-size: var(--rc-search-bar-input-font-size, inherit);
79
- outline: none;
80
- appearance: textfield;
81
- }
82
-
83
- #trailing {
84
- display: flex;
85
- flex: none;
86
- align-items: center;
87
- }
88
-
89
- #trailing.empty {
90
- display: none;
91
- }
92
-
93
- #clear {
94
- display: inline-grid;
95
- flex: none;
96
- place-items: center;
97
- min-inline-size: 24px;
98
- min-block-size: 24px;
99
- padding: 0;
100
- border: none;
101
- border-radius: 50%;
102
- background: none;
103
- color: var(--rc-search-bar-clear-color, GrayText);
104
- font: inherit;
105
- cursor: pointer;
106
- }
107
-
108
- #clear[inert] {
109
- visibility: hidden;
110
- }
111
-
112
- #clear:focus-visible {
113
- outline: var(--rc-focus-ring, auto);
114
- outline-offset: var(--rc-focus-ring-offset, 0);
115
- }
116
-
117
- #view {
118
- position: absolute;
119
- z-index: 1;
120
- inset-block-start: calc(100% + var(--rc-search-bar-view-offset, 0.25rem));
121
- inset-inline: 0;
122
- min-inline-size: 100%;
123
- }
124
-
125
- #view-surface {
126
- box-sizing: border-box;
127
- padding-block: var(--rc-search-bar-view-padding-block, 0.5rem);
128
- border: var(
129
- --rc-search-bar-view-border,
130
- var(--rc-search-bar-border, var(--rc-border, 1px solid var(--rc-border-color, ButtonBorder)))
131
- );
132
- border-radius: var(
133
- --rc-search-bar-view-radius,
134
- var(--rc-search-bar-radius, var(--rc-control-radius, var(--rc-radius-sm, 0.125em)))
135
- );
136
- box-shadow: var(--rc-search-bar-view-shadow, var(--rc-search-bar-shadow, none));
137
- background: var(--rc-search-bar-view-bg, var(--rc-search-bar-bg, var(--rc-field, Field)));
138
- color: var(
139
- --rc-search-bar-view-color,
140
- var(--rc-search-bar-color, var(--rc-field-text, FieldText))
141
- );
142
- font-family: var(--rc-font-family, inherit);
143
- font-size: var(--rc-font-size, inherit);
144
- }
145
-
146
- #view-surface.empty {
147
- display: none;
148
- }
149
-
150
- #suggestions {
151
- display: flex;
152
- flex-direction: column;
153
- }
154
-
155
- #suggestions ::slotted(*) {
156
- min-inline-size: 0;
157
- }
158
-
159
- [part='suggestion'] {
160
- display: flex;
161
- align-items: center;
162
- min-block-size: var(--rc-search-bar-suggestion-min-block-size, 2.75rem);
163
- padding-block: 0;
164
- padding-inline: var(--rc-search-bar-suggestion-padding-inline, 1rem);
165
- border: 0;
166
- background: transparent;
167
- color: inherit;
168
- font: inherit;
169
- text-align: start;
170
- cursor: pointer;
171
- }
172
-
173
- [part='suggestion']:hover,
174
- [part='suggestion']:focus-visible {
175
- background: var(--rc-search-bar-suggestion-hover-bg, ButtonFace);
176
- }
177
-
178
- [part='suggestion']:focus-visible {
179
- outline: var(--rc-focus-ring, auto);
180
- outline-offset: var(--rc-focus-ring-offset, 0);
181
- }
182
- `;
183
- var y = Object.defineProperty, w = Object.getOwnPropertyDescriptor, a = (p, e, t, i) => {
184
- for (var l = i > 1 ? void 0 : i ? w(e, t) : e, c = p.length - 1, d; c >= 0; c--)
185
- (d = p[c]) && (l = (i ? d(e, t, l) : d(l)) || l);
186
- return i && l && y(e, t, l), l;
4
+ import { MessagesController as f, NativeChildController as g, keyInteraction as m, cssText as y } from "@rcarls/rc-common";
5
+ const w = _`:host{color-scheme:inherit;display:inline-flex;position:relative}[hidden]{display:none!important}#root{align-items:center;gap:var(--rc-search-bar-gap,var(--rc-control-gap,.25em));min-inline-size:0;block-size:var(--rc-search-bar-height,var(--rc-control-block-size,2.5rem));padding-inline:var(--rc-search-bar-padding-inline,var(--rc-control-padding-inline,.75rem));border:var(--rc-search-bar-border,var(--rc-border,1px solid var(--rc-border-color,ButtonBorder)));border-radius:var(--rc-search-bar-radius,var(--rc-control-radius,var(--rc-radius-sm,.125em)));box-shadow:var(--rc-search-bar-shadow,none);background:var(--rc-search-bar-bg,var(--rc-field,Field));color:var(--rc-search-bar-color,var(--rc-field-text,FieldText));font-family:var(--rc-font-family,inherit);font-size:var(--rc-font-size,inherit);line-height:var(--rc-line-height,normal);flex:auto;transition:background-color .12s,border-color .12s,box-shadow .12s;display:flex}:host([data-interaction-mode=keyboard]) #root:focus-within{outline:var(--rc-focus-ring,auto);outline-offset:var(--rc-focus-ring-offset,0)}#root.empty{block-size:auto;box-shadow:none;background:0 0;border:none;border-radius:0;padding:0}#leading{color:var(--rc-search-bar-icon-color,GrayText);flex:none;align-items:center;display:flex}#leading.empty{display:none}::slotted(input[type=search]){min-inline-size:0;color:var(--rc-search-bar-input-color,inherit);font-family:var(--rc-search-bar-input-font-family,inherit);font-size:var(--rc-search-bar-input-font-size,inherit);appearance:textfield;background:0 0;border:none;outline:none;flex:auto;padding:0}#trailing{flex:none;align-items:center;display:flex}#trailing.empty{display:none}#clear{min-block-size:24px;min-inline-size:24px;color:var(--rc-search-bar-clear-color,GrayText);font:inherit;cursor:pointer;background:0 0;border:none;border-radius:50%;flex:none;place-items:center;padding:0;display:inline-grid}#clear[inert]{visibility:hidden}#clear:focus-visible{outline:var(--rc-focus-ring,auto);outline-offset:var(--rc-focus-ring-offset,0)}#view{z-index:1;min-inline-size:100%;position:absolute;inset-block-start:calc(100% + var(--rc-search-bar-view-offset,.25rem));inset-inline:0}#view-surface{box-sizing:border-box;padding-block:var(--rc-search-bar-view-padding-block,.5rem);border:var(--rc-search-bar-view-border,var(--rc-search-bar-border,var(--rc-border,1px solid var(--rc-border-color,ButtonBorder))));border-radius:var(--rc-search-bar-view-radius,var(--rc-search-bar-radius,var(--rc-control-radius,var(--rc-radius-sm,.125em))));box-shadow:var(--rc-search-bar-view-shadow,var(--rc-search-bar-shadow,none));background:var(--rc-search-bar-view-bg,var(--rc-search-bar-bg,var(--rc-field,Field)));color:var(--rc-search-bar-view-color,var(--rc-search-bar-color,var(--rc-field-text,FieldText)));font-family:var(--rc-font-family,inherit);font-size:var(--rc-font-size,inherit)}#view-surface.empty{display:none}#suggestions{flex-direction:column;display:flex}#suggestions ::slotted(*){min-inline-size:0}[part=suggestion]{min-block-size:var(--rc-search-bar-suggestion-min-block-size,2.75rem);padding-block:0;padding-inline:var(--rc-search-bar-suggestion-padding-inline,1rem);color:inherit;font:inherit;text-align:start;cursor:pointer;background:0 0;border:0;align-items:center;display:flex}[part=suggestion]:hover,[part=suggestion]:focus-visible{background:var(--rc-search-bar-suggestion-hover-bg,ButtonFace)}[part=suggestion]:focus-visible{outline:var(--rc-focus-ring,auto);outline-offset:var(--rc-focus-ring-offset,0)}`;
6
+ var S = Object.defineProperty, L = Object.getOwnPropertyDescriptor, a = (p, e, t, s) => {
7
+ for (var l = s > 1 ? void 0 : s ? L(e, t) : e, c = p.length - 1, u; c >= 0; c--)
8
+ (u = p[c]) && (l = (s ? u(e, t, l) : u(l)) || l);
9
+ return s && l && S(e, t, l), l;
187
10
  };
188
- const S = `
189
- rc-search-bar > input[type='search'] {
190
- flex: 1 1 auto;
191
- min-inline-size: 0;
192
- min-block-size: 0;
193
- padding: 0;
194
- border: 0;
195
- border-radius: 0;
196
- background: transparent;
197
- color: var(--rc-search-bar-input-color, inherit);
198
- font-family: var(--rc-search-bar-input-font-family, inherit);
199
- font-size: var(--rc-search-bar-input-font-size, inherit);
200
- outline: 0;
201
- box-shadow: none;
202
- appearance: textfield;
203
- }
204
-
205
- rc-search-bar > input[type='search']:focus-visible {
206
- border: 0;
207
- outline: 0;
208
- box-shadow: none;
209
- }
210
-
211
- rc-search-bar:not([allow-native-clear])
212
- > input[type='search']::-webkit-search-cancel-button {
213
- -webkit-appearance: none;
214
- display: none;
215
- }
216
- `;
11
+ const I = y`@layer rc-base{rc-search-bar>input[type=search]{min-block-size:0;min-inline-size:0;color:var(--rc-search-bar-input-color,inherit);font-family:var(--rc-search-bar-input-font-family,inherit);font-size:var(--rc-search-bar-input-font-size,inherit);box-shadow:none;appearance:textfield;background:0 0;border:0;border-radius:0;outline:0;flex:auto;padding:0}rc-search-bar>input[type=search]:focus-visible{box-shadow:none;border:0;outline:0}rc-search-bar:not([allow-native-clear])>input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none;display:none}}`, x = Object.freeze({
12
+ clear: "Clear search"
13
+ });
217
14
  var n;
218
- const s = (n = class extends _ {
15
+ const i = (n = class extends v {
219
16
  constructor() {
220
- super(...arguments), this.variant = "bar", this.debounce = 200, this.clearLabel = "Clear search", this.allowNativeClear = !1, this.showClearOnFocus = !1, this._open = !1, this._defaultOpen = !1, this._openInitialized = !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._$dataListRef = null, this._hasInput = !1, this._hasValue = !1, this._hasLeading = !1, this._hasTrailing = !1, this._inputDisabled = !1, this._hasSuggestionsSlot = !1, this._dataListSuggestions = [], this._disabledHost = void 0, this._focused = !1, this._onInputFocus = () => {
17
+ super(...arguments), this._messages = new f(
18
+ this,
19
+ "rc-search-bar",
20
+ x,
21
+ {
22
+ overrides: () => this.messages
23
+ }
24
+ ), this.variant = "bar", this.debounce = 200, this.allowNativeClear = !1, this.showClearOnFocus = !1, this._open = !1, this._defaultOpen = !1, this._openInitialized = !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._$dataListRef = null, this._hasInput = !1, this._hasValue = !1, this._hasLeading = !1, this._hasTrailing = !1, this._inputDisabled = !1, this._hasSuggestionsSlot = !1, this._dataListSuggestions = [], this._disabledHost = void 0, this._focused = !1, this._onInputFocus = () => {
221
25
  this._focused = !0, this.variant === "view" && this.showView();
222
- }, this._onInputBlur = () => {
223
- this._focused = !1;
26
+ }, this._onInputBlur = (e) => {
27
+ this._containsFocusTarget(e.relatedTarget) || (this._focused = !1);
28
+ }, this._onHostFocusOut = (e) => {
29
+ this._containsFocusTarget(e.relatedTarget) || (this._focused = !1);
224
30
  }, this._disabledObserver = new MutationObserver(() => {
225
31
  const e = this._$input();
226
32
  e && (this._inputDisabled = e.disabled, this._syncDataListSuggestions(e));
227
- }), this._dataListObserver = new MutationObserver(() => this._syncDataListSuggestions()), this._inputController = new f(this, {
33
+ }), this._dataListObserver = new MutationObserver(() => this._syncDataListSuggestions()), this._inputController = new g(this, {
228
34
  selector: ':scope > input[type="search"]',
229
35
  observe: { childList: !0, attributes: !0, attributeFilter: ["list"] },
230
36
  onChange: (e, t) => this._setupInput(e, t),
@@ -242,7 +48,7 @@ const s = (n = class extends _ {
242
48
  return;
243
49
  n._styledRoots.add(e);
244
50
  const t = document.createElement("style");
245
- t.setAttribute("data-rc-light-dom-base", "rc-search-bar"), t.textContent = S, e instanceof Document ? e.head.append(t) : e.append(t);
51
+ t.setAttribute("data-rc-light-dom-base", "rc-search-bar"), t.textContent = I, e instanceof Document ? e.head.append(t) : e.append(t);
246
52
  }
247
53
  get disabled() {
248
54
  return this._disabledHost ?? this._inputDisabled;
@@ -250,8 +56,11 @@ const s = (n = class extends _ {
250
56
  set disabled(e) {
251
57
  const t = this.disabled;
252
58
  this._disabledHost = e;
253
- const i = this._$input();
254
- i && (i.disabled = e), this.requestUpdate("disabled", t);
59
+ const s = this._$input();
60
+ s && (s.disabled = e), this.requestUpdate("disabled", t);
61
+ }
62
+ _containsFocusTarget(e) {
63
+ return e instanceof Node && (e === this || this.contains(e) || !!this.shadowRoot?.contains(e));
255
64
  }
256
65
  get open() {
257
66
  return this._open;
@@ -273,8 +82,8 @@ const s = (n = class extends _ {
273
82
  set value(e) {
274
83
  const t = this.value;
275
84
  this._value = e, this._valueSetByHost = !0, this._valueInitialized = !0;
276
- const i = this._$input();
277
- i && (i.value = e), this._hasValue = e.length > 0, this.requestUpdate("value", t);
85
+ const s = this._$input();
86
+ s && (s.value = e), this._hasValue = e.length > 0, this.requestUpdate("value", t);
278
87
  }
279
88
  get defaultValue() {
280
89
  return this._defaultValue;
@@ -282,14 +91,14 @@ const s = (n = class extends _ {
282
91
  set defaultValue(e) {
283
92
  const t = this._defaultValue;
284
93
  this._defaultValue = e;
285
- const i = this._$input();
286
- i && e !== void 0 && !this._valueInitialized && (i.value = e, this._hasValue = e.length > 0), this.requestUpdate("defaultValue", t);
94
+ const s = this._$input();
95
+ s && e !== void 0 && !this._valueInitialized && (s.value = e, this._hasValue = e.length > 0), this.requestUpdate("defaultValue", t);
287
96
  }
288
97
  connectedCallback() {
289
- super.connectedCallback(), n._ensureBaseStyles(this.getRootNode());
98
+ super.connectedCallback(), n._ensureBaseStyles(this.getRootNode()), this.addEventListener("focusout", this._onHostFocusOut);
290
99
  }
291
100
  disconnectedCallback() {
292
- super.disconnectedCallback(), this._focused = !1, this._open = !1, this._cancelPendingInput();
101
+ super.disconnectedCallback(), this.removeEventListener("focusout", this._onHostFocusOut), this._focused = !1, this._open = !1, this._cancelPendingInput();
293
102
  const e = this._$input();
294
103
  e?.removeEventListener("input", this._onNativeInput), e?.removeEventListener("focus", this._onInputFocus), e?.removeEventListener("blur", this._onInputBlur), e?.removeEventListener("keydown", this._onNativeKeyDown), this._disabledObserver.disconnect(), this._dataListObserver.disconnect();
295
104
  }
@@ -376,9 +185,9 @@ const s = (n = class extends _ {
376
185
  subtree: !0,
377
186
  attributes: !0,
378
187
  attributeFilter: ["value", "label", "disabled"]
379
- })), this._dataListSuggestions = t ? Array.from(t.options).filter((i) => !i.disabled && i.value).map((i) => ({
380
- value: i.value,
381
- label: i.label || i.textContent?.trim() || i.value
188
+ })), this._dataListSuggestions = t ? Array.from(t.options).filter((s) => !s.disabled && s.value).map((s) => ({
189
+ value: s.value,
190
+ label: s.label || s.textContent?.trim() || s.value
382
191
  })) : [];
383
192
  }
384
193
  _selectDataListSuggestion(e) {
@@ -402,12 +211,12 @@ const s = (n = class extends _ {
402
211
  ), this._dispatchInput(""), e.focus());
403
212
  }
404
213
  render() {
405
- return u`
214
+ return d`
406
215
  <div
407
216
  id="root"
408
217
  part="root"
409
218
  class=${h({ empty: !this._hasInput })}
410
- ${g({ attributeTarget: this })}
219
+ ${m({ attributeTarget: this })}
411
220
  >
412
221
  <span
413
222
  id="leading"
@@ -423,7 +232,7 @@ const s = (n = class extends _ {
423
232
  id="clear"
424
233
  part="clear"
425
234
  type="button"
426
- aria-label=${this.clearLabel}
235
+ aria-label=${this._messages.value.clear}
427
236
  ?hidden=${!this._hasInput}
428
237
  ?inert=${this._hasInput && !this._hasValue && !(this.showClearOnFocus && this._focused)}
429
238
  ?disabled=${this._inputDisabled}
@@ -447,7 +256,7 @@ const s = (n = class extends _ {
447
256
  if (this.variant !== "view" || !this.open)
448
257
  return b;
449
258
  const e = !this._hasSuggestionsSlot && this._dataListSuggestions.length > 0, t = !this._hasSuggestionsSlot && !e;
450
- return u`
259
+ return d`
451
260
  <div id="view">
452
261
  <div
453
262
  id="view-surface"
@@ -460,13 +269,13 @@ const s = (n = class extends _ {
460
269
  <div id="suggestions" part="suggestions">
461
270
  <slot name="suggestions" @slotchange=${this._onSuggestionsSlotChange}></slot>
462
271
  ${e ? this._dataListSuggestions.map(
463
- (i) => u`
272
+ (s) => d`
464
273
  <button
465
274
  part="suggestion"
466
275
  type="button"
467
- @click=${() => this._selectDataListSuggestion(i)}
276
+ @click=${() => this._selectDataListSuggestion(s)}
468
277
  >
469
- <span>${i.label}</span>
278
+ <span>${s.label}</span>
470
279
  </button>
471
280
  `
472
281
  ) : b}
@@ -487,66 +296,67 @@ const s = (n = class extends _ {
487
296
  const t = e.target;
488
297
  this._hasSuggestionsSlot = t.assignedElements({ flatten: !0 }).length > 0;
489
298
  }
490
- }, n.styles = [m], n._styledRoots = /* @__PURE__ */ new Set(), n);
299
+ }, n.styles = [w], n._styledRoots = /* @__PURE__ */ new Set(), n);
300
+ a([
301
+ r({ attribute: !1 })
302
+ ], i.prototype, "messages", 2);
491
303
  a([
492
304
  r({ type: String, reflect: !0 })
493
- ], s.prototype, "variant", 2);
305
+ ], i.prototype, "variant", 2);
494
306
  a([
495
307
  r({ type: Number })
496
- ], s.prototype, "debounce", 2);
497
- a([
498
- r({ type: String, attribute: "clear-label" })
499
- ], s.prototype, "clearLabel", 2);
308
+ ], i.prototype, "debounce", 2);
500
309
  a([
501
310
  r({ type: Boolean, attribute: "allow-native-clear", reflect: !0 })
502
- ], s.prototype, "allowNativeClear", 2);
311
+ ], i.prototype, "allowNativeClear", 2);
503
312
  a([
504
313
  r({ type: Boolean, attribute: "show-clear-on-focus" })
505
- ], s.prototype, "showClearOnFocus", 2);
314
+ ], i.prototype, "showClearOnFocus", 2);
506
315
  a([
507
316
  r({ type: Boolean, reflect: !0 })
508
- ], s.prototype, "disabled", 1);
317
+ ], i.prototype, "disabled", 1);
509
318
  a([
510
319
  r({ type: String })
511
- ], s.prototype, "placeholder", 2);
320
+ ], i.prototype, "placeholder", 2);
512
321
  a([
513
322
  o()
514
- ], s.prototype, "_hasInput", 2);
323
+ ], i.prototype, "_hasInput", 2);
515
324
  a([
516
325
  o()
517
- ], s.prototype, "_hasValue", 2);
326
+ ], i.prototype, "_hasValue", 2);
518
327
  a([
519
328
  o()
520
- ], s.prototype, "_hasLeading", 2);
329
+ ], i.prototype, "_hasLeading", 2);
521
330
  a([
522
331
  o()
523
- ], s.prototype, "_hasTrailing", 2);
332
+ ], i.prototype, "_hasTrailing", 2);
524
333
  a([
525
334
  o()
526
- ], s.prototype, "_inputDisabled", 2);
335
+ ], i.prototype, "_inputDisabled", 2);
527
336
  a([
528
337
  o()
529
- ], s.prototype, "_hasSuggestionsSlot", 2);
338
+ ], i.prototype, "_hasSuggestionsSlot", 2);
530
339
  a([
531
340
  o()
532
- ], s.prototype, "_dataListSuggestions", 2);
341
+ ], i.prototype, "_dataListSuggestions", 2);
533
342
  a([
534
343
  o()
535
- ], s.prototype, "_focused", 2);
344
+ ], i.prototype, "_focused", 2);
536
345
  a([
537
346
  r({ type: Boolean, reflect: !0 })
538
- ], s.prototype, "open", 1);
347
+ ], i.prototype, "open", 1);
539
348
  a([
540
349
  r({ type: Boolean, attribute: "default-open" })
541
- ], s.prototype, "defaultOpen", 1);
350
+ ], i.prototype, "defaultOpen", 1);
542
351
  a([
543
352
  r({ attribute: !1 })
544
- ], s.prototype, "value", 1);
353
+ ], i.prototype, "value", 1);
545
354
  a([
546
355
  r({ type: String, attribute: "default-value" })
547
- ], s.prototype, "defaultValue", 1);
548
- let z = s;
356
+ ], i.prototype, "defaultValue", 1);
357
+ let E = i;
549
358
  export {
550
- z as R
359
+ x as D,
360
+ E as R
551
361
  };
552
- //# sourceMappingURL=rc-search-bar-BotAjSsh.js.map
362
+ //# sourceMappingURL=rc-search-bar-DFKw8RH2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rc-search-bar-DFKw8RH2.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 position: relative;\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(\n --rc-search-bar-border,\n var(--rc-border, 1px solid var(--rc-border-color, ButtonBorder))\n );\n border-radius: var(\n --rc-search-bar-radius,\n var(--rc-control-radius, var(--rc-radius-sm, 0.125em))\n );\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:\n background-color 120ms,\n border-color 120ms,\n 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 #view {\n position: absolute;\n z-index: 1;\n inset-block-start: calc(100% + var(--rc-search-bar-view-offset, 0.25rem));\n inset-inline: 0;\n min-inline-size: 100%;\n }\n\n #view-surface {\n box-sizing: border-box;\n padding-block: var(--rc-search-bar-view-padding-block, 0.5rem);\n border: var(\n --rc-search-bar-view-border,\n var(--rc-search-bar-border, var(--rc-border, 1px solid var(--rc-border-color, ButtonBorder)))\n );\n border-radius: var(\n --rc-search-bar-view-radius,\n var(--rc-search-bar-radius, var(--rc-control-radius, var(--rc-radius-sm, 0.125em)))\n );\n box-shadow: var(--rc-search-bar-view-shadow, var(--rc-search-bar-shadow, none));\n background: var(--rc-search-bar-view-bg, var(--rc-search-bar-bg, var(--rc-field, Field)));\n color: var(\n --rc-search-bar-view-color,\n var(--rc-search-bar-color, var(--rc-field-text, FieldText))\n );\n font-family: var(--rc-font-family, inherit);\n font-size: var(--rc-font-size, inherit);\n }\n\n #view-surface.empty {\n display: none;\n }\n\n #suggestions {\n display: flex;\n flex-direction: column;\n }\n\n #suggestions ::slotted(*) {\n min-inline-size: 0;\n }\n\n [part='suggestion'] {\n display: flex;\n align-items: center;\n min-block-size: var(--rc-search-bar-suggestion-min-block-size, 2.75rem);\n padding-block: 0;\n padding-inline: var(--rc-search-bar-suggestion-padding-inline, 1rem);\n border: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n text-align: start;\n cursor: pointer;\n }\n\n [part='suggestion']:hover,\n [part='suggestion']:focus-visible {\n background: var(--rc-search-bar-suggestion-hover-bg, ButtonFace);\n }\n\n [part='suggestion']: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, nothing, type PropertyValues } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\n\nimport {\n cssText,\n keyInteraction,\n MessagesController,\n NativeChildController,\n warnMissingDirectChild,\n} from '@rcarls/rc-common';\n\nimport searchBarStyles from './rc-search-bar.styles.js';\n\nconst LIGHT_DOM_CSS = cssText`\n@layer rc-base {\n rc-search-bar > input[type='search'] {\n flex: 1 1 auto;\n min-inline-size: 0;\n min-block-size: 0;\n padding: 0;\n border: 0;\n border-radius: 0;\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: 0;\n box-shadow: none;\n appearance: textfield;\n }\n\n rc-search-bar > input[type='search']:focus-visible {\n border: 0;\n outline: 0;\n box-shadow: none;\n }\n\n rc-search-bar:not([allow-native-clear])\n > input[type='search']::-webkit-search-cancel-button {\n -webkit-appearance: none;\n display: none;\n }\n}\n`;\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'rc-search-bar': RCSearchBar;\n }\n\n interface HTMLElementEventMap {\n 'rc-search-bar-input': CustomEvent<RCSearchBarInputDetail>;\n 'rc-search-bar-clear': CustomEvent<Record<string, never>>;\n 'rc-search-bar-toggle': CustomEvent<RCSearchBarToggleDetail>;\n 'rc-search-bar-suggestion-select': CustomEvent<RCSearchBarSuggestionSelectDetail>;\n }\n}\n\nexport interface RCSearchBarInputDetail {\n /** The native input's value at dispatch time. */\n value: string;\n}\n\nexport interface RCSearchBarToggleDetail {\n /** Whether the search view is open after the user action. */\n open: boolean;\n}\n\nexport interface RCSearchBarSuggestionSelectDetail {\n /** Value written to the native search input. */\n value: string;\n\n /** Human-readable option label, when different from value. */\n label: string;\n}\n\nexport type RCSearchBarVariant = 'bar' | 'view';\n\ninterface RCSearchBarSuggestion {\n value: string;\n label: string;\n}\n\n/** Built-in text of `rc-search-bar`. */\nexport interface RCSearchBarMessages {\n /** Accessible name of the clear button, such as `Cancel` with `show-clear-on-focus`. */\n clear: string;\n}\n\nexport const DEFAULT_SEARCH_BAR_MESSAGES: Readonly<RCSearchBarMessages> = Object.freeze({\n clear: 'Clear search',\n});\n\ndeclare module '@rcarls/rc-common' {\n interface RcMessageCatalog {\n 'rc-search-bar': RCSearchBarMessages;\n }\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 * Built-in text (the clear button name) follows the element's own `lang`, else\n * `<html lang>`: per element through `messages`, or for every instance\n * through `registerMessages()` from `@rcarls/rc-common` under `rc-search-bar`.\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 * @slot suggestions - Rich search view suggestions; takes precedence over\n * datalist-derived suggestions.\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 * @fires rc-search-bar-toggle - When user interaction opens or closes the\n * search view; `detail: { open }`\n * @fires rc-search-bar-suggestion-select - When a datalist-derived suggestion\n * is activated; `detail: { value, label }`\n *\n * @attr variant - Presentation mode: docked search bar or expandable search view.\n * @attr debounce - Debounce window in ms for `rc-search-bar-input`; `0` dispatches synchronously.\n * @attr allow-native-clear - When set, leaves the browser's native WebKit cancel button visible.\n * @attr show-clear-on-focus - When set, the clear button is visible whenever the input is focused.\n * @attr disabled - Disables the component and mirrors the state to the slotted input.\n * @attr placeholder - Placeholder mirrored onto the native input; a consumer `placeholder`\n * attribute on the input itself is always honored instead.\n * @attr open - Whether the search view panel is open. Host writes are silent.\n * @attr default-open - Initial uncontrolled search view open state.\n * @attr default-value - Initial uncontrolled value hint, applied once.\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 * @cssprop [--rc-search-bar-view-bg=var(--rc-search-bar-bg)] - Search view panel background\n * @cssprop [--rc-search-bar-view-color=var(--rc-search-bar-color)] - Search view panel text color\n * @cssprop [--rc-search-bar-view-radius=var(--rc-search-bar-radius)] - Search view panel radius\n * @cssprop [--rc-search-bar-view-shadow=var(--rc-search-bar-shadow)] - Search view panel shadow\n * @cssprop [--rc-search-bar-view-border=var(--rc-search-bar-border)] - Search view panel border\n * @cssprop [--rc-search-bar-view-offset=0.25rem] - Gap between the search bar and the view panel below it\n * @cssprop [--rc-search-bar-view-padding-block=0.5rem] - Search view suggestion list block padding\n * @cssprop [--rc-search-bar-suggestion-min-block-size=2.75rem] - Datalist-derived suggestion row minimum block size\n * @cssprop [--rc-search-bar-suggestion-padding-inline=1rem] - Datalist-derived suggestion inline padding\n * @cssprop [--rc-search-bar-suggestion-hover-bg=ButtonFace] - Datalist-derived suggestion hover/focus background\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 * @csspart view - Search view panel\n * @csspart suggestions - Suggestions container\n * @csspart suggestion - Datalist-derived suggestion button\n */\nexport class RCSearchBar extends LitElement {\n static styles = [searchBarStyles];\n\n /** Built-in text overrides; unset keys fall back to registered text, then English. */\n @property({ attribute: false })\n messages: Partial<RCSearchBarMessages> | undefined;\n\n private readonly _messages = new MessagesController(\n this,\n 'rc-search-bar',\n DEFAULT_SEARCH_BAR_MESSAGES,\n {\n overrides: () => this.messages,\n },\n );\n\n private static readonly _styledRoots = new Set<Document | ShadowRoot>();\n\n private static _ensureBaseStyles(root: Document | ShadowRoot): void {\n if (RCSearchBar._styledRoots.has(root)) {\n return;\n }\n\n RCSearchBar._styledRoots.add(root);\n\n const style = document.createElement('style');\n\n style.setAttribute('data-rc-light-dom-base', 'rc-search-bar');\n style.textContent = LIGHT_DOM_CSS;\n\n if (root instanceof Document) {\n root.head.append(style);\n } else {\n root.append(style);\n }\n }\n\n /** Presentation mode: docked search bar or expandable search view. */\n @property({ type: String, reflect: true })\n variant: RCSearchBarVariant = 'bar';\n\n /** Debounce window in ms for `rc-search-bar-input`; `0` dispatches synchronously. */\n @property({ type: Number })\n debounce = 200;\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 `messages.clear` to `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\n set disabled(value: boolean) {\n const old = this.disabled;\n\n this._disabledHost = value;\n\n const $input = this._$input();\n\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 _open = false;\n\n private _defaultOpen = false;\n\n private _openInitialized = false;\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 private _$dataListRef: WeakRef<HTMLDataListElement> | null = null;\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 @state()\n private _hasSuggestionsSlot = false;\n\n @state()\n private _dataListSuggestions: RCSearchBarSuggestion[] = [];\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 if (this.variant === 'view') {\n this.showView();\n }\n };\n\n // Focus moving from the input to the component's own controls (the clear\n // button shown on focus, suggestions) keeps it focused; otherwise the clear\n // button would turn inert while it receives Tab focus and drop focus to\n // <body>. Event retargeting reports a move into the shadow root as the host.\n private readonly _onInputBlur = (e: FocusEvent): void => {\n if (!this._containsFocusTarget(e.relatedTarget)) {\n this._focused = false;\n }\n };\n\n private readonly _onHostFocusOut = (e: FocusEvent): void => {\n if (!this._containsFocusTarget(e.relatedTarget)) {\n this._focused = false;\n }\n };\n\n private _containsFocusTarget(target: EventTarget | null): boolean {\n return (\n target instanceof Node &&\n (target === this || this.contains(target) || Boolean(this.shadowRoot?.contains(target)))\n );\n }\n\n private readonly _disabledObserver = new MutationObserver(() => {\n const $input = this._$input();\n\n if ($input) {\n this._inputDisabled = $input.disabled;\n this._syncDataListSuggestions($input);\n }\n });\n\n private readonly _dataListObserver = new MutationObserver(() => this._syncDataListSuggestions());\n\n private readonly _inputController = new NativeChildController<HTMLInputElement>(this, {\n selector: ':scope > input[type=\"search\"]',\n observe: { childList: true, attributes: true, attributeFilter: ['list'] },\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 /** Whether the search view panel is open. Host writes are silent. */\n @property({ type: Boolean, reflect: true })\n get open(): boolean {\n return this._open;\n }\n\n set open(value: boolean) {\n const oldValue = this._open;\n\n this._open = value;\n this._openInitialized = true;\n\n this.requestUpdate('open', oldValue);\n }\n\n /** Initial uncontrolled search view open state. */\n @property({ type: Boolean, attribute: 'default-open' })\n get defaultOpen(): boolean {\n return this._defaultOpen;\n }\n\n set defaultOpen(value: boolean) {\n const oldValue = this._defaultOpen;\n\n this._defaultOpen = value;\n\n if (!this._openInitialized) {\n this._open = value;\n }\n\n this.requestUpdate('defaultOpen', oldValue);\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\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\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 RCSearchBar._ensureBaseStyles(this.getRootNode() as Document | ShadowRoot);\n this.addEventListener('focusout', this._onHostFocusOut);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('focusout', this._onHostFocusOut);\n\n this._focused = false;\n this._open = 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 $input?.removeEventListener('keydown', this._onNativeKeyDown);\n\n this._disabledObserver.disconnect();\n this._dataListObserver.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 if (changed.has('variant') && this.variant !== 'view' && this._open) {\n const oldOpen = this._open;\n\n this._open = false;\n this.requestUpdate('open', oldOpen);\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 $previousInput.removeEventListener('keydown', this._onNativeKeyDown);\n }\n\n this._disabledObserver.disconnect();\n this._dataListObserver.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 this._dataListSuggestions = [];\n this._$dataListRef = null;\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 this._syncDataListSuggestions($input);\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 $input.addEventListener('keydown', this._onNativeKeyDown);\n\n this._disabledObserver.observe($input, { attributeFilter: ['disabled', 'list'] });\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 readonly _onNativeKeyDown = (e: KeyboardEvent): void => {\n if (e.key === 'Escape' && this.open) {\n e.preventDefault();\n this.closeView();\n }\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 _setUserOpen(open: boolean): void {\n if (this._open === open) {\n return;\n }\n\n const oldOpen = this._open;\n\n this._open = open;\n this._openInitialized = true;\n this.requestUpdate('open', oldOpen);\n\n this.dispatchEvent(\n new CustomEvent<RCSearchBarToggleDetail>('rc-search-bar-toggle', {\n bubbles: true,\n composed: true,\n detail: { open },\n }),\n );\n }\n\n /** Opens the search view and fires `rc-search-bar-toggle` when it changes. */\n public showView(): void {\n if (this.variant !== 'view' || this.disabled) {\n return;\n }\n\n this._setUserOpen(true);\n }\n\n /** Closes the search view and fires `rc-search-bar-toggle` when it changes. */\n public closeView(): void {\n this._setUserOpen(false);\n }\n\n /** Toggles the search view and fires `rc-search-bar-toggle` when it changes. */\n public toggleView(): void {\n this.open ? this.closeView() : this.showView();\n }\n\n private _syncDataListSuggestions($input = this._$input()): void {\n const $dataList = $input?.list ?? null;\n\n if (this._$dataListRef?.deref() !== $dataList) {\n this._dataListObserver.disconnect();\n this._$dataListRef = $dataList ? new WeakRef($dataList) : null;\n\n if ($dataList) {\n this._dataListObserver.observe($dataList, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['value', 'label', 'disabled'],\n });\n }\n }\n\n this._dataListSuggestions = $dataList\n ? Array.from($dataList.options)\n .filter(($option) => !$option.disabled && $option.value)\n .map(($option) => ({\n value: $option.value,\n label: $option.label || $option.textContent?.trim() || $option.value,\n }))\n : [];\n }\n\n private _selectDataListSuggestion(suggestion: RCSearchBarSuggestion): void {\n const $input = this._$input();\n\n if (!$input) {\n return;\n }\n\n this._cancelPendingInput();\n\n $input.value = suggestion.value;\n this._valueInitialized = true;\n this._hasValue = suggestion.value.length > 0;\n\n this.dispatchEvent(\n new CustomEvent<RCSearchBarSuggestionSelectDetail>('rc-search-bar-suggestion-select', {\n bubbles: true,\n composed: true,\n detail: suggestion,\n }),\n );\n\n this._dispatchInput(suggestion.value);\n $input.focus();\n this.closeView();\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\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\n id=\"root\"\n part=\"root\"\n class=${classMap({ empty: !this._hasInput })}\n ${keyInteraction({ attributeTarget: this })}\n >\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._messages.value.clear}\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 ${this._renderSearchView()}\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 _renderSearchView() {\n if (this.variant !== 'view' || !this.open) {\n return nothing;\n }\n\n const hasDataListSuggestions =\n !this._hasSuggestionsSlot && this._dataListSuggestions.length > 0;\n const empty = !this._hasSuggestionsSlot && !hasDataListSuggestions;\n\n return html`\n <div id=\"view\">\n <div\n id=\"view-surface\"\n part=\"view\"\n ?hidden=${empty}\n class=${classMap({\n empty,\n })}\n >\n <div id=\"suggestions\" part=\"suggestions\">\n <slot name=\"suggestions\" @slotchange=${this._onSuggestionsSlotChange}></slot>\n ${hasDataListSuggestions\n ? this._dataListSuggestions.map(\n (suggestion) => html`\n <button\n part=\"suggestion\"\n type=\"button\"\n @click=${() => this._selectDataListSuggestion(suggestion)}\n >\n <span>${suggestion.label}</span>\n </button>\n `,\n )\n : nothing}\n </div>\n </div>\n </div>\n `;\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 private _onSuggestionsSlotChange(e: Event): void {\n const $slot = e.target as HTMLSlotElement;\n\n this._hasSuggestionsSlot = $slot.assignedElements({ flatten: true }).length > 0;\n }\n}\n\nexport default RCSearchBar;\n"],"names":["searchBarStyles","css","LIGHT_DOM_CSS","cssText","DEFAULT_SEARCH_BAR_MESSAGES","_RCSearchBar","_a","LitElement","MessagesController","$input","NativeChildController","$previousInput","root","style","value","old","target","oldValue","changed","oldOpen","open","$dataList","$option","suggestion","html","classMap","keyInteraction","nothing","hasDataListSuggestions","empty","$slot","__decorateClass","property","state","RCSearchBar"],"mappings":"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"}
@@ -1,6 +1,8 @@
1
- import { R as e } from "./rc-search-bar-BotAjSsh.js";
2
- customElements.get("rc-search-bar") || customElements.define("rc-search-bar", e);
1
+ import { R as r } from "./rc-search-bar-DFKw8RH2.js";
2
+ import { D as t } from "./rc-search-bar-DFKw8RH2.js";
3
+ customElements.get("rc-search-bar") || customElements.define("rc-search-bar", r);
3
4
  export {
4
- e as RCSearchBar
5
+ t as DEFAULT_SEARCH_BAR_MESSAGES,
6
+ r as RCSearchBar
5
7
  };
6
8
  //# sourceMappingURL=rc-search-bar-define.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"rc-search-bar-define.js","sources":["../src/define.ts"],"sourcesContent":["import { RCSearchBar } from './index.js';\n\ncustomElements.get('rc-search-bar') || customElements.define('rc-search-bar', RCSearchBar);\n\nexport * from './index.js';\n"],"names":["RCSearchBar"],"mappings":";AAEA,eAAe,IAAI,eAAe,KAAK,eAAe,OAAO,iBAAiBA,CAAW;"}
1
+ {"version":3,"file":"rc-search-bar-define.js","sources":["../src/define.ts"],"sourcesContent":["import { RCSearchBar } from './index.js';\n\ncustomElements.get('rc-search-bar') || customElements.define('rc-search-bar', RCSearchBar);\n\nexport * from './index.js';\n"],"names":["RCSearchBar"],"mappings":";;AAEA,eAAe,IAAI,eAAe,KAAK,eAAe,OAAO,iBAAiBA,CAAW;"}
@@ -1,5 +1,6 @@
1
- import { R as e } from "./rc-search-bar-BotAjSsh.js";
1
+ import { D as r, R as A } from "./rc-search-bar-DFKw8RH2.js";
2
2
  export {
3
- e as RCSearchBar
3
+ r as DEFAULT_SEARCH_BAR_MESSAGES,
4
+ A as RCSearchBar
4
5
  };
5
6
  //# sourceMappingURL=rc-search-bar.js.map
@@ -25,6 +25,17 @@ export interface RCSearchBarSuggestionSelectDetail {
25
25
  label: string;
26
26
  }
27
27
  export type RCSearchBarVariant = 'bar' | 'view';
28
+ /** Built-in text of `rc-search-bar`. */
29
+ export interface RCSearchBarMessages {
30
+ /** Accessible name of the clear button, such as `Cancel` with `show-clear-on-focus`. */
31
+ clear: string;
32
+ }
33
+ export declare const DEFAULT_SEARCH_BAR_MESSAGES: Readonly<RCSearchBarMessages>;
34
+ declare module '@rcarls/rc-common' {
35
+ interface RcMessageCatalog {
36
+ 'rc-search-bar': RCSearchBarMessages;
37
+ }
38
+ }
28
39
  /**
29
40
  * Search field wrapper for a native <input type="search"> with icon chrome, clear button,
30
41
  * and debounced events.
@@ -40,6 +51,10 @@ export type RCSearchBarVariant = 'bar' | 'view';
40
51
  * (a debounced `rc-search-bar-input` with an empty value) and never fires
41
52
  * `rc-search-bar-clear`.
42
53
  *
54
+ * Built-in text (the clear button name) follows the element's own `lang`, else
55
+ * `<html lang>`: per element through `messages`, or for every instance
56
+ * through `registerMessages()` from `@rcarls/rc-common` under `rc-search-bar`.
57
+ *
43
58
  * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-search-bar rc-search-bar docs}
44
59
  *
45
60
  * @slot - The required native `<input type="search">`
@@ -59,7 +74,6 @@ export type RCSearchBarVariant = 'bar' | 'view';
59
74
  *
60
75
  * @attr variant - Presentation mode: docked search bar or expandable search view.
61
76
  * @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
77
  * @attr allow-native-clear - When set, leaves the browser's native WebKit cancel button visible.
64
78
  * @attr show-clear-on-focus - When set, the clear button is visible whenever the input is focused.
65
79
  * @attr disabled - Disables the component and mirrors the state to the slotted input.
@@ -102,21 +116,22 @@ export type RCSearchBarVariant = 'bar' | 'view';
102
116
  */
103
117
  export declare class RCSearchBar extends LitElement {
104
118
  static styles: import('lit').CSSResult[];
119
+ /** Built-in text overrides; unset keys fall back to registered text, then English. */
120
+ messages: Partial<RCSearchBarMessages> | undefined;
121
+ private readonly _messages;
105
122
  private static readonly _styledRoots;
106
123
  private static _ensureBaseStyles;
107
124
  /** Presentation mode: docked search bar or expandable search view. */
108
125
  variant: RCSearchBarVariant;
109
126
  /** Debounce window in ms for `rc-search-bar-input`; `0` dispatches synchronously. */
110
127
  debounce: number;
111
- /** Accessible label for the clear button. */
112
- clearLabel: string;
113
128
  /** When set, leaves the browser's native WebKit cancel button visible. */
114
129
  allowNativeClear: boolean;
115
130
  /**
116
131
  * When set, the clear button is visible whenever the input is focused.
117
132
  *
118
133
  * Matching the Apple HIG "cancel" pattern.
119
- * Consider setting `clear-label="Cancel"` in this mode.
134
+ * Consider setting `messages.clear` to `Cancel` in this mode.
120
135
  */
121
136
  showClearOnFocus: boolean;
122
137
  /** Disables the component and mirrors the state to the slotted input. */
@@ -151,6 +166,8 @@ export declare class RCSearchBar extends LitElement {
151
166
  private _focused;
152
167
  private readonly _onInputFocus;
153
168
  private readonly _onInputBlur;
169
+ private readonly _onHostFocusOut;
170
+ private _containsFocusTarget;
154
171
  private readonly _disabledObserver;
155
172
  private readonly _dataListObserver;
156
173
  private readonly _inputController;
@@ -195,7 +212,7 @@ export declare class RCSearchBar extends LitElement {
195
212
  private _syncDataListSuggestions;
196
213
  private _selectDataListSuggestion;
197
214
  private _handleClear;
198
- protected render(): import('lit').TemplateResult<1>;
215
+ protected render(): import('lit-html').TemplateResult<1>;
199
216
  /** Programmatically clears the value and fires rc-search-bar-clear + rc-search-bar-input. */
200
217
  clear(): void;
201
218
  private _renderSearchView;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.6.0",
6
+ "version": "0.7.0",
7
7
  "description": "Search field/view wrapper for a native <input type=\"search\"> with suggestions and debounced events.",
8
8
  "repository": {
9
9
  "type": "git",
@@ -60,6 +60,6 @@
60
60
  "lit": "^3.0.0"
61
61
  },
62
62
  "dependencies": {
63
- "@rcarls/rc-common": "0.6.0"
63
+ "@rcarls/rc-common": "0.7.0"
64
64
  }
65
65
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"rc-search-bar-BotAjSsh.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 position: relative;\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(\n --rc-search-bar-border,\n var(--rc-border, 1px solid var(--rc-border-color, ButtonBorder))\n );\n border-radius: var(\n --rc-search-bar-radius,\n var(--rc-control-radius, var(--rc-radius-sm, 0.125em))\n );\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:\n background-color 120ms,\n border-color 120ms,\n 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 #view {\n position: absolute;\n z-index: 1;\n inset-block-start: calc(100% + var(--rc-search-bar-view-offset, 0.25rem));\n inset-inline: 0;\n min-inline-size: 100%;\n }\n\n #view-surface {\n box-sizing: border-box;\n padding-block: var(--rc-search-bar-view-padding-block, 0.5rem);\n border: var(\n --rc-search-bar-view-border,\n var(--rc-search-bar-border, var(--rc-border, 1px solid var(--rc-border-color, ButtonBorder)))\n );\n border-radius: var(\n --rc-search-bar-view-radius,\n var(--rc-search-bar-radius, var(--rc-control-radius, var(--rc-radius-sm, 0.125em)))\n );\n box-shadow: var(--rc-search-bar-view-shadow, var(--rc-search-bar-shadow, none));\n background: var(--rc-search-bar-view-bg, var(--rc-search-bar-bg, var(--rc-field, Field)));\n color: var(\n --rc-search-bar-view-color,\n var(--rc-search-bar-color, var(--rc-field-text, FieldText))\n );\n font-family: var(--rc-font-family, inherit);\n font-size: var(--rc-font-size, inherit);\n }\n\n #view-surface.empty {\n display: none;\n }\n\n #suggestions {\n display: flex;\n flex-direction: column;\n }\n\n #suggestions ::slotted(*) {\n min-inline-size: 0;\n }\n\n [part='suggestion'] {\n display: flex;\n align-items: center;\n min-block-size: var(--rc-search-bar-suggestion-min-block-size, 2.75rem);\n padding-block: 0;\n padding-inline: var(--rc-search-bar-suggestion-padding-inline, 1rem);\n border: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n text-align: start;\n cursor: pointer;\n }\n\n [part='suggestion']:hover,\n [part='suggestion']:focus-visible {\n background: var(--rc-search-bar-suggestion-hover-bg, ButtonFace);\n }\n\n [part='suggestion']: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, nothing, 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.js';\n\nconst LIGHT_DOM_CSS = `\nrc-search-bar > input[type='search'] {\n flex: 1 1 auto;\n min-inline-size: 0;\n min-block-size: 0;\n padding: 0;\n border: 0;\n border-radius: 0;\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: 0;\n box-shadow: none;\n appearance: textfield;\n}\n\nrc-search-bar > input[type='search']:focus-visible {\n border: 0;\n outline: 0;\n box-shadow: none;\n}\n\nrc-search-bar:not([allow-native-clear])\n > input[type='search']::-webkit-search-cancel-button {\n -webkit-appearance: none;\n display: none;\n}\n`;\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'rc-search-bar': RCSearchBar;\n }\n\n interface HTMLElementEventMap {\n 'rc-search-bar-input': CustomEvent<RCSearchBarInputDetail>;\n 'rc-search-bar-clear': CustomEvent<Record<string, never>>;\n 'rc-search-bar-toggle': CustomEvent<RCSearchBarToggleDetail>;\n 'rc-search-bar-suggestion-select': CustomEvent<RCSearchBarSuggestionSelectDetail>;\n }\n}\n\nexport interface RCSearchBarInputDetail {\n /** The native input's value at dispatch time. */\n value: string;\n}\n\nexport interface RCSearchBarToggleDetail {\n /** Whether the search view is open after the user action. */\n open: boolean;\n}\n\nexport interface RCSearchBarSuggestionSelectDetail {\n /** Value written to the native search input. */\n value: string;\n\n /** Human-readable option label, when different from value. */\n label: string;\n}\n\nexport type RCSearchBarVariant = 'bar' | 'view';\n\ninterface RCSearchBarSuggestion {\n value: string;\n label: 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 * @slot suggestions - Rich search view suggestions; takes precedence over\n * datalist-derived suggestions.\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 * @fires rc-search-bar-toggle - When user interaction opens or closes the\n * search view; `detail: { open }`\n * @fires rc-search-bar-suggestion-select - When a datalist-derived suggestion\n * is activated; `detail: { value, label }`\n *\n * @attr variant - Presentation mode: docked search bar or expandable search view.\n * @attr debounce - Debounce window in ms for `rc-search-bar-input`; `0` dispatches synchronously.\n * @attr clear-label - Accessible label for the clear button.\n * @attr allow-native-clear - When set, leaves the browser's native WebKit cancel button visible.\n * @attr show-clear-on-focus - When set, the clear button is visible whenever the input is focused.\n * @attr disabled - Disables the component and mirrors the state to the slotted input.\n * @attr placeholder - Placeholder mirrored onto the native input; a consumer `placeholder`\n * attribute on the input itself is always honored instead.\n * @attr open - Whether the search view panel is open. Host writes are silent.\n * @attr default-open - Initial uncontrolled search view open state.\n * @attr default-value - Initial uncontrolled value hint, applied once.\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 * @cssprop [--rc-search-bar-view-bg=var(--rc-search-bar-bg)] - Search view panel background\n * @cssprop [--rc-search-bar-view-color=var(--rc-search-bar-color)] - Search view panel text color\n * @cssprop [--rc-search-bar-view-radius=var(--rc-search-bar-radius)] - Search view panel radius\n * @cssprop [--rc-search-bar-view-shadow=var(--rc-search-bar-shadow)] - Search view panel shadow\n * @cssprop [--rc-search-bar-view-border=var(--rc-search-bar-border)] - Search view panel border\n * @cssprop [--rc-search-bar-view-offset=0.25rem] - Gap between the search bar and the view panel below it\n * @cssprop [--rc-search-bar-view-padding-block=0.5rem] - Search view suggestion list block padding\n * @cssprop [--rc-search-bar-suggestion-min-block-size=2.75rem] - Datalist-derived suggestion row minimum block size\n * @cssprop [--rc-search-bar-suggestion-padding-inline=1rem] - Datalist-derived suggestion inline padding\n * @cssprop [--rc-search-bar-suggestion-hover-bg=ButtonFace] - Datalist-derived suggestion hover/focus background\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 * @csspart view - Search view panel\n * @csspart suggestions - Suggestions container\n * @csspart suggestion - Datalist-derived suggestion button\n */\nexport class RCSearchBar extends LitElement {\n static styles = [searchBarStyles];\n\n private static readonly _styledRoots = new Set<Document | ShadowRoot>();\n\n private static _ensureBaseStyles(root: Document | ShadowRoot): void {\n if (RCSearchBar._styledRoots.has(root)) {\n return;\n }\n\n RCSearchBar._styledRoots.add(root);\n\n const style = document.createElement('style');\n\n style.setAttribute('data-rc-light-dom-base', 'rc-search-bar');\n style.textContent = LIGHT_DOM_CSS;\n\n if (root instanceof Document) {\n root.head.append(style);\n } else {\n root.append(style);\n }\n }\n\n /** Presentation mode: docked search bar or expandable search view. */\n @property({ type: String, reflect: true })\n variant: RCSearchBarVariant = 'bar';\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\n set disabled(value: boolean) {\n const old = this.disabled;\n\n this._disabledHost = value;\n\n const $input = this._$input();\n\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 _open = false;\n\n private _defaultOpen = false;\n\n private _openInitialized = false;\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 private _$dataListRef: WeakRef<HTMLDataListElement> | null = null;\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 @state()\n private _hasSuggestionsSlot = false;\n\n @state()\n private _dataListSuggestions: RCSearchBarSuggestion[] = [];\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 if (this.variant === 'view') {\n this.showView();\n }\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 this._syncDataListSuggestions($input);\n }\n });\n\n private readonly _dataListObserver = new MutationObserver(() => this._syncDataListSuggestions());\n\n private readonly _inputController = new NativeChildController<HTMLInputElement>(this, {\n selector: ':scope > input[type=\"search\"]',\n observe: { childList: true, attributes: true, attributeFilter: ['list'] },\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 /** Whether the search view panel is open. Host writes are silent. */\n @property({ type: Boolean, reflect: true })\n get open(): boolean {\n return this._open;\n }\n\n set open(value: boolean) {\n const oldValue = this._open;\n\n this._open = value;\n this._openInitialized = true;\n\n this.requestUpdate('open', oldValue);\n }\n\n /** Initial uncontrolled search view open state. */\n @property({ type: Boolean, attribute: 'default-open' })\n get defaultOpen(): boolean {\n return this._defaultOpen;\n }\n\n set defaultOpen(value: boolean) {\n const oldValue = this._defaultOpen;\n\n this._defaultOpen = value;\n\n if (!this._openInitialized) {\n this._open = value;\n }\n\n this.requestUpdate('defaultOpen', oldValue);\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\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\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 RCSearchBar._ensureBaseStyles(this.getRootNode() as Document | ShadowRoot);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n\n this._focused = false;\n this._open = 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 $input?.removeEventListener('keydown', this._onNativeKeyDown);\n\n this._disabledObserver.disconnect();\n this._dataListObserver.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 if (changed.has('variant') && this.variant !== 'view' && this._open) {\n const oldOpen = this._open;\n\n this._open = false;\n this.requestUpdate('open', oldOpen);\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 $previousInput.removeEventListener('keydown', this._onNativeKeyDown);\n }\n\n this._disabledObserver.disconnect();\n this._dataListObserver.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 this._dataListSuggestions = [];\n this._$dataListRef = null;\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 this._syncDataListSuggestions($input);\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 $input.addEventListener('keydown', this._onNativeKeyDown);\n\n this._disabledObserver.observe($input, { attributeFilter: ['disabled', 'list'] });\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 readonly _onNativeKeyDown = (e: KeyboardEvent): void => {\n if (e.key === 'Escape' && this.open) {\n e.preventDefault();\n this.closeView();\n }\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 _setUserOpen(open: boolean): void {\n if (this._open === open) {\n return;\n }\n\n const oldOpen = this._open;\n\n this._open = open;\n this._openInitialized = true;\n this.requestUpdate('open', oldOpen);\n\n this.dispatchEvent(\n new CustomEvent<RCSearchBarToggleDetail>('rc-search-bar-toggle', {\n bubbles: true,\n composed: true,\n detail: { open },\n }),\n );\n }\n\n /** Opens the search view and fires `rc-search-bar-toggle` when it changes. */\n public showView(): void {\n if (this.variant !== 'view' || this.disabled) {\n return;\n }\n\n this._setUserOpen(true);\n }\n\n /** Closes the search view and fires `rc-search-bar-toggle` when it changes. */\n public closeView(): void {\n this._setUserOpen(false);\n }\n\n /** Toggles the search view and fires `rc-search-bar-toggle` when it changes. */\n public toggleView(): void {\n this.open ? this.closeView() : this.showView();\n }\n\n private _syncDataListSuggestions($input = this._$input()): void {\n const $dataList = $input?.list ?? null;\n\n if (this._$dataListRef?.deref() !== $dataList) {\n this._dataListObserver.disconnect();\n this._$dataListRef = $dataList ? new WeakRef($dataList) : null;\n\n if ($dataList) {\n this._dataListObserver.observe($dataList, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['value', 'label', 'disabled'],\n });\n }\n }\n\n this._dataListSuggestions = $dataList\n ? Array.from($dataList.options)\n .filter(($option) => !$option.disabled && $option.value)\n .map(($option) => ({\n value: $option.value,\n label: $option.label || $option.textContent?.trim() || $option.value,\n }))\n : [];\n }\n\n private _selectDataListSuggestion(suggestion: RCSearchBarSuggestion): void {\n const $input = this._$input();\n\n if (!$input) {\n return;\n }\n\n this._cancelPendingInput();\n\n $input.value = suggestion.value;\n this._valueInitialized = true;\n this._hasValue = suggestion.value.length > 0;\n\n this.dispatchEvent(\n new CustomEvent<RCSearchBarSuggestionSelectDetail>('rc-search-bar-suggestion-select', {\n bubbles: true,\n composed: true,\n detail: suggestion,\n }),\n );\n\n this._dispatchInput(suggestion.value);\n $input.focus();\n this.closeView();\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\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\n id=\"root\"\n part=\"root\"\n class=${classMap({ empty: !this._hasInput })}\n ${keyInteraction({ attributeTarget: this })}\n >\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 ${this._renderSearchView()}\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 _renderSearchView() {\n if (this.variant !== 'view' || !this.open) {\n return nothing;\n }\n\n const hasDataListSuggestions =\n !this._hasSuggestionsSlot && this._dataListSuggestions.length > 0;\n const empty = !this._hasSuggestionsSlot && !hasDataListSuggestions;\n\n return html`\n <div id=\"view\">\n <div\n id=\"view-surface\"\n part=\"view\"\n ?hidden=${empty}\n class=${classMap({\n empty,\n })}\n >\n <div id=\"suggestions\" part=\"suggestions\">\n <slot name=\"suggestions\" @slotchange=${this._onSuggestionsSlotChange}></slot>\n ${hasDataListSuggestions\n ? this._dataListSuggestions.map(\n (suggestion) => html`\n <button\n part=\"suggestion\"\n type=\"button\"\n @click=${() => this._selectDataListSuggestion(suggestion)}\n >\n <span>${suggestion.label}</span>\n </button>\n `,\n )\n : nothing}\n </div>\n </div>\n </div>\n `;\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 private _onSuggestionsSlotChange(e: Event): void {\n const $slot = e.target as HTMLSlotElement;\n\n this._hasSuggestionsSlot = $slot.assignedElements({ flatten: true }).length > 0;\n }\n}\n\nexport default RCSearchBar;\n"],"names":["searchBarStyles","css","LIGHT_DOM_CSS","_RCSearchBar","_a","LitElement","$input","NativeChildController","$previousInput","root","style","value","old","oldValue","changed","oldOpen","open","$dataList","$option","suggestion","html","classMap","keyInteraction","nothing","hasDataListSuggestions","empty","$slot","__decorateClass","property","state","RCSearchBar"],"mappings":";;;;AAEO,MAAMA,IAAkBC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;ACM/B,MAAMC,IAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AA+If,MAAMC,KAANC,IAAA,cAA0BC,EAAW;AAAA,EAArC,cAAA;AAAA,UAAA,GAAA,SAAA,GA0BL,KAAA,UAA8B,OAI9B,KAAA,WAAW,KAIX,KAAA,aAAa,gBAIb,KAAA,mBAAmB,IASnB,KAAA,mBAAmB,IAgCnB,KAAQ,QAAQ,IAEhB,KAAQ,eAAe,IAEvB,KAAQ,mBAAmB,IAE3B,KAAQ,SAA6B,QAErC,KAAQ,gBAAoC,QAE5C,KAAQ,kBAAkB,IAG1B,KAAQ,oBAAoB,IAE5B,KAAQ,qBAAqB,IAE7B,KAAQ,aAA+C,MAEvD,KAAQ,iBAA4D,QAEpE,KAAQ,gBAAqD,MAG7D,KAAQ,YAAY,IAGpB,KAAQ,YAAY,IAGpB,KAAQ,cAAc,IAGtB,KAAQ,eAAe,IAGvB,KAAQ,iBAAiB,IAGzB,KAAQ,sBAAsB,IAG9B,KAAQ,uBAAgD,CAAA,GAIxD,KAAQ,gBAAqC,QAG7C,KAAQ,WAAW,IAEnB,KAAiB,gBAAgB,MAAY;AAC3C,WAAK,WAAW,IAEZ,KAAK,YAAY,UACnB,KAAK,SAAA;AAAA,IAET,GAEA,KAAiB,eAAe,MAAY;AAC1C,WAAK,WAAW;AAAA,IAClB,GAEA,KAAiB,oBAAoB,IAAI,iBAAiB,MAAM;AAC9D,YAAMC,IAAS,KAAK,QAAA;AAEpB,MAAIA,MACF,KAAK,iBAAiBA,EAAO,UAC7B,KAAK,yBAAyBA,CAAM;AAAA,IAExC,CAAC,GAED,KAAiB,oBAAoB,IAAI,iBAAiB,MAAM,KAAK,0BAA0B,GAE/F,KAAiB,mBAAmB,IAAIC,EAAwC,MAAM;AAAA,MACpF,UAAU;AAAA,MACV,SAAS,EAAE,WAAW,IAAM,YAAY,IAAM,iBAAiB,CAAC,MAAM,EAAA;AAAA,MACtE,UAAU,CAACD,GAAQE,MAAmB,KAAK,YAAYF,GAAQE,CAAc;AAAA,MAC7E,WAAW,MAAM;AAAA,MASjB;AAAA,IAAA,CACD,GA4ND,KAAiB,iBAAiB,CAAC,MAAmB;AACpD,YAAMF,IAAS,EAAE;AAEjB,WAAK,oBAAoB,IACzB,KAAK,YAAYA,EAAO,MAAM,SAAS,GACvC,KAAK,oBAAoBA,EAAO,KAAK;AAAA,IACvC,GAEA,KAAiB,mBAAmB,CAAC,MAA2B;AAC9D,MAAI,EAAE,QAAQ,YAAY,KAAK,SAC7B,EAAE,eAAA,GACF,KAAK,UAAA;AAAA,IAET;AAAA,EAAA;AAAA,EA3YA,OAAe,kBAAkBG,GAAmC;AAClE,QAAIN,EAAY,aAAa,IAAIM,CAAI;AACnC;AAGFN,IAAAA,EAAY,aAAa,IAAIM,CAAI;AAEjC,UAAMC,IAAQ,SAAS,cAAc,OAAO;AAE5C,IAAAA,EAAM,aAAa,0BAA0B,eAAe,GAC5DA,EAAM,cAAcR,GAEhBO,aAAgB,WAClBA,EAAK,KAAK,OAAOC,CAAK,IAEtBD,EAAK,OAAOC,CAAK;AAAA,EAErB;AAAA,EA6BA,IAAI,WAAoB;AAGtB,WAAO,KAAK,iBAAiB,KAAK;AAAA,EACpC;AAAA,EAEA,IAAI,SAASC,GAAgB;AAC3B,UAAMC,IAAM,KAAK;AAEjB,SAAK,gBAAgBD;AAErB,UAAML,IAAS,KAAK,QAAA;AAEpB,IAAIA,MACFA,EAAO,WAAWK,IAGpB,KAAK,cAAc,YAAYC,CAAG;AAAA,EACpC;AAAA,EAsGA,IAAI,OAAgB;AAClB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,KAAKD,GAAgB;AACvB,UAAME,IAAW,KAAK;AAEtB,SAAK,QAAQF,GACb,KAAK,mBAAmB,IAExB,KAAK,cAAc,QAAQE,CAAQ;AAAA,EACrC;AAAA,EAIA,IAAI,cAAuB;AACzB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,YAAYF,GAAgB;AAC9B,UAAME,IAAW,KAAK;AAEtB,SAAK,eAAeF,GAEf,KAAK,qBACR,KAAK,QAAQA,IAGf,KAAK,cAAc,eAAeE,CAAQ;AAAA,EAC5C;AAAA,EAOA,IAAI,QAAgB;AAClB,WAAO,KAAK,QAAA,GAAW,SAAS,KAAK,UAAU,KAAK,iBAAiB;AAAA,EACvE;AAAA,EAEA,IAAI,MAAMF,GAAe;AACvB,UAAME,IAAW,KAAK;AAEtB,SAAK,SAASF,GACd,KAAK,kBAAkB,IACvB,KAAK,oBAAoB;AAEzB,UAAML,IAAS,KAAK,QAAA;AAEpB,IAAIA,MACFA,EAAO,QAAQK,IAGjB,KAAK,YAAYA,EAAM,SAAS,GAEhC,KAAK,cAAc,SAASE,CAAQ;AAAA,EACtC;AAAA,EAOA,IAAI,eAAmC;AACrC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,aAAaF,GAA2B;AAC1C,UAAME,IAAW,KAAK;AAEtB,SAAK,gBAAgBF;AAErB,UAAML,IAAS,KAAK,QAAA;AAEpB,IAAIA,KAAUK,MAAU,UAAa,CAAC,KAAK,sBACzCL,EAAO,QAAQK,GACf,KAAK,YAAYA,EAAM,SAAS,IAGlC,KAAK,cAAc,gBAAgBE,CAAQ;AAAA,EAC7C;AAAA,EAES,oBAA0B;AACjC,UAAM,kBAAA,GACNV,EAAY,kBAAkB,KAAK,aAAsC;AAAA,EAC3E;AAAA,EAES,uBAA6B;AACpC,UAAM,qBAAA,GAEN,KAAK,WAAW,IAChB,KAAK,QAAQ,IACb,KAAK,oBAAA;AAEL,UAAMG,IAAS,KAAK,QAAA;AAEpB,IAAAA,GAAQ,oBAAoB,SAAS,KAAK,cAAc,GACxDA,GAAQ,oBAAoB,SAAS,KAAK,aAAa,GACvDA,GAAQ,oBAAoB,QAAQ,KAAK,YAAY,GACrDA,GAAQ,oBAAoB,WAAW,KAAK,gBAAgB,GAE5D,KAAK,kBAAkB,WAAA,GACvB,KAAK,kBAAkB,WAAA;AAAA,EACzB;AAAA,EAEmB,QAAQQ,GAAqC;AAC9D,QAAIA,EAAQ,IAAI,aAAa,GAAG;AAC9B,YAAMR,IAAS,KAAK,QAAA;AAEpB,MAAIA,KACF,KAAK,kBAAkBA,CAAM;AAAA,IAEjC;AAEA,QAAIQ,EAAQ,IAAI,SAAS,KAAK,KAAK,YAAY,UAAU,KAAK,OAAO;AACnE,YAAMC,IAAU,KAAK;AAErB,WAAK,QAAQ,IACb,KAAK,cAAc,QAAQA,CAAO;AAAA,IACpC;AAAA,EACF;AAAA,EAEQ,UAAmC;AACzC,WAAO,KAAK,YAAY,MAAA,KAAW;AAAA,EACrC;AAAA,EAEQ,oBAA0B;AAChC,SAAK,iBAAiB,KAAA;AAAA,EACxB;AAAA,EAEQ,YACNT,GACAE,GACM;AAgBN,QAfIA,KAAkBA,MAAmBF,MACvCE,EAAe,oBAAoB,SAAS,KAAK,cAAc,GAC/DA,EAAe,oBAAoB,SAAS,KAAK,aAAa,GAC9DA,EAAe,oBAAoB,QAAQ,KAAK,YAAY,GAC5DA,EAAe,oBAAoB,WAAW,KAAK,gBAAgB,IAGrE,KAAK,kBAAkB,WAAA,GACvB,KAAK,kBAAkB,WAAA,GACvB,KAAK,WAAW,IAEhB,KAAK,aAAaF,IAAS,IAAI,QAAQA,CAAM,IAAI,MACjD,KAAK,YAAYA,MAAW,MAC5B,KAAK,qBAAqBA,GAAQ,aAAa,aAAa,KAAK,IAE7D,CAACA,GAAQ;AACX,WAAK,YAAY,IACjB,KAAK,uBAAuB,CAAA,GAC5B,KAAK,gBAAgB;AAErB;AAAA,IACF;AAGA,mBAAe,MAAM;AACnB,MAAKA,EAAO,gBAIR,KAAK,kBACPA,EAAO,QAAQ,KAAK,UAAU,KACrBA,EAAO,QAEhB,KAAK,oBAAoB,KAChB,KAAK,kBAAkB,UAAa,CAAC,KAAK,sBACnDA,EAAO,QAAQ,KAAK,gBAGtB,KAAK,kBAAkBA,CAAM,GAEzB,KAAK,kBAAkB,WACzBA,EAAO,WAAW,KAAK,gBAGzB,KAAK,iBAAiBA,EAAO,UAC7B,KAAK,YAAYA,EAAO,MAAM,SAAS,GACvC,KAAK,yBAAyBA,CAAM,GAepC,KAAK,WAAWA,CAAM;AAAA,IACxB,CAAC;AAAA,EACH;AAAA,EAEQ,WAAWA,GAAgC;AACjD,IAAAA,EAAO,iBAAiB,SAAS,KAAK,cAAc,GACpDA,EAAO,iBAAiB,SAAS,KAAK,aAAa,GACnDA,EAAO,iBAAiB,QAAQ,KAAK,YAAY,GACjDA,EAAO,iBAAiB,WAAW,KAAK,gBAAgB,GAExD,KAAK,kBAAkB,QAAQA,GAAQ,EAAE,iBAAiB,CAAC,YAAY,MAAM,GAAG;AAAA,EAClF;AAAA,EAEQ,kBAAkBA,GAAgC;AACxD,IAAI,KAAK,gBAAgB,UAAa,KAAK,uBAI3CA,EAAO,cAAc,KAAK;AAAA,EAC5B;AAAA,EAiBQ,oBAAoBK,GAAqB;AAG/C,QAFA,KAAK,oBAAA,GAED,KAAK,YAAY,GAAG;AACtB,WAAK,eAAeA,CAAK;AAEzB;AAAA,IACF;AAEA,SAAK,iBAAiB,WAAW,MAAM;AACrC,WAAK,iBAAiB,QACtB,KAAK,eAAeA,CAAK;AAAA,IAC3B,GAAG,KAAK,QAAQ;AAAA,EAClB;AAAA,EAEQ,sBAA4B;AAClC,IAAI,KAAK,mBAAmB,WAI5B,aAAa,KAAK,cAAc,GAChC,KAAK,iBAAiB;AAAA,EACxB;AAAA,EAEQ,eAAeA,GAAqB;AAC1C,SAAK;AAAA,MACH,IAAI,YAAoC,uBAAuB;AAAA,QAC7D,SAAS;AAAA,QACT,UAAU;AAAA,QACV,QAAQ,EAAE,OAAAA,EAAA;AAAA,MAAM,CACjB;AAAA,IAAA;AAAA,EAEL;AAAA,EAEQ,aAAaK,GAAqB;AACxC,QAAI,KAAK,UAAUA;AACjB;AAGF,UAAMD,IAAU,KAAK;AAErB,SAAK,QAAQC,GACb,KAAK,mBAAmB,IACxB,KAAK,cAAc,QAAQD,CAAO,GAElC,KAAK;AAAA,MACH,IAAI,YAAqC,wBAAwB;AAAA,QAC/D,SAAS;AAAA,QACT,UAAU;AAAA,QACV,QAAQ,EAAE,MAAAC,EAAA;AAAA,MAAK,CAChB;AAAA,IAAA;AAAA,EAEL;AAAA;AAAA,EAGO,WAAiB;AACtB,IAAI,KAAK,YAAY,UAAU,KAAK,YAIpC,KAAK,aAAa,EAAI;AAAA,EACxB;AAAA;AAAA,EAGO,YAAkB;AACvB,SAAK,aAAa,EAAK;AAAA,EACzB;AAAA;AAAA,EAGO,aAAmB;AACxB,SAAK,OAAO,KAAK,UAAA,IAAc,KAAK,SAAA;AAAA,EACtC;AAAA,EAEQ,yBAAyBV,IAAS,KAAK,WAAiB;AAC9D,UAAMW,IAAYX,GAAQ,QAAQ;AAElC,IAAI,KAAK,eAAe,MAAA,MAAYW,MAClC,KAAK,kBAAkB,WAAA,GACvB,KAAK,gBAAgBA,IAAY,IAAI,QAAQA,CAAS,IAAI,MAEtDA,KACF,KAAK,kBAAkB,QAAQA,GAAW;AAAA,MACxC,WAAW;AAAA,MACX,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,iBAAiB,CAAC,SAAS,SAAS,UAAU;AAAA,IAAA,CAC/C,IAIL,KAAK,uBAAuBA,IACxB,MAAM,KAAKA,EAAU,OAAO,EACzB,OAAO,CAACC,MAAY,CAACA,EAAQ,YAAYA,EAAQ,KAAK,EACtD,IAAI,CAACA,OAAa;AAAA,MACjB,OAAOA,EAAQ;AAAA,MACf,OAAOA,EAAQ,SAASA,EAAQ,aAAa,KAAA,KAAUA,EAAQ;AAAA,IAAA,EAC/D,IACJ,CAAA;AAAA,EACN;AAAA,EAEQ,0BAA0BC,GAAyC;AACzE,UAAMb,IAAS,KAAK,QAAA;AAEpB,IAAKA,MAIL,KAAK,oBAAA,GAELA,EAAO,QAAQa,EAAW,OAC1B,KAAK,oBAAoB,IACzB,KAAK,YAAYA,EAAW,MAAM,SAAS,GAE3C,KAAK;AAAA,MACH,IAAI,YAA+C,mCAAmC;AAAA,QACpF,SAAS;AAAA,QACT,UAAU;AAAA,QACV,QAAQA;AAAA,MAAA,CACT;AAAA,IAAA,GAGH,KAAK,eAAeA,EAAW,KAAK,GACpCb,EAAO,MAAA,GACP,KAAK,UAAA;AAAA,EACP;AAAA,EAEQ,eAAqB;AAC3B,UAAMA,IAAS,KAAK,QAAA;AAEpB,IAAKA,MAIL,KAAK,oBAAA,GAELA,EAAO,QAAQ,IAEf,KAAK,oBAAoB,IACzB,KAAK,YAAY,IAEjB,KAAK;AAAA,MACH,IAAI,YAAY,uBAAuB;AAAA,QACrC,SAAS;AAAA,QACT,UAAU;AAAA,QACV,QAAQ,CAAA;AAAA,MAAC,CACV;AAAA,IAAA,GAGH,KAAK,eAAe,EAAE,GAItBA,EAAO,MAAA;AAAA,EACT;AAAA,EAEmB,SAAS;AAC1B,WAAOc;AAAA;AAAA;AAAA;AAAA,gBAIKC,EAAS,EAAE,OAAO,CAAC,KAAK,UAAA,CAAW,CAAC;AAAA,UAC1CC,EAAe,EAAE,iBAAiB,MAAM,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,kBAKjCD,EAAS,EAAE,OAAO,CAAC,KAAK,eAAe,CAAC,KAAK,WAAW,CAAC;AAAA;AAAA,6CAE9B,KAAK,oBAAoB;AAAA;AAAA;AAAA,4BAG1C,KAAK,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uBAM3B,KAAK,UAAU;AAAA,oBAClB,CAAC,KAAK,SAAS;AAAA,mBAChB,KAAK,aAAa,CAAC,KAAK,aAAa,EAAE,KAAK,oBAAoB,KAAK,SAAS;AAAA,sBAC3E,KAAK,cAAc;AAAA,mBACtB,KAAK,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA,oDAKgBA,EAAS,EAAE,OAAO,CAAC,KAAK,aAAA,CAAc,CAAC;AAAA,8CAC7C,KAAK,qBAAqB;AAAA;AAAA;AAAA,QAGhE,KAAK,mBAAmB;AAAA;AAAA,EAE9B;AAAA;AAAA,EAGO,QAAc;AACnB,SAAK,aAAA;AAAA,EACP;AAAA,EAEQ,oBAAoB;AAC1B,QAAI,KAAK,YAAY,UAAU,CAAC,KAAK;AACnC,aAAOE;AAGT,UAAMC,IACJ,CAAC,KAAK,uBAAuB,KAAK,qBAAqB,SAAS,GAC5DC,IAAQ,CAAC,KAAK,uBAAuB,CAACD;AAE5C,WAAOJ;AAAA;AAAA;AAAA;AAAA;AAAA,oBAKSK,CAAK;AAAA,kBACPJ,EAAS;AAAA,MACf,OAAAI;AAAA,IAAA,CACD,CAAC;AAAA;AAAA;AAAA,mDAGuC,KAAK,wBAAwB;AAAA,cAClED,IACE,KAAK,qBAAqB;AAAA,MACxB,CAACL,MAAeC;AAAA;AAAA;AAAA;AAAA,+BAIH,MAAM,KAAK,0BAA0BD,CAAU,CAAC;AAAA;AAAA,8BAEjDA,EAAW,KAAK;AAAA;AAAA;AAAA,IAAA,IAI9BI,CAAO;AAAA;AAAA;AAAA;AAAA;AAAA,EAKrB;AAAA,EAEQ,qBAAqB,GAAgB;AAC3C,UAAMG,IAAQ,EAAE;AAEhB,SAAK,cAAcA,EAAM,iBAAA,EAAmB,SAAS;AAAA,EACvD;AAAA,EAEQ,sBAAsB,GAAgB;AAC5C,UAAMA,IAAQ,EAAE;AAEhB,SAAK,eAAeA,EAAM,iBAAA,EAAmB,SAAS;AAAA,EACxD;AAAA,EAEQ,yBAAyB,GAAgB;AAC/C,UAAMA,IAAQ,EAAE;AAEhB,SAAK,sBAAsBA,EAAM,iBAAiB,EAAE,SAAS,GAAA,CAAM,EAAE,SAAS;AAAA,EAChF;AACF,GAjpBEtB,EAAO,SAAS,CAACJ,CAAe,GAEhCI,EAAwB,mCAAmB,IAAA,GAHtCA;AA0BLuB,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GAzB9BzB,EA0BX,WAAA,WAAA,CAAA;AAIAwB,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GA7BfzB,EA8BX,WAAA,YAAA,CAAA;AAIAwB,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,WAAW,eAAe;AAAA,GAjCzCzB,EAkCX,WAAA,cAAA,CAAA;AAIAwB,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,SAAS,WAAW,sBAAsB,SAAS,IAAM;AAAA,GArChEzB,EAsCX,WAAA,oBAAA,CAAA;AASAwB,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,SAAS,WAAW,uBAAuB;AAAA,GA9ClDzB,EA+CX,WAAA,oBAAA,CAAA;AAIIwB,EAAA;AAAA,EADHC,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GAlD/BzB,EAmDP,WAAA,YAAA,CAAA;AA0BJwB,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GA5EfzB,EA6EX,WAAA,eAAA,CAAA;AA0BQwB,EAAA;AAAA,EADPE,EAAA;AAAM,GAtGI1B,EAuGH,WAAA,aAAA,CAAA;AAGAwB,EAAA;AAAA,EADPE,EAAA;AAAM,GAzGI1B,EA0GH,WAAA,aAAA,CAAA;AAGAwB,EAAA;AAAA,EADPE,EAAA;AAAM,GA5GI1B,EA6GH,WAAA,eAAA,CAAA;AAGAwB,EAAA;AAAA,EADPE,EAAA;AAAM,GA/GI1B,EAgHH,WAAA,gBAAA,CAAA;AAGAwB,EAAA;AAAA,EADPE,EAAA;AAAM,GAlHI1B,EAmHH,WAAA,kBAAA,CAAA;AAGAwB,EAAA;AAAA,EADPE,EAAA;AAAM,GArHI1B,EAsHH,WAAA,uBAAA,CAAA;AAGAwB,EAAA;AAAA,EADPE,EAAA;AAAM,GAxHI1B,EAyHH,WAAA,wBAAA,CAAA;AAOAwB,EAAA;AAAA,EADPE,EAAA;AAAM,GA/HI1B,EAgIH,WAAA,YAAA,CAAA;AA2CJwB,EAAA;AAAA,EADHC,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GA1K/BzB,EA2KP,WAAA,QAAA,CAAA;AAeAwB,EAAA;AAAA,EADHC,EAAS,EAAE,MAAM,SAAS,WAAW,gBAAgB;AAAA,GAzL3CzB,EA0LP,WAAA,eAAA,CAAA;AAqBAwB,EAAA;AAAA,EADHC,EAAS,EAAE,WAAW,GAAA,CAAO;AAAA,GA9MnBzB,EA+MP,WAAA,SAAA,CAAA;AA2BAwB,EAAA;AAAA,EADHC,EAAS,EAAE,MAAM,QAAQ,WAAW,iBAAiB;AAAA,GAzO3CzB,EA0OP,WAAA,gBAAA,CAAA;AA1OC,IAAM2B,IAAN3B;"}