rich-input 1.2.2 → 1.3.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/README.md +9 -2
- package/assets/rich-input-parts.svg +92 -61
- package/components/rich-input.js +122 -19
- package/package.json +5 -2
- package/utils/query-parser.js +12 -6
package/README.md
CHANGED
|
@@ -45,7 +45,8 @@ The visual below illustrates the internal Shadow DOM elements, exposed CSS Shado
|
|
|
45
45
|
- `::part(suggestions-header)`: The header bar at the top of the suggestions popover.
|
|
46
46
|
- `::part(suggestions-list)`: The `<ul>` container holding autocomplete suggestion items.
|
|
47
47
|
- `::part(suggestion-item)`: Each suggestion `<li>` row.
|
|
48
|
-
- `::part(suggestion-item-active)`: The currently
|
|
48
|
+
- `::part(suggestion-item-active)`: The currently focused / hovered suggestion row.
|
|
49
|
+
- `::part(suggestion-item-selected)`: The suggestion row matching the value currently echoed in the input.
|
|
49
50
|
- `::part(suggestion-image)`: The circular logo, icon, or avatar image prepended to rich suggestions.
|
|
50
51
|
- `::part(suggestion-keyword)`: The keyword label text inside a keyword suggestion.
|
|
51
52
|
- `::part(suggestion-value)`: The value label text inside a value suggestion.
|
|
@@ -82,6 +83,7 @@ Nest `<datalist>` elements inside `<rich-input>` to configure keywords and autoc
|
|
|
82
83
|
<rich-input placeholder="Search music catalog...">
|
|
83
84
|
<datalist id="label" label="Record Label">
|
|
84
85
|
<option value="Defected"></option>
|
|
86
|
+
<option value="House"></option>
|
|
85
87
|
<option value="Keinemusik"></option>
|
|
86
88
|
<option value="Kranky"></option>
|
|
87
89
|
<option value="Madhouse Records"></option>
|
|
@@ -134,6 +136,10 @@ Datalists can be added, updated, or removed dynamically at runtime; `<rich-input
|
|
|
134
136
|
<img src="assets/defected.jpg" height="50" width="50" alt="Defected Logo">
|
|
135
137
|
Defected
|
|
136
138
|
</option>
|
|
139
|
+
<option value="House">
|
|
140
|
+
<img src="assets/house.jpg" height="50" width="50" alt="House Logo">
|
|
141
|
+
House
|
|
142
|
+
</option>
|
|
137
143
|
<option value="Keinemusik">
|
|
138
144
|
<img src="assets/keinemusik.jpg" height="50" width="50" alt="Keinemusik Logo">
|
|
139
145
|
Keinemusik
|
|
@@ -345,7 +351,8 @@ rich-input::part(suggestion-item-active) {
|
|
|
345
351
|
| `::part(suggestions-header)` | The header bar at the top of the popover |
|
|
346
352
|
| `::part(suggestions-list)` | The `<ul>` list element |
|
|
347
353
|
| `::part(suggestion-item)` | Each suggestion `<li>` item |
|
|
348
|
-
| `::part(suggestion-item-active)` | The currently
|
|
354
|
+
| `::part(suggestion-item-active)` | The currently focused / hovered suggestion item |
|
|
355
|
+
| `::part(suggestion-item-selected)` | The suggestion item matching the value currently echoed in the input |
|
|
349
356
|
| `::part(suggestion-keyword)` | Keyword name element in suggestion items |
|
|
350
357
|
| `::part(suggestion-value)` | Value element in suggestion items |
|
|
351
358
|
| `::part(suggestion-content)` | The content container inside each suggestion item |
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
--text-muted: #64748b;
|
|
11
11
|
--text-hint: #94a3b8;
|
|
12
12
|
--popover-bg: #ffffff;
|
|
13
|
+
--selected-item-bg: rgba(219, 39, 119, 0.07);
|
|
13
14
|
--active-item-bg: #eff6ff;
|
|
14
15
|
|
|
15
16
|
/* Annotation Colors */
|
|
@@ -22,6 +23,7 @@
|
|
|
22
23
|
--c-popover: #9333ea; /* Purple */
|
|
23
24
|
--c-header: #475569; /* Slate */
|
|
24
25
|
--c-list: #7c3aed; /* Violet */
|
|
26
|
+
--c-selected: #db2777; /* Pink / Rose */
|
|
25
27
|
--c-item: #16a34a; /* Green */
|
|
26
28
|
--c-active: #0284c7; /* Sky */
|
|
27
29
|
--c-image: #ea580c; /* Orange */
|
|
@@ -40,6 +42,7 @@
|
|
|
40
42
|
--text-muted: #94a3b8;
|
|
41
43
|
--text-hint: #64748b;
|
|
42
44
|
--popover-bg: #1e293b;
|
|
45
|
+
--selected-item-bg: rgba(244, 114, 182, 0.12);
|
|
43
46
|
--active-item-bg: #1e3a5f;
|
|
44
47
|
|
|
45
48
|
/* Annotation Colors (Brighter for Dark Mode) */
|
|
@@ -52,6 +55,7 @@
|
|
|
52
55
|
--c-popover: #c084fc;
|
|
53
56
|
--c-header: #94a3b8;
|
|
54
57
|
--c-list: #a78bfa;
|
|
58
|
+
--c-selected: #f472b6;
|
|
55
59
|
--c-item: #4ade80;
|
|
56
60
|
--c-active: #38bdf8;
|
|
57
61
|
--c-image: #fb923c;
|
|
@@ -180,6 +184,7 @@
|
|
|
180
184
|
:scope:has(.lbl-popover:hover) .target-popover,
|
|
181
185
|
:scope:has(.lbl-header:hover) .target-header,
|
|
182
186
|
:scope:has(.lbl-list:hover) .target-list,
|
|
187
|
+
:scope:has(.lbl-selected:hover) .target-selected,
|
|
183
188
|
:scope:has(.lbl-item:hover) .target-item,
|
|
184
189
|
:scope:has(.lbl-active:hover) .target-active,
|
|
185
190
|
:scope:has(.lbl-image:hover) .target-image,
|
|
@@ -193,7 +198,7 @@
|
|
|
193
198
|
}
|
|
194
199
|
|
|
195
200
|
/* Contained parts: when hovering a container, contained parts in the preview also remain at opacity 1 */
|
|
196
|
-
/* Control contains icon, input (including highlight
|
|
201
|
+
/* Control contains icon, input (including highlight house), and clear button */
|
|
197
202
|
:scope:has(.lbl-control:hover) #component-preview .target-icon,
|
|
198
203
|
:scope:has(.lbl-control:hover) #component-preview .target-input,
|
|
199
204
|
:scope:has(.lbl-control:hover) #component-preview .target-hl-val,
|
|
@@ -201,19 +206,21 @@
|
|
|
201
206
|
opacity: 1 !important;
|
|
202
207
|
}
|
|
203
208
|
|
|
204
|
-
/* Input contains highlight label (
|
|
209
|
+
/* Input contains highlight label (house text and background pill) */
|
|
205
210
|
:scope:has(.lbl-input:hover) #component-preview .target-hl-val {
|
|
206
211
|
opacity: 1 !important;
|
|
207
212
|
}
|
|
208
213
|
|
|
209
214
|
/* Popover contains header, list, and all suggestion items */
|
|
210
215
|
:scope:has(.lbl-popover:hover) #component-preview .target-header,
|
|
216
|
+
:scope:has(.lbl-popover:hover) #component-preview .target-selected,
|
|
211
217
|
:scope:has(.lbl-popover:hover) #component-preview .target-item,
|
|
212
218
|
:scope:has(.lbl-popover:hover) #component-preview .target-active {
|
|
213
219
|
opacity: 1 !important;
|
|
214
220
|
}
|
|
215
221
|
|
|
216
222
|
/* Suggestions list contains all suggestion items */
|
|
223
|
+
:scope:has(.lbl-list:hover) #component-preview .target-selected,
|
|
217
224
|
:scope:has(.lbl-list:hover) #component-preview .target-item,
|
|
218
225
|
:scope:has(.lbl-list:hover) #component-preview .target-active {
|
|
219
226
|
opacity: 1 !important;
|
|
@@ -229,6 +236,7 @@
|
|
|
229
236
|
:scope:has(.lbl-popover:hover) .target-popover.guide-line,
|
|
230
237
|
:scope:has(.lbl-header:hover) .target-header.guide-line,
|
|
231
238
|
:scope:has(.lbl-list:hover) .target-list.guide-line,
|
|
239
|
+
:scope:has(.lbl-selected:hover) .target-selected.guide-line,
|
|
232
240
|
:scope:has(.lbl-item:hover) .target-item.guide-line,
|
|
233
241
|
:scope:has(.lbl-active:hover) .target-active.guide-line,
|
|
234
242
|
:scope:has(.lbl-image:hover) .target-image.guide-line,
|
|
@@ -246,6 +254,7 @@
|
|
|
246
254
|
:scope:has(.lbl-popover:hover) .target-popover.guide-box,
|
|
247
255
|
:scope:has(.lbl-header:hover) .target-header.guide-box,
|
|
248
256
|
:scope:has(.lbl-list:hover) .target-list.guide-box,
|
|
257
|
+
:scope:has(.lbl-selected:hover) .target-selected.guide-box,
|
|
249
258
|
:scope:has(.lbl-item:hover) .target-item.guide-box,
|
|
250
259
|
:scope:has(.lbl-active:hover) .target-active.guide-box,
|
|
251
260
|
:scope:has(.lbl-image:hover) .target-image.guide-box,
|
|
@@ -263,12 +272,16 @@
|
|
|
263
272
|
<feDropShadow dx="0" dy="8" stdDeviation="12" flood-opacity="0.12"/>
|
|
264
273
|
</filter>
|
|
265
274
|
|
|
275
|
+
<clipPath id="logo-clip-house">
|
|
276
|
+
<circle cx="543" cy="176" r="19"/>
|
|
277
|
+
</clipPath>
|
|
278
|
+
|
|
266
279
|
<clipPath id="logo-clip-madhouse">
|
|
267
|
-
<circle cx="543" cy="
|
|
280
|
+
<circle cx="543" cy="246" r="19"/>
|
|
268
281
|
</clipPath>
|
|
269
282
|
|
|
270
283
|
<clipPath id="logo-clip-wph">
|
|
271
|
-
<circle cx="543" cy="
|
|
284
|
+
<circle cx="543" cy="316" r="19"/>
|
|
272
285
|
</clipPath>
|
|
273
286
|
</defs>
|
|
274
287
|
|
|
@@ -291,14 +304,14 @@
|
|
|
291
304
|
<!-- Input Text Area (label: & caret): ::part(input) -->
|
|
292
305
|
<g class="comp-part target-input">
|
|
293
306
|
<text class="mono-text" x="458" y="82" font-size="15" fill="var(--text-muted)" font-weight="600">label:</text>
|
|
294
|
-
<line x1="
|
|
307
|
+
<line x1="558" y1="65" x2="558" y2="87" stroke="var(--c-active)" stroke-width="2.5"/>
|
|
295
308
|
</g>
|
|
296
309
|
|
|
297
|
-
<!-- Highlight Pill for "
|
|
310
|
+
<!-- Highlight Pill for "house": ::highlight(label) -->
|
|
298
311
|
<g class="comp-part target-hl-val">
|
|
299
|
-
<rect x="508" y="62" width="
|
|
300
|
-
<line x1="512" y1="87" x2="
|
|
301
|
-
<text class="mono-text" x="512" y="82" font-size="15" fill="var(--c-control)" font-weight="600">
|
|
312
|
+
<rect x="508" y="62" width="52" height="28" rx="5" fill="rgba(37, 99, 235, 0.14)"/>
|
|
313
|
+
<line x1="512" y1="87" x2="556" y2="87" stroke="var(--c-control)" stroke-width="2" stroke-linecap="round"/>
|
|
314
|
+
<text class="mono-text" x="512" y="82" font-size="15" fill="var(--c-control)" font-weight="600">house</text>
|
|
302
315
|
</g>
|
|
303
316
|
|
|
304
317
|
<!-- Clear Button: ::part(clear-button) -->
|
|
@@ -307,8 +320,8 @@
|
|
|
307
320
|
<path d="M897 71 L907 81 M907 71 L897 81" stroke="var(--text-muted)" stroke-width="2" stroke-linecap="round"/>
|
|
308
321
|
</g>
|
|
309
322
|
|
|
310
|
-
<!-- Suggestions Popover Background Card (aligned with colored box of "
|
|
311
|
-
<rect class="component-card comp-part target-popover" x="508" y="94" width="350" height="
|
|
323
|
+
<!-- Suggestions Popover Background Card (aligned with colored box of "house" at x=508): ::part(popover) -->
|
|
324
|
+
<rect class="component-card comp-part target-popover" x="508" y="94" width="350" height="264" rx="10" filter="url(#shadow)"/>
|
|
312
325
|
|
|
313
326
|
<!-- Popover Header: ::part(suggestions-header) -->
|
|
314
327
|
<g class="comp-part target-header">
|
|
@@ -317,22 +330,30 @@
|
|
|
317
330
|
<text class="ui-text" x="526" y="121" font-size="12" font-weight="700" letter-spacing="0.06em" fill="var(--text-muted)" style="text-transform: uppercase;">Record Label</text>
|
|
318
331
|
</g>
|
|
319
332
|
|
|
320
|
-
<!-- Item 1: "
|
|
321
|
-
<rect class="comp-part target-
|
|
333
|
+
<!-- Item 1 (Selected): "House": ::part(suggestion-item-selected) -->
|
|
334
|
+
<rect class="comp-part target-selected" x="516" y="144" width="334" height="64" rx="8" fill="var(--selected-item-bg)"/>
|
|
335
|
+
<g class="comp-part target-selected">
|
|
336
|
+
<image href="data:image/jpeg;base64,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" x="524" y="157" width="38" height="38" preserveAspectRatio="xMidYMid slice" clip-path="url(#logo-clip-house)"/>
|
|
337
|
+
<circle cx="543" cy="176" r="19" fill="none" stroke="var(--border-color)" stroke-width="1.5"/>
|
|
338
|
+
</g>
|
|
339
|
+
<text class="ui-text comp-part target-selected" x="574" y="181" font-size="15" font-weight="600" fill="var(--text-color)">House</text>
|
|
340
|
+
|
|
341
|
+
<!-- Item 2: "Madhouse Records": ::part(suggestion-item) -->
|
|
342
|
+
<rect class="comp-part target-item" x="516" y="214" width="334" height="64" rx="8" fill="none"/>
|
|
322
343
|
<g class="comp-part target-image target-item">
|
|
323
|
-
<image href="data:image/jpeg;base64,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" x="524" y="
|
|
324
|
-
<circle cx="543" cy="
|
|
344
|
+
<image href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAASABIAAD/4QBYRXhpZgAATU0AKgAAAAgAAgESAAMAAAABAAEAAIdpAAQAAAABAAAAJgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAZKADAAQAAAABAAAAZAAAAAD/7QA4UGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAAA4QklNBCUAAAAAABDUHYzZjwCyBOmACZjs+EJ+/8IAEQgAZABkAwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAMCBAEFAAYHCAkKC//EAMMQAAEDAwIEAwQGBAcGBAgGcwECAAMRBBIhBTETIhAGQVEyFGFxIweBIJFCFaFSM7EkYjAWwXLRQ5I0ggjhU0AlYxc18JNzolBEsoPxJlQ2ZJR0wmDShKMYcOInRTdls1V1pJXDhfLTRnaA40dWZrQJChkaKCkqODk6SElKV1hZWmdoaWp3eHl6hoeIiYqQlpeYmZqgpaanqKmqsLW2t7i5usDExcbHyMnK0NTV1tfY2drg5OXm5+jp6vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAQIAAwQFBgcICQoL/8QAwxEAAgIBAwMDAgMFAgUCBASHAQACEQMQEiEEIDFBEwUwIjJRFEAGMyNhQhVxUjSBUCSRoUOxFgdiNVPw0SVgwUThcvEXgmM2cCZFVJInotIICQoYGRooKSo3ODk6RkdISUpVVldYWVpkZWZnaGlqc3R1dnd4eXqAg4SFhoeIiYqQk5SVlpeYmZqgo6SlpqeoqaqwsrO0tba3uLm6wMLDxMXGx8jJytDT1NXW19jZ2uDi4+Tl5ufo6ery8/T19vf4+fr/2wBDAAICAgICAgMCAgMFAwMDBQYFBQUFBggGBgYGBggKCAgICAgICgoKCgoKCgoMDAwMDAwODg4ODg8PDw8PDw8PDw//2wBDAQICAgQEBAcEBAcQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/2gAMAwEAAhEDEQAAAfh7Rujnk1t6g2vmHunlfpWnReeLfT/zI2nLVXsnA5cnM5w3TGdGrXrAhYXvHzz9Fabg6bzuvff0x95lwsPTPKPor56VFUA+iy5ue0SEvaG+oS3qBPQeI27OO6X7G+Fy31D5/wC0eLadPiv0F4L63lx/O1+Opx5BxdUoF7Q39CT9OHp+96vU7TzXufkkt9V+Y+H8/lye7dN5L9JNt8r8gd7z+e95920hfsGH2A+3FdOig37fojy+2da9XnfcDsRmfyc1gieRcb91fEWXLyO2w4da1er7S+a+Hutev1fqvD/rvToY+IfSngGmvJdp5HS8/D6P5HsmEacqTExWlKqh+w0berRo7bS7bVpia//aAAgBAQABBQLvHHJMo2Qjdt4ChliP1f2j3HabawvZrK4hT96K1QmO/sIv6PbVsE26W8i7i58JxXP6UhuLS83W527Y0XlseRdKlikhk728ccUSlT3k23Lj5m0y/wCsFvZTeGrawjudiVa7bceGlosLjw74n3O4ju9xgkTdoWhUa3bQG5nu5xPK9h8P2tla7v4umu0+GLha978ZpmF9bbvuFtHt97tfijbdz2252m7c/wDGrZw/Q2L8J7Unc9z8Vb2rc739CX427wtyZbrc/DcO7bibnYFbtfWl1sm5bgmPxR4ae3dVw7jpsX4e/iHhPwbtqb7cFQxKRcW15BJaSfpfbty220O47lvNzu0fgC5PM3K3913BCzGvcUCO/u/8We2jneBPDVzHbbPFbzLmvfC15dJt5I/DOzb7vnhneLay2fw7ue3eFtln2zd9+UF7091/2or+k21+BruOWPYNtGyWi1XN6veTJZ7wN33TAAqOw29wjcLKGy2axkkVLJZxc+7uJefPYUkNvaXN3NsmwW9jfQT7bsMEKolxbj4P2/cbqPwFaoni8KbJbz3+5IRPZ7Tbfo/d/Cm47a7b6C27eD9ws7y0Kpor+f8ARm3+E9p3+zvIN53622aCbxFybLd9wuLSI+IrO4m5Qh8RR3X8X3rcU7lfdrK8uNvubDxVt97YDcU7pvsXP/pztFpMdtsdxg3S0iurrw3eeJbPb4keD9/5UfiXxMvdlfcRIuJfPtblmO/Wjw3aqtNkXtG3Lu/FcW4o3W4kiWue7kmT/MR3V1Ezf35ZUpZ+7//aAAgBAxEBPwFjitwwHmQeoxxr7Qyxaj83prJRkjYATmETX5OaP2/b4fOknb9sYD1cuD2yCHNH+1FwEbjD0L4KQycXO2QeomAOQ5OrsbQOHpwDUq8J5LLy4MYmdpRURwyMJRuSIYh4DKQkbepwxhyNAWfUmVW9N9xc4kBb7u2W4OTIZGz2ApPZ/9oACAECEQE/AURYAeockR6BMezH5RIXSZ0WY448alrgRDKG2mY9Q4zzWpYc0XIQyzegcYvl9UuON8PhO0jlqKTbkgB41OUlx8lyXVu+jbKV+fo//9oACAEBAAY/Au/LiSVqPkNX/Gp0RfyfbV+CWiVd6VBYqMU+vzfTdyV/shyWPvgK4/2kkDX4ir5ik5R/tpOSfxH3xcXhKI1eyke2v5eg+LTf7epUOOAliHDqFdTxPEcXNciVMKIRXqrqBx4OG+sp1iSxOCsSU5IDsURpVEiUcwqTJrgniNPU6O83TEptgtSlSEaUr5erXcbFflVxGOqNScKsxygWtwNPRBPxH5T+pmKVOKk+X3PfbkZJ4Ro/bV/cDqeuRb3jaL1XLhXFUH/dYpUPd7uMYooIYx8P9tTjsZP45FfrxkAHsAihoPNxbQoZyXalpzrpFFXpp+sv+Mz+9bbcfRrr+SvA/LyLi5X+LK1y8uUeNfk7m5i9iWRSh8mLO4NFD90s+X8k/D+BlCxipOhHZMNaV4n0A4l1QMY09KB6JHb9N770oAqlCuFPj/carTboxb23yGR/uNEspM85CuXkfzU8/scC51ZLVHrw06j6NUCZSuFYoqNfUkgtOzXOUM8aRjr+z5g+fyarS5Go4HyUPUdk3f8AfIqIk+P7Kv6u0835pSIh8uKv6u2UorDb9avifINUESv4tAaJ+J/aa9zUjCJB4K0VT1A9NWuyUeXNMAYpPNKk+X2hwyz9FtDHSidCpRL/AECiBKLMgx5jzlPnX9Q+LVCTjJCqqVDz9C07ggfxm3BP2p9ofbx7e7K9m4Bj+0+z+uj1doj15i/xVT+rte7gn2150+zQNck8QkihRrlwqr/bL5ciQpNKUPCh8mvdI0JhSiSoxPsnKg0+YcFyVKjEyKkJNPnq74m2JMITy6HFITyz8R5uEXaU5wCmY9oj4u7sVeyoBf8AUXc2w4RyKH62lY4pNXcJHDMuyP8AsNQ/3tXa4QnilMn6jVgWaaqOSpFfyhSv2CoeVx1cuTT0pjxA+bmihmgEcqyoVQcxVWXFwRbioqEXSVISSOL5SzJzU+wsI4H+44EpuhBehFV0P8ILmUqWOZHKpWNVeJHEcQ71Q/01Xaf4Ko4z/pMik/YvUfwHtdbRNwWMh8jopmG565jIopSPQ6D8aONFaRqUoECoFE8aq4n9Qd3FbrVElMhoEkhmP3qQoVoQVVH63ikVJYMsEnLKVZdPlT4u73dBP0gyOXHoGIH4tUq/aWST9rii/aUK/Lzck3+mKKvxclmrhcCg/tjVP9z7WLa2jMkn7IZhvLhaNwEZUBHWiAfOvm457i+N+mWX2tDiaHX1aVwUMatQRwNXJeLlkRJKamlKNC1XJkjSdUFPEfMFx3MESkLjUFCizxDG1W8yY72ZJKcuCfj/AHHeW1xdS3+S+rk8EKHz4n1ZmiHvNv8AtJ4j5hzXZ4n6JHzV7R+wfw91pShMd2n97Tiv+U953hZVBy0BEeSfaAHx+Ls038Qnll+kQngclak19PVpCozZlKfZUKJp8D6OKeRJmExoMSGL02i/IrRUZISrgVfN+8WpTy4k8yWoy6fIADzLs93uYIuUlZiy15iFEcaejuIkSqRDdBFyko1BWn1+bXc3Sfd0JKva/ZHmWuaFAjhB6EgU+35nui7tVYyIclzJ0SQpquLifs9XBc7hRMHMSMfypRXg1ZcOYqvpyqfwUe5TbQlC851cnPUYp/Zfvcf0N1bfvEq8iOIV8C5rpcfNs7uRSFIV8Nf4C7S/2yqIL0FfL9CPOjXYXppFGMkyfsj0J/gfutrVFon8V/P4fdEkailSeBD/AI0jlSftxjQ/NP8AceNtc+8IpSiV609MTQu1hUKKxyI+KjV+/Ktxzv2vX5jg1G3V/F5UpJCiOXX/ACtGJL+4N0tIoEx6JA9K8KfIPlACOIcEJ4f6J+f8zSKZaPkoh0NzJ/hl1Uan4/e//8QAMxABAAMAAgICAgIDAQEAAAILAREAITFBUWFxgZGhscHw0RDh8SAwQFBgcICQoLDA0OD/2gAIAQEAAT8hn/p3hkKv1R5SOj/KB9pS6RiwgScmtM3stzDoXNpj5N+DAX7APv8A/HpvD9EP5P1NAMJF6UofmEbXNYyXYHgVDRlnh2EcCNhiowhy0p9j3TO1CJEA7KI4+7yRyYHiJRH3J5ocJMohuv3B8g5qKucv/wAEaMijo5X93lzzWrr4/wBB0B0dXHOW6APvZCR4pMwPHiQHysn200N9YzBoyP4smSh8wF7Kw2LTAMp1qKkpw82bqOz/AHvj/wCaQ8dQ6c/NC3g7Xy+fXl6mpPQo5E5P+AKHa8GlPgLiw/w99vL7X/kpTqOdE9r1bQv/ALmOPpvumSulpLStclEd1DeKwRgAlB3qtWW3qEJDx9RYmlAtWEDPyX/t7zwfJ4/4LvG9NH8RL2Hn/i6FB/xdD7/4YjcB4k2+Xfqx9HEcHiv69XjGB0lGznDaoNweSbrwyN91CMFieiOXm+UWYYB8mORfKrFOzocn8/8AlNGMQ5/ixj6szWMkPPyL6NIjAhObm+qfMH9f8ji85fH9StSQzCeMZ2xS9OUcfkOuKnNolkwJTlANfcuODE8+G44aydE7JBnJ4rDcGSfaw+byIKj5H9wlDiCfgx+qgcCH0zcww58LN0Hj8w/3f85JzP8Ag6s/asYo9nQByu53WHs3IhCJ2Trv4rPCLQEI+2PiyACDKUk+Oe6rNld3xMpK7LyYGgSPObxwlAjEC6QVOP8AQ/DFdEsIf/gIqg+WPgP3f8GO1H5CL+LxK5BSP1EQ7fqq40REnBGnmwfhBQd6oFmJMw9JKnVcYCV+Cn8FKRGk4jqqQ8LAdR8j93ST5CUt8Z/ADV9Flf8A2SakoJc8CS/bRqNYg0jz4+6SET4HEyIjwwfNgEV5u4omB466qxg9Sak+bu+wdIjBKb7jFeqBFYiY4dDla8Y5KlEyjuJhViE2d5hdhrI34ovZEeX5/skvURvwn9D8j/miIwlRGExBJx7z34bwl2NPcR7HVjXqWyNgaAg8uKH2jiOrxekxWQhPiBKzxTYceBsN0fldUaVlLGBp2sQVBBR3Y8EOeXnKBsfk44gOb4ias/SdUbPBJsV2jAjC6g+V/wCyw5j0nYnY3SN/GO/E/ruk8jqfxiPPm48ux/N6/VUKxQY+GDks51U0ZExvEXcXP9l7YowiB1yel52sTIjhEIdOY/jLrU6eA/G/8eKjdDvFO/4D8/8A4dozIhK62TrSfWfcPi6e3CvexfUJXwzlciNWVa4nXDjsfZeDqUo4yc+T5o4wZ4cSgPRvmi0POOfl79iX/wDJFg3j+IaLIn+PdmG8yl/f/wCL/9oADAMBAAIRAxEAABDxbJJzUxVknvj4gmiQqSBfEzZ3KqlGuw1+t3dZaminBwh9byij/8QAMxEBAQEAAwABAgUFAQEAAQEJAQARITEQQVFhIHHwkYGhsdHB4fEwQFBgcICQoLDA0OD/2gAIAQMRAT8QmC/TmxukzTn6dxQ9/wCf0kAfr/P9ZM4fOJqHBPz3rMe/3jc29b+bzx871beP0fb8z535sg8m7+T9Lpz2efEh/N83/UHPvr/uAADl535Mkk/R/iPn+LJS7n8RftGP2yLuhv1yxOkzG1TD/Donu/VlqYmmQVgM11/PP63FBIVejn9bbpydfwljv38WyDpBj4f1hqZnb+/EbfY/H98/vG3j+18i/wACHUz3+D//2gAIAQIRAT8QnRbMsYSnOfTjmK8IQH5bBlnXV3I7PPohfUOY2jmwAO4Fnpjhkx8BwfTIhybaGHECMZkuxcwMTADj42ejpB7hAt7udXg5yRIPxHQ/N/eAC7I4OR7+ANr+D//aAAgBAQABPxCDcNbt5SeCTzAWPd7XeSHyDPTvVaGbOCIKuGuQEYkfYRTs5asiRCkBMgTYbZIFdeJdHqD6uNjxTmzfdfFBuzDQneCXEY8XIN0QmiGGC6aCUBU1jGMiiCkETGshw0zDxyD3LFSSE/TACNkJJHYOb7STcnNApkCKCJRygls63Us34MTa5Cv/AOhl5HuTnZ4NLk6OaSSPhE0SRNFLxnm7Y5sELmkOqYeOZyB7BMyDgl4BgGBACACgHRL8YRgwmNgFVa2fLLk5mntmwe/MUwbIGVD12ilOSPBaUBQSg7YtZ6W52LSEEBTK/T7RDNHhR8uojUsAOAmlqjqGx7oHHn4k47j4nmEhihGO2F4Q8jn/AAj7nlCesc/UVU4P6ov3P2zu5G8WFu6LL3n8+T5RcEc5GuIyKCcggIIVPGqDIVWAIBKgzUeuSUjYvkCQ0Nehe8PJqQ7vpaHhmpKnReUQyElmN2IGEM/ZrU9PCcjI8XI4ru7h7dCeVR+0O1JWEPK8MnPr4Lvqi7CV1npSI7Ed1ci8odfKS548OWo5BLPCsm4Q8+LPQy8qQjSE2vHMWXhhsYgAoQeQsDy2FWEcByGR2gBQ6s3axILI+ByeZXdEZcOA/hD5+VAJOLrWN8EP2En5q6YoDyJyWGE+ZUSVspTeTv8A2B7bH+rbUGrEmB4d8UtKlQQ4yJQAiMPFghkNnaQiAzQnhohdxPSARIIQMUbCqX+EY4JGmOsJ7+RsxiVInANXy1TfM+MBHiQ+KDEBvhn9VmyBvCQ/igfCU4Fn9NDyh+Qn8LzS4mUczL/tU2FjIKjo6o0AFOPOcFSW55OMjnFTbiUc7VGE4eFAf7L2TElASAnJok1Qj5gByfJDdN50R44jmSzaztknBEkiE6R4WuSJRPmfspYDUgs0yVV8kv2Vgk+k/pj8j/hKlS+B30uPlqfiwEaYqEkWEwGiWKJtOPiFKUmgZSaPxOKOADACavFIy6FII+672IeQ9BKvxQEwuOyhBIjJ3g2xUHZ2wPtI5mkXm35c35bLfHJ4VI9Cr8VCe/SOP02UglIFSOoVPQq/G0msofEjyoDtqMonmOyAjkOsNHnYJc7Y0sqVbIGRkD60WdxiJWfNFSI0kDQph5o5YtMuZ5LyFQI4wIJAieTsomxc8XkkF2JucvtZy6VJERCQHKqeMimXohIzn2EcXXPbtyXqVUQmeKKGQIjCJwjZSlZ3Wjz4PHSSWB9s1aIgoWFjtctChlKKMIDiOXAUoTzCIU8ap5tYQjJkaGeb2WNz0NmQMHAhQGmUcYLEjELACLYYCwbDdk45KJQjYMq+5pB6U4UCbTapXG4NLItNJhJynoBMkyGEm/PB1/ziuAmuR3phYj/MNZ5gGlDCMasHy482KdIADIIQNy+yre5Qh5nt4ceEXx4HxmBDMbEgnihZmvK2oeOWjCQhV2g+12n1AwAE8EgXo6ASwZI0EZSi5fml7/pe3vPIs4YLrjRdB379QHFgeq05regkz/Im/wC7JjDfcB1V7X5mx2AzsLhj4XwJqKyCIkAciCCNRB6UEXICKRijh4vYTIdJ1DKUcrES+rprS8J4DtiF4BIYTr/ChBl9v/ILF6mise7FgmGwUHgMfQFcL+IxtsF7lDfKlvD/AM7+asMUv//Z" x="524" y="227" width="38" height="38" preserveAspectRatio="xMidYMid slice" clip-path="url(#logo-clip-madhouse)"/>
|
|
345
|
+
<circle cx="543" cy="246" r="19" fill="none" stroke="var(--border-color)" stroke-width="1.5"/>
|
|
325
346
|
</g>
|
|
326
|
-
<text class="ui-text comp-part target-item" x="574" y="
|
|
347
|
+
<text class="ui-text comp-part target-item" x="574" y="251" font-size="15" font-weight="600" fill="var(--text-color)">Madhouse Records</text>
|
|
327
348
|
|
|
328
|
-
<!-- Item
|
|
329
|
-
<rect class="comp-part target-active" x="516" y="
|
|
349
|
+
<!-- Item 3 (Active/Highlighted): "We Play House Recordings": ::part(suggestion-item-active) -->
|
|
350
|
+
<rect class="comp-part target-active" x="516" y="284" width="334" height="64" rx="8" fill="var(--active-item-bg)"/>
|
|
330
351
|
<g class="comp-part target-active">
|
|
331
|
-
<image href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAASABIAAD/4QCARXhpZgAATU0AKgAAAAgABAEaAAUAAAABAAAAPgEbAAUAAAABAAAARgEoAAMAAAABAAIAAIdpAAQAAAABAAAATgAAAAAAAABIAAAAAQAAAEgAAAABAAOgAQADAAAAAQABAACgAgAEAAAAAQAAAGSgAwAEAAAAAQAAAGQAAAAA/+0AOFBob3Rvc2hvcCAzLjAAOEJJTQQEAAAAAAAAOEJJTQQlAAAAAAAQ1B2M2Y8AsgTpgAmY7PhCfv/AABEIAGQAZAMBIgACEQEDEQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMDAgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAfAQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2wBDAAICAgICAgMCAgMFAwMDBQYFBQUFBggGBgYGBggKCAgICAgICgoKCgoKCgoMDAwMDAwODg4ODg8PDw8PDw8PDw//2wBDAQICAgQEBAcEBAcQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/3QAEAAf/2gAMAwEAAhEDEQA/AP38ooooAKKKKACiiigAooooAKKKKACiiigAooooA//Q/fyiiigAooooAKKKKACiiigAooooAKKKKACiiigD/9H9/Ko6nqEGk6bd6rcrI8NnDJM6xRtLIVjUsQkaAs7EDhVBJPAGavUUAfm4f+Csf7FIOD4qvwR/1Cbz/wCN0n/D2T9ij/oar/8A8FN5/wDG6/Gf/gqV+yv/AMKH+Nz/ABB8LWnk+DPiFJLeQCNcR2mo53XVvxwqsW82McDDMqjEZrwHVv2MfibpP7JWm/tYzxn+yL7UGhey8s+bFprkRQX7HtHJOGjxjoY3GVbgA/oct/8Agq5+xfd3EVra+JtRmmmZURE0e9ZmZjgKoEeSSeABX3h448Vf8If4D1/xslsbr+xNNutREDExGT7NC02wkglN23GSpx6dq/mo/wCCSv7K/wDwtj4sSfHHxbZ+Z4W+H8yNZrIuUutZIDxAZ6i2UiZvRzF1BNf0YfHb/kiHxD/7F3Vv/SSWgD5h/Zc/4KH/AAD/AGm0tdDtb7/hEvGcoAbRNTkVXlfuLSfhLgegG2TAyYwOa+86/gi8LeGvE/i/xBZeHPBum3Wr61eyBLa1sonmuJJOoCJGCxI68dOtf1ufsB/Dv9r74f8Aw9az/af8TxanbvFGNL0yc/a9UsVHUXF8rYYY4EZMpXj94uNlAD/jN/wUK+Ff7Pn7REfwO+LGn3Ol6bdadaXsWuwk3EMb3LyKUuLdV8xEXYPnTzDk8qAM19dS/F34Ww+Af+FqS+LdLXwd5XnDV/tcX2Ip6ibdtJzxgHOeMZ4r+Zz/AILFf8nep/2Lum/+jJ6+EZfg58eY/hInxGl8La2vw7NwZFvTBN/Z/mlQvn4+6FI+TzsbSfl3Z4oA/qW+B/8AwUJ+F/7Rf7Qt18E/hTpl1f6VY6XdX767cH7PHNJbyxIEgtmXzGjYSE75DGcjGwg5r7/r+WP/AII2/wDJ297/ANixqP8A6Pta/qcoAKKKKAP/0v38ooqOUKYnDJ5gKnKcHcMdOeOfegDxj4//AAB+Hv7Snw5uPhl8SreWXS5riC6SW3YR3EE1u+5XidlYKSpaNjjlHYd812+rfDzwZrXw/ufhZf6VC3hW6046S1gq7YRZGLyREoH3QqcLjkYBHIr5G+F3wn+JHhf4cav4d8Q+HW+16r4FsNKhgtpLOOCO8s7WaKS3uU89hJdPNKSLpXMTxbVIiMZMvUy/DvxvB4Bk0fSvD1wb2Ofw7dXyTNp1u2p2VjNE11pkbW0mx8Ik3Nx5aSeaImdkZ2UA9p+BvwV8Efs9/DHRvhT8PopE0jR0bEs5Vri4lkYvJNM6qoaR2JJIUADAACgAd14t8OWXjLwprPhHUZJIrTXLK4sZniIEix3MbRMULAjcAxIyCM9jXhPiHwRd6ifD974e8HnT9AtvEI1LWdHJto31GM2E1qspgSQwMIZzbTeW7gt5RcLvVA/IeIPhj401HRvEUGjaEtvpupeMPDupaZpcn2d0s7SxuLJr+5aIzJGiS+TNIYI33MCWIEkrqADuf2e/2Uvgj+zHoX9k/CzQEtryZAl1qlzifUbvH/PWcgHbnny0Cxg8hBX0bXyDpXw+8ZWvhv4X6VrvhibUbjwt4n1G81VfNs5IDDc2Wpp59qjzLts/tF1ELe3I82GIIhT93uNo/DrxriInRT/Za+PLTV9O07zbdjpWkxWsUcxOZPLAe6We4EcTOVWYKBkFVALXjX9jP4EfEr44x/Hz4i6M3iXXLaytrK2s75lk02EWzOyy/Z9oEjnfg+aXQYBCg819RNaWj2psHhRrZk8sxFRsMeNu3b0244xjGK+V9X+FviMeNNR8T+HNFVdN1rxFpkmraZdPD5Fzb2jWjJqtsqu6x3ELxMJAwRpos7gXSLOhY+DvGGm6lqc2p+Godf1yfxauoW2q3BiZI9JluE2NG/mpLE9laExCILiRkOAyys1AFLwD+xj8CPhX8cLn48/DXSG8N6zfWFxYXNjZMqabILiSORpVt9p8px5YAETImCTszzX1bXzV4D8EeKdA+LWoa+unOujag2smVtQS1e5tZLi7jlT7JeW7+ZJbXW0yeRcIzw4VQ8aqsR+laACiiigD/9P9/KKKKACiiigAooooAKKKKACiiigAooooAKKKKAP/1P38ooooAKKKKACiiigAooooAKKKKACiiigAooooA//V/fyiiigAooooAKKKKACiiigAooooAKKKKACiiigD/9k=" x="524" y="
|
|
332
|
-
<circle cx="543" cy="
|
|
352
|
+
<image href="data:image/jpeg;base64,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bEs5Vri4lkYvJNM6qoaR2JJIUADAACgAd14t8OWXjLwprPhHUZJIrTXLK4sZniIEix3MbRMULAjcAxIyCM9jXhPiHwRd6ifD974e8HnT9AtvEI1LWdHJto31GM2E1qspgSQwMIZzbTeW7gt5RcLvVA/IeIPhj401HRvEUGjaEtvpupeMPDupaZpcn2d0s7SxuLJr+5aIzJGiS+TNIYI33MCWIEkrqADuf2e/2Uvgj+zHoX9k/CzQEtryZAl1qlzifUbvH/PWcgHbnny0Cxg8hBX0bXyDpXw+8ZWvhv4X6VrvhibUbjwt4n1G81VfNs5IDDc2Wpp59qjzLts/tF1ELe3I82GIIhT93uNo/DrxriInRT/Za+PLTV9O07zbdjpWkxWsUcxOZPLAe6We4EcTOVWYKBkFVALXjX9jP4EfEr44x/Hz4i6M3iXXLaytrK2s75lk02EWzOyy/Z9oEjnfg+aXQYBCg819RNaWj2psHhRrZk8sxFRsMeNu3b0244xjGK+V9X+FviMeNNR8T+HNFVdN1rxFpkmraZdPD5Fzb2jWjJqtsqu6x3ELxMJAwRpos7gXSLOhY+DvGGm6lqc2p+Godf1yfxauoW2q3BiZI9JluE2NG/mpLE9laExCILiRkOAyys1AFLwD+xj8CPhX8cLn48/DXSG8N6zfWFxYXNjZMqabILiSORpVt9p8px5YAETImCTszzX1bXzV4D8EeKdA+LWoa+unOujag2smVtQS1e5tZLi7jlT7JeW7+ZJbXW0yeRcIzw4VQ8aqsR+laACiiigD/9P9/KKKKACiiigAooooAKKKKACiiigAooooAKKKKAP/1P38ooooAKKKKACiiigAooooAKKKKACiiigAooooA//V/fyiiigAooooAKKKKACiiigAooooAKKKKACiiigD/9k=" x="524" y="297" width="38" height="38" preserveAspectRatio="xMidYMid slice" clip-path="url(#logo-clip-wph)"/>
|
|
353
|
+
<circle cx="543" cy="316" r="19" fill="none" stroke="var(--border-color)" stroke-width="1.5"/>
|
|
333
354
|
</g>
|
|
334
355
|
<g class="comp-part target-val target-active">
|
|
335
|
-
<text class="ui-text" x="574" y="
|
|
356
|
+
<text class="ui-text" x="574" y="321" font-size="15" font-weight="600" fill="var(--text-color)">We Play House Recordings</text>
|
|
336
357
|
</g>
|
|
337
358
|
</g>
|
|
338
359
|
|
|
@@ -343,7 +364,7 @@
|
|
|
343
364
|
|
|
344
365
|
<!-- 1. Host Target -->
|
|
345
366
|
<path class="guide-line target-host" d="M200 49 L395 49" stroke="var(--c-host)"/>
|
|
346
|
-
<rect class="guide-box target-host" x="398" y="38" width="544" height="
|
|
367
|
+
<rect class="guide-box target-host" x="398" y="38" width="544" height="330" rx="16" stroke="var(--c-host)"/>
|
|
347
368
|
<circle class="guide-dot target-host" cx="395" cy="49" r="4" fill="var(--c-host)"/>
|
|
348
369
|
|
|
349
370
|
<!-- 2. Control Target -->
|
|
@@ -361,10 +382,10 @@
|
|
|
361
382
|
<rect class="guide-box target-input" x="454" y="58" width="395" height="36" rx="6" stroke="var(--c-input)"/>
|
|
362
383
|
<circle class="guide-dot target-input" cx="454" cy="100" r="4" fill="var(--c-input)"/>
|
|
363
384
|
|
|
364
|
-
<!-- 5. Highlight Label Target (around "
|
|
365
|
-
<path class="guide-line target-hl-val" d="M240 263
|
|
366
|
-
<rect class="guide-box target-hl-val" x="504" y="58" width="
|
|
367
|
-
<circle class="guide-dot target-hl-val" cx="
|
|
385
|
+
<!-- 5. Highlight Label Target (around "house") -->
|
|
386
|
+
<path class="guide-line target-hl-val" d="M240 263 L534 263 L534 93" stroke="var(--c-hl-val)"/>
|
|
387
|
+
<rect class="guide-box target-hl-val" x="504" y="58" width="60" height="34" rx="7" stroke="var(--c-hl-val)"/>
|
|
388
|
+
<circle class="guide-dot target-hl-val" cx="534" cy="93" r="4" fill="var(--c-hl-val)"/>
|
|
368
389
|
|
|
369
390
|
<!-- 6. Suggestions Header Target -->
|
|
370
391
|
<path class="guide-line target-header" d="M310 331 L480 331 L480 116 L506 116" stroke="var(--c-header)"/>
|
|
@@ -372,39 +393,44 @@
|
|
|
372
393
|
<circle class="guide-dot target-header" cx="506" cy="116" r="4" fill="var(--c-header)"/>
|
|
373
394
|
|
|
374
395
|
<!-- 7. Suggestion Image Target -->
|
|
375
|
-
<path class="guide-line target-image" d="M300 395 L495 395 L495
|
|
376
|
-
<circle class="guide-box target-image" cx="543" cy="
|
|
377
|
-
<circle class="guide-dot target-image" cx="520" cy="
|
|
396
|
+
<path class="guide-line target-image" d="M300 395 L495 395 L495 246 L520 246" stroke="var(--c-image)"/>
|
|
397
|
+
<circle class="guide-box target-image" cx="543" cy="246" r="23" stroke="var(--c-image)"/>
|
|
398
|
+
<circle class="guide-dot target-image" cx="520" cy="246" r="4" fill="var(--c-image)"/>
|
|
378
399
|
|
|
379
400
|
<!-- 8. Clear Button Target -->
|
|
380
|
-
<path class="guide-line target-clear" d="M1005
|
|
401
|
+
<path class="guide-line target-clear" d="M1005 63 L940 63 L922 76" stroke="var(--c-clear)"/>
|
|
381
402
|
<circle class="guide-box target-clear" cx="902" cy="76" r="20" stroke="var(--c-clear)"/>
|
|
382
|
-
<circle class="guide-dot target-clear" cx="
|
|
403
|
+
<circle class="guide-dot target-clear" cx="922" cy="76" r="4" fill="var(--c-clear)"/>
|
|
383
404
|
|
|
384
405
|
<!-- 9. Popover Target -->
|
|
385
|
-
<path class="guide-line target-popover" d="M1005
|
|
386
|
-
<rect class="guide-box target-popover" x="504" y="90" width="358" height="
|
|
387
|
-
<circle class="guide-dot target-popover" cx="862" cy="
|
|
406
|
+
<path class="guide-line target-popover" d="M1005 119 L862 119" stroke="var(--c-popover)"/>
|
|
407
|
+
<rect class="guide-box target-popover" x="504" y="90" width="358" height="272" rx="14" stroke="var(--c-popover)"/>
|
|
408
|
+
<circle class="guide-dot target-popover" cx="862" cy="119" r="4" fill="var(--c-popover)"/>
|
|
388
409
|
|
|
389
410
|
<!-- 10. Suggestions List Target -->
|
|
390
|
-
<path class="guide-line target-list" d="M1005
|
|
391
|
-
<rect class="guide-box target-list" x="512" y="
|
|
392
|
-
<circle class="guide-dot target-list" cx="854" cy="
|
|
411
|
+
<path class="guide-line target-list" d="M1005 175 L875 175 L875 148 L854 148" stroke="var(--c-list)"/>
|
|
412
|
+
<rect class="guide-box target-list" x="512" y="140" width="342" height="212" rx="8" stroke="var(--c-list)"/>
|
|
413
|
+
<circle class="guide-dot target-list" cx="854" cy="148" r="4" fill="var(--c-list)"/>
|
|
393
414
|
|
|
394
|
-
<!-- 11. Suggestion Item Target (Item 1:
|
|
395
|
-
<path class="guide-line target-
|
|
396
|
-
<rect class="guide-box target-
|
|
397
|
-
<circle class="guide-dot target-
|
|
415
|
+
<!-- 11. Suggestion Item Selected Target (Item 1: House) -->
|
|
416
|
+
<path class="guide-line target-selected" d="M1005 231 L895 231 L895 176 L852 176" stroke="var(--c-selected)"/>
|
|
417
|
+
<rect class="guide-box target-selected" x="514" y="142" width="338" height="68" rx="10" stroke="var(--c-selected)"/>
|
|
418
|
+
<circle class="guide-dot target-selected" cx="852" cy="176" r="4" fill="var(--c-selected)"/>
|
|
398
419
|
|
|
399
|
-
<!-- 12. Suggestion Item
|
|
400
|
-
<path class="guide-line target-
|
|
401
|
-
<rect class="guide-box target-
|
|
402
|
-
<circle class="guide-dot target-
|
|
420
|
+
<!-- 12. Suggestion Item Target (Item 2: Madhouse Records) -->
|
|
421
|
+
<path class="guide-line target-item" d="M1005 287 L910 287 L910 246 L852 246" stroke="var(--c-item)"/>
|
|
422
|
+
<rect class="guide-box target-item" x="514" y="212" width="338" height="68" rx="10" stroke="var(--c-item)"/>
|
|
423
|
+
<circle class="guide-dot target-item" cx="852" cy="246" r="4" fill="var(--c-item)"/>
|
|
403
424
|
|
|
404
|
-
<!-- 13. Suggestion
|
|
405
|
-
<path class="guide-line target-
|
|
406
|
-
<rect class="guide-box target-
|
|
407
|
-
<circle class="guide-dot target-
|
|
425
|
+
<!-- 13. Suggestion Item Active Target (Item 3: We Play House Recordings) -->
|
|
426
|
+
<path class="guide-line target-active" d="M1005 343 L925 343 L925 316 L852 316" stroke="var(--c-active)"/>
|
|
427
|
+
<rect class="guide-box target-active" x="514" y="282" width="338" height="68" rx="10" stroke="var(--c-active)"/>
|
|
428
|
+
<circle class="guide-dot target-active" cx="852" cy="316" r="4" fill="var(--c-active)"/>
|
|
429
|
+
|
|
430
|
+
<!-- 14. Suggestion Value Target ("We Play House Recordings" text) -->
|
|
431
|
+
<path class="guide-line target-val" d="M1005 399 L940 399 L940 316 L770 316" stroke="var(--c-val-text)"/>
|
|
432
|
+
<rect class="guide-box target-val" x="570" y="305" width="204" height="24" rx="6" stroke="var(--c-val-text)"/>
|
|
433
|
+
<circle class="guide-dot target-val" cx="770" cy="316" r="4" fill="var(--c-val-text)"/>
|
|
408
434
|
|
|
409
435
|
|
|
410
436
|
<!-- ===================================================================== -->
|
|
@@ -450,32 +476,37 @@
|
|
|
450
476
|
<!-- CODE LABELS (RIGHT SIDE) -->
|
|
451
477
|
<!-- ===================================================================== -->
|
|
452
478
|
<g class="code-label lbl-clear">
|
|
453
|
-
<rect class="label-hitbox" x="1005" y="
|
|
454
|
-
<text class="label-text" x="1015" y="
|
|
479
|
+
<rect class="label-hitbox" x="1005" y="48" width="225" height="30" rx="6"/>
|
|
480
|
+
<text class="label-text" x="1015" y="68" fill="var(--c-clear)">::part(clear-button)</text>
|
|
455
481
|
</g>
|
|
456
482
|
|
|
457
483
|
<g class="code-label lbl-popover">
|
|
458
|
-
<rect class="label-hitbox" x="1005" y="
|
|
459
|
-
<text class="label-text" x="1015" y="
|
|
484
|
+
<rect class="label-hitbox" x="1005" y="104" width="185" height="30" rx="6"/>
|
|
485
|
+
<text class="label-text" x="1015" y="124" fill="var(--c-popover)">::part(popover)</text>
|
|
460
486
|
</g>
|
|
461
487
|
|
|
462
488
|
<g class="code-label lbl-list">
|
|
463
|
-
<rect class="label-hitbox" x="1005" y="
|
|
464
|
-
<text class="label-text" x="1015" y="
|
|
489
|
+
<rect class="label-hitbox" x="1005" y="160" width="260" height="30" rx="6"/>
|
|
490
|
+
<text class="label-text" x="1015" y="180" fill="var(--c-list)">::part(suggestions-list)</text>
|
|
491
|
+
</g>
|
|
492
|
+
|
|
493
|
+
<g class="code-label lbl-selected">
|
|
494
|
+
<rect class="label-hitbox" x="1005" y="216" width="335" height="30" rx="6"/>
|
|
495
|
+
<text class="label-text" x="1015" y="236" fill="var(--c-selected)">::part(suggestion-item-selected)</text>
|
|
465
496
|
</g>
|
|
466
497
|
|
|
467
498
|
<g class="code-label lbl-item">
|
|
468
|
-
<rect class="label-hitbox" x="1005" y="
|
|
469
|
-
<text class="label-text" x="1015" y="
|
|
499
|
+
<rect class="label-hitbox" x="1005" y="272" width="265" height="30" rx="6"/>
|
|
500
|
+
<text class="label-text" x="1015" y="292" fill="var(--c-item)">::part(suggestion-item)</text>
|
|
470
501
|
</g>
|
|
471
502
|
|
|
472
503
|
<g class="code-label lbl-active">
|
|
473
|
-
<rect class="label-hitbox" x="1005" y="
|
|
474
|
-
<text class="label-text" x="1015" y="
|
|
504
|
+
<rect class="label-hitbox" x="1005" y="328" width="320" height="30" rx="6"/>
|
|
505
|
+
<text class="label-text" x="1015" y="348" fill="var(--c-active)">::part(suggestion-item-active)</text>
|
|
475
506
|
</g>
|
|
476
507
|
|
|
477
508
|
<g class="code-label lbl-val">
|
|
478
|
-
<rect class="label-hitbox" x="1005" y="
|
|
479
|
-
<text class="label-text" x="1015" y="
|
|
509
|
+
<rect class="label-hitbox" x="1005" y="384" width="270" height="30" rx="6"/>
|
|
510
|
+
<text class="label-text" x="1015" y="404" fill="var(--c-val-text)">::part(suggestion-value)</text>
|
|
480
511
|
</g>
|
|
481
512
|
</svg>
|
package/components/rich-input.js
CHANGED
|
@@ -8,6 +8,8 @@ import { highlightManager, isOpaqueRangeSupported, isHighlightSupported } from '
|
|
|
8
8
|
import { getCaretCoordinates, positionPopover } from '../utils/positioning.js';
|
|
9
9
|
import { setupContentEditableAdapter, isContentEditableFallbackActive } from '../utils/contenteditable-adapter.js';
|
|
10
10
|
|
|
11
|
+
const KEYWORD_SUGGESTION_DELAY = 300;
|
|
12
|
+
|
|
11
13
|
const TEMPLATE = document.createElement('template');
|
|
12
14
|
TEMPLATE.innerHTML = `
|
|
13
15
|
<style>
|
|
@@ -224,6 +226,10 @@ TEMPLATE.innerHTML = `
|
|
|
224
226
|
color: var(--ri-item-title-color, var(--rs-item-title-color, #0f172a));
|
|
225
227
|
}
|
|
226
228
|
|
|
229
|
+
.suggestion-item.selected {
|
|
230
|
+
background-color: var(--ri-item-selected-bg, rgba(37, 99, 235, 0.06));
|
|
231
|
+
}
|
|
232
|
+
|
|
227
233
|
.suggestion-item:hover,
|
|
228
234
|
.suggestion-item.active {
|
|
229
235
|
background-color: var(--ri-item-active-bg, var(--rs-item-active-bg, #f1f5f9));
|
|
@@ -409,6 +415,7 @@ export class RichInput extends HTMLElement {
|
|
|
409
415
|
this._activeSuggestions = [];
|
|
410
416
|
this._selectedIndex = -1;
|
|
411
417
|
this._context = null;
|
|
418
|
+
this._suggestionTimeout = null;
|
|
412
419
|
this._ownedRanges = [];
|
|
413
420
|
this._invalidRanges = [];
|
|
414
421
|
this._activeKeywordHighlightMap = new Map();
|
|
@@ -949,8 +956,9 @@ export class RichInput extends HTMLElement {
|
|
|
949
956
|
}
|
|
950
957
|
}
|
|
951
958
|
|
|
952
|
-
// Enter when popover closed triggers search/change
|
|
959
|
+
// Enter when popover closed (or no suggestion selected) triggers search/change
|
|
953
960
|
if (e.key === 'Enter') {
|
|
961
|
+
this.hideSuggestions();
|
|
954
962
|
this.dispatchEvent(new CustomEvent('search', {
|
|
955
963
|
bubbles: true,
|
|
956
964
|
composed: true,
|
|
@@ -971,15 +979,16 @@ export class RichInput extends HTMLElement {
|
|
|
971
979
|
this._isFocused = true;
|
|
972
980
|
this._lastCaretPosition = this._input.selectionStart;
|
|
973
981
|
this.updateHighlights();
|
|
974
|
-
|
|
975
|
-
if (this._input.value.length > 0) {
|
|
976
|
-
this.updateSuggestions('focus');
|
|
977
|
-
}
|
|
982
|
+
this.updateSuggestions('focus');
|
|
978
983
|
}
|
|
979
984
|
|
|
980
985
|
_onBlur() {
|
|
981
986
|
this._isFocused = false;
|
|
982
987
|
this._lastCaretPosition = -1;
|
|
988
|
+
if (this._suggestionTimeout) {
|
|
989
|
+
clearTimeout(this._suggestionTimeout);
|
|
990
|
+
this._suggestionTimeout = null;
|
|
991
|
+
}
|
|
983
992
|
this.updateHighlights();
|
|
984
993
|
// Delay closing so click events on popover items can fire
|
|
985
994
|
setTimeout(() => {
|
|
@@ -1012,7 +1021,7 @@ export class RichInput extends HTMLElement {
|
|
|
1012
1021
|
_onClearClick() {
|
|
1013
1022
|
this.value = '';
|
|
1014
1023
|
this._input.focus();
|
|
1015
|
-
this.
|
|
1024
|
+
this.updateSuggestions('clear');
|
|
1016
1025
|
this.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
|
|
1017
1026
|
this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));
|
|
1018
1027
|
}
|
|
@@ -1087,6 +1096,11 @@ export class RichInput extends HTMLElement {
|
|
|
1087
1096
|
}
|
|
1088
1097
|
|
|
1089
1098
|
updateSuggestions(trigger = 'input') {
|
|
1099
|
+
if (this._suggestionTimeout) {
|
|
1100
|
+
clearTimeout(this._suggestionTimeout);
|
|
1101
|
+
this._suggestionTimeout = null;
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1090
1104
|
const caretPos = this._input.selectionStart;
|
|
1091
1105
|
const context = getCaretContext(this._input.value, caretPos, this._configuredKeywords);
|
|
1092
1106
|
|
|
@@ -1106,8 +1120,60 @@ export class RichInput extends HTMLElement {
|
|
|
1106
1120
|
return;
|
|
1107
1121
|
}
|
|
1108
1122
|
|
|
1123
|
+
// Value suggestions always show immediately.
|
|
1124
|
+
// Keyword suggestions show immediately when:
|
|
1125
|
+
// - focusing/clearing an empty field
|
|
1126
|
+
// - typing characters that match a keyword (Boolean(context.query))
|
|
1127
|
+
// - explicitly triggered via the Down Arrow key
|
|
1128
|
+
// In other cases (at the start of a new token after a space when the field is not empty),
|
|
1129
|
+
// show after a small delay to prevent constant popups when typing regular sentences with spaces.
|
|
1130
|
+
const isEmptyField = this._input.value.length === 0;
|
|
1131
|
+
const shouldShowImmediately =
|
|
1132
|
+
context.mode === 'value' ||
|
|
1133
|
+
isEmptyField ||
|
|
1134
|
+
Boolean(context.query) ||
|
|
1135
|
+
trigger === 'arrow';
|
|
1136
|
+
|
|
1137
|
+
if (shouldShowImmediately) {
|
|
1138
|
+
this._showSuggestions(suggestions, context, trigger);
|
|
1139
|
+
} else {
|
|
1140
|
+
if (this._isPopoverOpen()) {
|
|
1141
|
+
this.hideSuggestions();
|
|
1142
|
+
}
|
|
1143
|
+
this._suggestionTimeout = setTimeout(() => {
|
|
1144
|
+
this._suggestionTimeout = null;
|
|
1145
|
+
const isFocused =
|
|
1146
|
+
this._isFocused ||
|
|
1147
|
+
this.shadowRoot?.activeElement === this._input ||
|
|
1148
|
+
document.activeElement === this ||
|
|
1149
|
+
document.activeElement === this._input ||
|
|
1150
|
+
Boolean(this.matches?.(':focus-within'));
|
|
1151
|
+
if (!isFocused) return;
|
|
1152
|
+
|
|
1153
|
+
const currentCaretPos = this._input.selectionStart;
|
|
1154
|
+
const currentContext = getCaretContext(this._input.value, currentCaretPos, this._configuredKeywords);
|
|
1155
|
+
this._context = currentContext;
|
|
1156
|
+
const currentSuggestions = getSuggestions(currentContext, this._configuredKeywords);
|
|
1157
|
+
if (currentSuggestions.length === 0) {
|
|
1158
|
+
this.hideSuggestions();
|
|
1159
|
+
return;
|
|
1160
|
+
}
|
|
1161
|
+
this._showSuggestions(currentSuggestions, currentContext, trigger);
|
|
1162
|
+
}, KEYWORD_SUGGESTION_DELAY);
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
_showSuggestions(suggestions, context, trigger) {
|
|
1109
1167
|
this._activeSuggestions = suggestions;
|
|
1110
|
-
|
|
1168
|
+
|
|
1169
|
+
// Pre-select first item for quick Enter/Tab when filtering or in value mode or triggered via Down Arrow,
|
|
1170
|
+
// but leave unselected (-1) when showing full keyword list at the start of a new token so Enter/Tab aren't hijacked.
|
|
1171
|
+
const shouldPreselect =
|
|
1172
|
+
context.mode === 'value' ||
|
|
1173
|
+
Boolean(context.query) ||
|
|
1174
|
+
trigger === 'arrow';
|
|
1175
|
+
const existingSelectedIdx = suggestions.findIndex((s) => this._isSuggestionSelected(s));
|
|
1176
|
+
this._selectedIndex = existingSelectedIdx !== -1 ? existingSelectedIdx : (shouldPreselect ? 0 : -1); // Highlight matching item or first item for quick Enter/Tab
|
|
1111
1177
|
this._renderSuggestions();
|
|
1112
1178
|
|
|
1113
1179
|
// Show popover
|
|
@@ -1126,6 +1192,10 @@ export class RichInput extends HTMLElement {
|
|
|
1126
1192
|
}
|
|
1127
1193
|
|
|
1128
1194
|
hideSuggestions() {
|
|
1195
|
+
if (this._suggestionTimeout) {
|
|
1196
|
+
clearTimeout(this._suggestionTimeout);
|
|
1197
|
+
this._suggestionTimeout = null;
|
|
1198
|
+
}
|
|
1129
1199
|
if (this._isPopoverOpen()) {
|
|
1130
1200
|
try {
|
|
1131
1201
|
this._popover.hidePopover();
|
|
@@ -1137,6 +1207,28 @@ export class RichInput extends HTMLElement {
|
|
|
1137
1207
|
this._selectedIndex = -1;
|
|
1138
1208
|
}
|
|
1139
1209
|
|
|
1210
|
+
_isSuggestionSelected(sug) {
|
|
1211
|
+
if (!this._context || !sug) return false;
|
|
1212
|
+
|
|
1213
|
+
if (sug.type === 'value' && this._context.mode === 'value' && this._context.token) {
|
|
1214
|
+
const currentVal = (this._context.token.innerValue ?? '').trim().toLowerCase();
|
|
1215
|
+
if (!currentVal) return false;
|
|
1216
|
+
const sugVal = (sug.value ?? '').trim().toLowerCase();
|
|
1217
|
+
const sugLabel = (sug.label ?? '').trim().toLowerCase();
|
|
1218
|
+
const sugDisplay = (sug.display ?? '').trim().toLowerCase();
|
|
1219
|
+
return currentVal === sugVal || currentVal === sugLabel || currentVal === sugDisplay;
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
if (sug.type === 'keyword' && this._context.mode === 'keyword' && this._context.token?.type === 'keyword') {
|
|
1223
|
+
const currentKw = (this._context.token.keywordLower ?? '').trim().toLowerCase();
|
|
1224
|
+
if (!currentKw) return false;
|
|
1225
|
+
const sugId = (sug.id ?? '').trim().toLowerCase();
|
|
1226
|
+
return currentKw === sugId;
|
|
1227
|
+
}
|
|
1228
|
+
|
|
1229
|
+
return false;
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1140
1232
|
_renderSuggestions() {
|
|
1141
1233
|
if (this._popoverTitle) {
|
|
1142
1234
|
let title = 'Suggestions';
|
|
@@ -1152,12 +1244,17 @@ export class RichInput extends HTMLElement {
|
|
|
1152
1244
|
this._suggestionsList.replaceChildren();
|
|
1153
1245
|
|
|
1154
1246
|
this._activeSuggestions.forEach((sug, idx) => {
|
|
1247
|
+
const isAct = idx === this._selectedIndex;
|
|
1248
|
+
const isSel = this._isSuggestionSelected(sug);
|
|
1155
1249
|
const li = document.createElement('li');
|
|
1156
|
-
li.className = `suggestion-item${
|
|
1250
|
+
li.className = `suggestion-item${isAct ? ' active' : ''}${isSel ? ' selected' : ''}`;
|
|
1157
1251
|
li.id = `ri-opt-${idx}`;
|
|
1158
1252
|
li.setAttribute('role', 'option');
|
|
1159
|
-
li.setAttribute('aria-selected',
|
|
1160
|
-
|
|
1253
|
+
li.setAttribute('aria-selected', isSel ? 'true' : 'false');
|
|
1254
|
+
const parts = ['suggestion-item'];
|
|
1255
|
+
if (isAct) parts.push('suggestion-item-active');
|
|
1256
|
+
if (isSel) parts.push('suggestion-item-selected');
|
|
1257
|
+
li.setAttribute('part', parts.join(' '));
|
|
1161
1258
|
|
|
1162
1259
|
if (sug.image) {
|
|
1163
1260
|
const img = sug.image.cloneNode(true);
|
|
@@ -1209,7 +1306,11 @@ export class RichInput extends HTMLElement {
|
|
|
1209
1306
|
_moveSelection(delta) {
|
|
1210
1307
|
if (this._activeSuggestions.length === 0) return;
|
|
1211
1308
|
const len = this._activeSuggestions.length;
|
|
1212
|
-
|
|
1309
|
+
if (this._selectedIndex === -1) {
|
|
1310
|
+
this._selectedIndex = delta > 0 ? 0 : len - 1;
|
|
1311
|
+
} else {
|
|
1312
|
+
this._selectedIndex = (this._selectedIndex + delta + len) % len;
|
|
1313
|
+
}
|
|
1213
1314
|
this._updateActiveSuggestion();
|
|
1214
1315
|
|
|
1215
1316
|
// Scroll active item into view
|
|
@@ -1223,9 +1324,14 @@ export class RichInput extends HTMLElement {
|
|
|
1223
1324
|
const items = this._suggestionsList.children;
|
|
1224
1325
|
for (let i = 0; i < items.length; i++) {
|
|
1225
1326
|
const isAct = i === this._selectedIndex;
|
|
1327
|
+
const isSel = this._isSuggestionSelected(this._activeSuggestions[i]);
|
|
1226
1328
|
items[i].classList.toggle('active', isAct);
|
|
1227
|
-
items[i].
|
|
1228
|
-
items[i].setAttribute('
|
|
1329
|
+
items[i].classList.toggle('selected', isSel);
|
|
1330
|
+
items[i].setAttribute('aria-selected', isSel ? 'true' : 'false');
|
|
1331
|
+
const parts = ['suggestion-item'];
|
|
1332
|
+
if (isAct) parts.push('suggestion-item-active');
|
|
1333
|
+
if (isSel) parts.push('suggestion-item-selected');
|
|
1334
|
+
items[i].setAttribute('part', parts.join(' '));
|
|
1229
1335
|
if (isAct) {
|
|
1230
1336
|
this._input.setAttribute('aria-activedescendant', items[i].id);
|
|
1231
1337
|
}
|
|
@@ -1263,12 +1369,9 @@ export class RichInput extends HTMLElement {
|
|
|
1263
1369
|
composed: true,
|
|
1264
1370
|
detail: selectDetail,
|
|
1265
1371
|
}));
|
|
1266
|
-
//
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
} else {
|
|
1270
|
-
this.hideSuggestions();
|
|
1271
|
-
}
|
|
1372
|
+
// Immediately show value suggestions when a keyword was selected (e.g. `mix:`),
|
|
1373
|
+
// or keyword suggestions when a value was selected (since cursor is now after a space at a new token)
|
|
1374
|
+
this.updateSuggestions(suggestion.type === 'keyword' ? 'keyword-selected' : 'value-selected');
|
|
1272
1375
|
}
|
|
1273
1376
|
}
|
|
1274
1377
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rich-input",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "A rich input field with keyword-based autocomplete and in-input highlighting powered by <datalist>, OpaqueRange, and the Custom Highlight API",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./index.js",
|
|
@@ -31,5 +31,8 @@
|
|
|
31
31
|
"bugs": {
|
|
32
32
|
"url": "https://github.com/bramus/rich-input/issues"
|
|
33
33
|
},
|
|
34
|
-
"homepage": "https://github.com/bramus/rich-input#readme"
|
|
34
|
+
"homepage": "https://github.com/bramus/rich-input#readme",
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"puppeteer": "^25.11.0"
|
|
37
|
+
}
|
|
35
38
|
}
|
package/utils/query-parser.js
CHANGED
|
@@ -168,11 +168,13 @@ export function getCaretContext(inputStr, caretPos, configuredKeywords) {
|
|
|
168
168
|
}
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
-
// If caret is in whitespace or
|
|
171
|
+
// If caret is in whitespace or empty input (at the start of a new token)
|
|
172
172
|
if (!activeToken || activeToken.type === 'whitespace') {
|
|
173
|
-
// Check if the previous token was a colon without value or if we're in open space
|
|
174
173
|
return {
|
|
175
|
-
mode: '
|
|
174
|
+
mode: 'keyword',
|
|
175
|
+
query: '',
|
|
176
|
+
replaceStart: caretPos,
|
|
177
|
+
replaceEnd: caretPos,
|
|
176
178
|
caretPos,
|
|
177
179
|
tokens,
|
|
178
180
|
};
|
|
@@ -252,7 +254,7 @@ export function getSuggestions(context, configuredKeywords) {
|
|
|
252
254
|
for (const [id, kw] of configuredKeywords.entries()) {
|
|
253
255
|
const idLower = id.toLowerCase();
|
|
254
256
|
const labelLower = (kw.label || '').toLowerCase();
|
|
255
|
-
const matches = !q || idLower.startsWith(q) || labelLower.startsWith(q)
|
|
257
|
+
const matches = !q || idLower.startsWith(q) || labelLower.startsWith(q);
|
|
256
258
|
|
|
257
259
|
if (matches) {
|
|
258
260
|
suggestions.push({
|
|
@@ -325,6 +327,9 @@ export function applySuggestion(inputStr, suggestion, context) {
|
|
|
325
327
|
// If after text starts with colon, remove it to avoid `mix::`
|
|
326
328
|
if (after.startsWith(':')) {
|
|
327
329
|
after = after.slice(1);
|
|
330
|
+
} else if (context.token?.type !== 'keyword' && after.length > 0 && !/^\s/.test(after)) {
|
|
331
|
+
// Ensure space before following token so it doesn't become the value of this keyword
|
|
332
|
+
after = ' ' + after;
|
|
328
333
|
}
|
|
329
334
|
const newValue = before + insertText + after;
|
|
330
335
|
const newCaret = before.length + insertText.length;
|
|
@@ -333,12 +338,13 @@ export function applySuggestion(inputStr, suggestion, context) {
|
|
|
333
338
|
|
|
334
339
|
// When inserting a value (e.g. `"We Play House Recordings"`)
|
|
335
340
|
// Add a trailing space if after does not already start with whitespace
|
|
336
|
-
|
|
341
|
+
const hasLeadingSpaceAfter = /^\s/.test(after);
|
|
342
|
+
if (after.length === 0 || !hasLeadingSpaceAfter) {
|
|
337
343
|
insertText += ' ';
|
|
338
344
|
}
|
|
339
345
|
|
|
340
346
|
const newValue = before + insertText + after;
|
|
341
|
-
const newCaret = before.length + insertText.length;
|
|
347
|
+
const newCaret = before.length + insertText.length + (hasLeadingSpaceAfter ? 1 : 0);
|
|
342
348
|
return { newValue, newCaret };
|
|
343
349
|
}
|
|
344
350
|
|