@keenmate/web-multiselect 2.0.0-rc02 → 2.0.0-rc03
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 +57 -41
- package/custom-elements.json +627 -6
- package/dist/index.d.ts +244 -7
- package/dist/multiselect.js +2201 -1525
- package/dist/multiselect.umd.js +23 -23
- package/dist/style.css +1 -1
- package/package.json +2 -2
- package/src/css/badges.css +14 -6
- package/src/css/base.css +13 -0
- package/src/css/controls.css +11 -6
- package/src/css/debug.css +1 -1
- package/src/css/floating.css +400 -0
- package/src/css/options.css +40 -20
- package/src/css/rtl.css +27 -140
- package/src/css/states.css +2 -2
- package/src/css/variables.css +101 -0
- package/vscode.html-custom-data.json +15 -1
- package/web-types.json +29 -6
package/src/css/floating.css
CHANGED
|
@@ -54,6 +54,313 @@
|
|
|
54
54
|
flex-direction: column;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
/* ------------------------------------------------------------------------------
|
|
58
|
+
FULLSCREEN OVERLAY — phone / touch presentation
|
|
59
|
+
Set by JS (setPresentation('fullscreen'), driven by the element's
|
|
60
|
+
environmentChanged hook) INSTEAD of anchoring the panel. The panel becomes a
|
|
61
|
+
fixed, full-viewport sheet with its own search + close header, so the input it
|
|
62
|
+
would otherwise float beneath is fully covered. `dvh` tracks the mobile URL bar.
|
|
63
|
+
------------------------------------------------------------------------------ */
|
|
64
|
+
/* Phone-view scaling. Every size is calc(N × --ms-rem), but a custom property bakes
|
|
65
|
+
its var(--ms-rem) at its DECLARATION site — the semantic vars are declared at :host
|
|
66
|
+
(10px), so overriding --ms-rem on the panel alone does NOT re-scale them. So we both
|
|
67
|
+
(a) set the panel's --ms-rem to --ms-fullscreen-rem, and (b) RE-DECLARE the shared
|
|
68
|
+
option/checkbox/group vars here in the panel scope, with the same formulas as
|
|
69
|
+
variables.css, so their var(--ms-rem) now resolves to the enlarged value. Overlay-
|
|
70
|
+
only --ms-fullscreen-* vars already derive from --ms-fullscreen-rem at :host, and
|
|
71
|
+
JS-driven row heights (virtual/fixed) are scaled to match in code. */
|
|
72
|
+
.ms__dropdown--fullscreen,
|
|
73
|
+
.ms__selected-popover--fullscreen {
|
|
74
|
+
--ms-rem: var(--ms-fullscreen-rem);
|
|
75
|
+
--ms-option-padding: calc(0.8 * var(--ms-rem)) calc(1.2 * var(--ms-rem));
|
|
76
|
+
--ms-option-gap: calc(0.8 * var(--ms-rem));
|
|
77
|
+
--ms-option-title-font-size: calc(var(--base-font-size-sm, 1.4) * var(--ms-rem));
|
|
78
|
+
--ms-option-subtitle-font-size: calc(var(--base-font-size-xs, 1.2) * var(--ms-rem));
|
|
79
|
+
--ms-option-icon-font-size: calc(var(--base-font-size-base, 1.6) * var(--ms-rem));
|
|
80
|
+
--ms-checkbox-size: calc(1.6 * var(--ms-rem));
|
|
81
|
+
--ms-group-label-font-size: calc(var(--base-font-size-xs, 1.2) * var(--ms-rem));
|
|
82
|
+
--ms-group-label-padding: calc(0.4 * var(--ms-rem)) calc(1.2 * var(--ms-rem));
|
|
83
|
+
/* Reclaim horizontal space for labels: tighter indent than the floating default
|
|
84
|
+
(--ms-tree-base-indent 0.75rem / --ms-tree-indent 1.25rem in tree.css). */
|
|
85
|
+
--ms-tree-base-indent: var(--ms-fullscreen-tree-base-indent);
|
|
86
|
+
--ms-tree-indent: var(--ms-fullscreen-tree-indent);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/* Bigger, dropdown-like selected-item rows in the phone overlay. The badge sizing
|
|
90
|
+
vars are declared at :host against the base --ms-rem (baked at 10px), so without
|
|
91
|
+
this they'd keep base-size text/padding inside the enlarged sheet and read as
|
|
92
|
+
cramped. Re-declaring them here — where --ms-rem is --ms-fullscreen-rem — scales
|
|
93
|
+
the pill height, text, padding and remove button up with the rest of the overlay.
|
|
94
|
+
The row height is also mirrored in JS (scaledBadgeHeight → --ms-badge-height-virtual)
|
|
95
|
+
for the virtual list, so both paths agree. */
|
|
96
|
+
.ms__selected-popover--fullscreen {
|
|
97
|
+
--ms-badge-gap: calc(0.8 * var(--ms-rem));
|
|
98
|
+
--ms-badge-height: calc(4.2 * var(--ms-rem));
|
|
99
|
+
--ms-badge-font-size: calc(var(--base-font-size-sm, 1.4) * var(--ms-rem));
|
|
100
|
+
--ms-badge-text-padding: 0 calc(1.2 * var(--ms-rem));
|
|
101
|
+
--ms-badge-remove-width: calc(3.6 * var(--ms-rem));
|
|
102
|
+
--ms-badge-remove-icon-size: calc(1.2 * var(--ms-rem));
|
|
103
|
+
--ms-badge-remove-font-size: calc(var(--base-font-size-sm, 1.4) * var(--ms-rem));
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/* Action buttons (Select All / Clear All / custom) scale up in the overlay too — their
|
|
107
|
+
sizing vars are baked at :host against the base --ms-rem, so re-declare them here
|
|
108
|
+
(where --ms-rem is --ms-fullscreen-rem) for a comfortable touch target. Dropdown-only:
|
|
109
|
+
the selected-items popover has no actions row. */
|
|
110
|
+
.ms__dropdown--fullscreen {
|
|
111
|
+
--ms-actions-gap: calc(0.4 * var(--ms-rem));
|
|
112
|
+
--ms-actions-padding: calc(0.8 * var(--ms-rem));
|
|
113
|
+
--ms-action-btn-padding: calc(0.6 * var(--ms-rem)) calc(1.2 * var(--ms-rem));
|
|
114
|
+
--ms-action-btn-font-size: calc(var(--base-font-size-sm, 1.4) * var(--ms-rem));
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.ms__dropdown--fullscreen {
|
|
118
|
+
position: fixed;
|
|
119
|
+
/* top/left only — NOT `inset: 0`. `inset` also sets `bottom: 0`, and a fixed box with
|
|
120
|
+
both `top` and `bottom` constrained ignores its `height`. observeKeyboardInset()
|
|
121
|
+
shrinks the sheet above the soft keyboard by writing `height` (+ `top`), so a pinned
|
|
122
|
+
`bottom` would silently defeat it — the list and bottom actions would stay behind the
|
|
123
|
+
keyboard. With only top/left pinned, height governs and the keyboard reflow works. */
|
|
124
|
+
top: 0;
|
|
125
|
+
inset-inline-start: 0;
|
|
126
|
+
width: 100vw;
|
|
127
|
+
max-width: 100vw;
|
|
128
|
+
height: 100dvh;
|
|
129
|
+
max-height: 100dvh;
|
|
130
|
+
border: none;
|
|
131
|
+
border-radius: 0;
|
|
132
|
+
background: var(--ms-fullscreen-bg);
|
|
133
|
+
color: var(--ms-fullscreen-text-color);
|
|
134
|
+
z-index: var(--ms-z-index-fullscreen);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.ms__dropdown--fullscreen .ms__dropdown-inner {
|
|
138
|
+
/* The panel is a full-height flex column; the list fills the space under the header. */
|
|
139
|
+
display: flex;
|
|
140
|
+
flex-direction: column;
|
|
141
|
+
flex: 1;
|
|
142
|
+
min-height: 0;
|
|
143
|
+
max-height: none;
|
|
144
|
+
/* The .ms__options child is the sole scroller in fullscreen (flex-fill + overflow-y
|
|
145
|
+
below). The base rule makes THIS element scroll too; two nested scrollers let the
|
|
146
|
+
last row get trapped in the outer one (partially visible, unreachable). Clip here so
|
|
147
|
+
scrolling happens in exactly one place. */
|
|
148
|
+
overflow: hidden;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/* The options list fills the sheet between the header and any actions row, scrolling
|
|
152
|
+
within the panel instead of at a fixed height — for BOTH the virtual list (its
|
|
153
|
+
inline maxHeight is dropped in fullscreen, see renderDropdownVirtual) and the plain
|
|
154
|
+
non-virtual list (small selections). Without flex-fill, a short non-virtual list
|
|
155
|
+
sits content-height at the top and a bottom actions row floats mid-sheet with empty
|
|
156
|
+
space beneath it. */
|
|
157
|
+
.ms__dropdown--fullscreen .ms__options {
|
|
158
|
+
flex: 1 1 0;
|
|
159
|
+
min-height: 0;
|
|
160
|
+
height: auto;
|
|
161
|
+
max-height: none;
|
|
162
|
+
overflow-y: auto;
|
|
163
|
+
/* Breathing room so the last row always clears the sheet's (or keyboard's) bottom edge
|
|
164
|
+
instead of sitting flush against it, half-cut. */
|
|
165
|
+
padding-bottom: var(--ms-option-gap);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/* Pin the action row (Select All / Clear / custom) so it never shrinks and stays docked
|
|
169
|
+
at the bottom of the sheet. Once observeKeyboardInset() shrinks the panel above the
|
|
170
|
+
soft keyboard, only .ms__options scrolls — the actions stay reachable above the keys. */
|
|
171
|
+
.ms__dropdown--fullscreen .ms__actions {
|
|
172
|
+
flex: 0 0 auto;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/* Shared fullscreen header bar — ONE treatment for both the dropdown (search
|
|
176
|
+
field) and the selected-items popover (title). Same padding, height, border, and
|
|
177
|
+
close button, so the two mobile overlays are visually identical. The popover's
|
|
178
|
+
header/close reuse their own class names but adopt these rules under
|
|
179
|
+
`--fullscreen`, and the selectors are listed together so there's one source of
|
|
180
|
+
truth (no drift between the two headers). */
|
|
181
|
+
.ms__fullscreen-header,
|
|
182
|
+
.ms__selected-popover--fullscreen .ms__selected-popover-header {
|
|
183
|
+
flex: 0 0 auto;
|
|
184
|
+
display: flex;
|
|
185
|
+
align-items: center;
|
|
186
|
+
/* Wrap lets the navigate-mode match navigator (flex-basis 100%) drop onto its own
|
|
187
|
+
row under the search box while search + close stay on the first row. */
|
|
188
|
+
flex-wrap: wrap;
|
|
189
|
+
gap: var(--ms-fullscreen-header-gap);
|
|
190
|
+
min-height: var(--ms-fullscreen-header-min-height);
|
|
191
|
+
padding: var(--ms-fullscreen-header-padding);
|
|
192
|
+
background: var(--ms-fullscreen-header-bg);
|
|
193
|
+
border-bottom: var(--ms-fullscreen-header-border);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/* Match navigator (navigate searchMode only): result count on the lead edge, round
|
|
197
|
+
prev/next buttons on the trailing edge, forced onto its own full-width row. Hidden
|
|
198
|
+
inline (display:none) by JS until there's a search term. */
|
|
199
|
+
.ms__fullscreen-nav {
|
|
200
|
+
flex: 0 0 100%;
|
|
201
|
+
display: flex;
|
|
202
|
+
align-items: center;
|
|
203
|
+
justify-content: space-between;
|
|
204
|
+
gap: var(--ms-fullscreen-nav-gap);
|
|
205
|
+
padding-top: var(--ms-fullscreen-nav-padding-top);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.ms__fullscreen-nav-count {
|
|
209
|
+
font-size: var(--ms-fullscreen-nav-count-font-size);
|
|
210
|
+
color: var(--ms-fullscreen-nav-count-color);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.ms__fullscreen-nav-controls {
|
|
214
|
+
display: flex;
|
|
215
|
+
align-items: center;
|
|
216
|
+
gap: var(--ms-fullscreen-nav-gap);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.ms__fullscreen-nav-btn {
|
|
220
|
+
flex: 0 0 auto;
|
|
221
|
+
display: inline-flex;
|
|
222
|
+
align-items: center;
|
|
223
|
+
justify-content: center;
|
|
224
|
+
width: var(--ms-fullscreen-nav-btn-size);
|
|
225
|
+
height: var(--ms-fullscreen-nav-btn-size);
|
|
226
|
+
padding: 0;
|
|
227
|
+
color: var(--ms-fullscreen-nav-btn-color);
|
|
228
|
+
background: var(--ms-fullscreen-nav-btn-bg);
|
|
229
|
+
border: none;
|
|
230
|
+
border-radius: 50%;
|
|
231
|
+
cursor: pointer;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.ms__fullscreen-nav-btn:hover:not(:disabled) {
|
|
235
|
+
background: var(--ms-fullscreen-nav-btn-bg-hover);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.ms__fullscreen-nav-btn:disabled {
|
|
239
|
+
opacity: 0.4;
|
|
240
|
+
cursor: default;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.ms__fullscreen-nav-btn::before {
|
|
244
|
+
content: "";
|
|
245
|
+
display: block;
|
|
246
|
+
width: var(--ms-fullscreen-nav-btn-icon-size);
|
|
247
|
+
height: var(--ms-fullscreen-nav-btn-icon-size);
|
|
248
|
+
background-color: currentColor;
|
|
249
|
+
-webkit-mask: var(--ms-icon-chevron) center / contain no-repeat;
|
|
250
|
+
mask: var(--ms-icon-chevron) center / contain no-repeat;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/* Chevron points up by default; the "next" (down) button flips it vertically. */
|
|
254
|
+
.ms__fullscreen-nav-btn--next::before {
|
|
255
|
+
transform: scaleY(-1);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/* The leading element (search field or title) fills the bar, pushing the close
|
|
259
|
+
button to the trailing edge in both overlays. */
|
|
260
|
+
.ms__fullscreen-header > .ms__fullscreen-search,
|
|
261
|
+
.ms__selected-popover--fullscreen .ms__selected-popover-header > span {
|
|
262
|
+
flex: 1 1 auto;
|
|
263
|
+
min-width: 0;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/* Popover title typography in fullscreen (matches a header title, not the small
|
|
267
|
+
floating-popover label). */
|
|
268
|
+
.ms__selected-popover--fullscreen .ms__selected-popover-header {
|
|
269
|
+
font-size: var(--ms-fullscreen-title-font-size);
|
|
270
|
+
font-weight: var(--ms-fullscreen-title-font-weight);
|
|
271
|
+
color: var(--ms-fullscreen-text-color);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
.ms__fullscreen-search {
|
|
275
|
+
font-family: inherit;
|
|
276
|
+
font-size: var(--ms-fullscreen-search-font-size);
|
|
277
|
+
color: inherit;
|
|
278
|
+
background: transparent;
|
|
279
|
+
border: var(--ms-fullscreen-search-border);
|
|
280
|
+
border-radius: var(--ms-fullscreen-search-border-radius);
|
|
281
|
+
padding: var(--ms-fullscreen-search-padding);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
.ms__fullscreen-search:focus {
|
|
285
|
+
outline: none;
|
|
286
|
+
border: var(--ms-input-border-focus);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/* Shared close button — identical big, round, mask-icon ✕ in both overlays. */
|
|
290
|
+
.ms__fullscreen-close,
|
|
291
|
+
.ms__selected-popover--fullscreen .ms__selected-popover-close {
|
|
292
|
+
flex: 0 0 auto;
|
|
293
|
+
display: inline-flex;
|
|
294
|
+
align-items: center;
|
|
295
|
+
justify-content: center;
|
|
296
|
+
width: var(--ms-fullscreen-close-size);
|
|
297
|
+
height: var(--ms-fullscreen-close-size);
|
|
298
|
+
padding: 0;
|
|
299
|
+
color: var(--ms-fullscreen-close-color);
|
|
300
|
+
background: transparent;
|
|
301
|
+
border: none;
|
|
302
|
+
border-radius: 50%;
|
|
303
|
+
cursor: pointer;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.ms__fullscreen-close:hover,
|
|
307
|
+
.ms__selected-popover--fullscreen .ms__selected-popover-close:hover {
|
|
308
|
+
background: var(--ms-fullscreen-close-bg-hover);
|
|
309
|
+
color: var(--ms-fullscreen-close-color);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
.ms__fullscreen-close::before,
|
|
313
|
+
.ms__selected-popover--fullscreen .ms__selected-popover-close::before {
|
|
314
|
+
content: "";
|
|
315
|
+
display: block;
|
|
316
|
+
width: var(--ms-fullscreen-close-icon-size);
|
|
317
|
+
height: var(--ms-fullscreen-close-icon-size);
|
|
318
|
+
background-color: currentColor;
|
|
319
|
+
-webkit-mask: var(--ms-icon-remove) center / contain no-repeat;
|
|
320
|
+
mask: var(--ms-icon-remove) center / contain no-repeat;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/* Truncated-label reveal — a circled "i" at the trailing edge of a fullscreen row
|
|
324
|
+
whose label is clipped. Fullscreen-only markup (the renderer emits it only for the
|
|
325
|
+
overlay), and CSS keeps it hidden until JS tags the row .ms__option--truncated
|
|
326
|
+
(measured per render). Tapping it reveals the full label — the touch-friendly
|
|
327
|
+
substitute for the hover option tooltip, which never fires on touch. */
|
|
328
|
+
.ms__dropdown--fullscreen .ms__option-info {
|
|
329
|
+
flex: 0 0 auto;
|
|
330
|
+
display: none;
|
|
331
|
+
align-items: center;
|
|
332
|
+
justify-content: center;
|
|
333
|
+
width: var(--ms-fullscreen-info-size);
|
|
334
|
+
height: var(--ms-fullscreen-info-size);
|
|
335
|
+
margin-inline-start: var(--ms-option-gap);
|
|
336
|
+
padding: 0;
|
|
337
|
+
color: var(--ms-fullscreen-info-color);
|
|
338
|
+
background: transparent;
|
|
339
|
+
border: none;
|
|
340
|
+
border-radius: 50%;
|
|
341
|
+
cursor: pointer;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
.ms__dropdown--fullscreen .ms__option--truncated .ms__option-info {
|
|
345
|
+
display: inline-flex;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
@media (hover: hover) {
|
|
349
|
+
.ms__dropdown--fullscreen .ms__option-info:hover {
|
|
350
|
+
background: var(--ms-fullscreen-info-bg-hover);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
.ms__dropdown--fullscreen .ms__option-info::before {
|
|
355
|
+
content: "";
|
|
356
|
+
display: block;
|
|
357
|
+
width: var(--ms-fullscreen-info-icon-size);
|
|
358
|
+
height: var(--ms-fullscreen-info-icon-size);
|
|
359
|
+
background-color: currentColor;
|
|
360
|
+
-webkit-mask: var(--ms-icon-info) center / contain no-repeat;
|
|
361
|
+
mask: var(--ms-icon-info) center / contain no-repeat;
|
|
362
|
+
}
|
|
363
|
+
|
|
57
364
|
/* Inner scrolling container — clips scrollbar to rounded corners */
|
|
58
365
|
.ms__dropdown-inner {
|
|
59
366
|
flex: 1;
|
|
@@ -150,6 +457,64 @@
|
|
|
150
457
|
visibility: visible;
|
|
151
458
|
}
|
|
152
459
|
|
|
460
|
+
/* Truncated-label reveal fired from inside the fullscreen overlay — lift it above
|
|
461
|
+
the overlay (10001), which the plain option tooltip (10000) would sit behind. */
|
|
462
|
+
.ms__option-tooltip--fullscreen {
|
|
463
|
+
z-index: var(--ms-z-index-fullscreen-tooltip);
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/* ==============================================================================
|
|
467
|
+
TRANSIENT MESSAGE / TOAST (showMessage)
|
|
468
|
+
==============================================================================
|
|
469
|
+
Rendered above the panel so a veto reason (or any consumer feedback) is visible
|
|
470
|
+
in BOTH presentations: anchored under the control when floating (position set by
|
|
471
|
+
floating-ui), pinned to the bottom-centre of the viewport — above the sheet — when
|
|
472
|
+
fullscreen. One shows at a time; tap to dismiss. */
|
|
473
|
+
.ms__message {
|
|
474
|
+
position: fixed;
|
|
475
|
+
z-index: var(--ms-message-z-index);
|
|
476
|
+
box-sizing: border-box;
|
|
477
|
+
max-width: var(--ms-message-max-width);
|
|
478
|
+
padding: var(--ms-message-padding);
|
|
479
|
+
font-family: inherit;
|
|
480
|
+
font-size: var(--ms-message-font-size);
|
|
481
|
+
font-weight: var(--ms-message-font-weight);
|
|
482
|
+
line-height: var(--ms-line-height-normal);
|
|
483
|
+
color: var(--ms-message-color);
|
|
484
|
+
background: var(--ms-message-bg);
|
|
485
|
+
border: var(--ms-message-border);
|
|
486
|
+
border-radius: var(--ms-message-border-radius);
|
|
487
|
+
box-shadow: var(--ms-message-shadow);
|
|
488
|
+
cursor: pointer;
|
|
489
|
+
opacity: 0;
|
|
490
|
+
transition: opacity var(--ms-transition-normal) ease;
|
|
491
|
+
/* The one tap-highlight declaration NOT covered by :host (base.css): the message can
|
|
492
|
+
be reparented to document.body, outside the shadow subtree, so it sets its own. */
|
|
493
|
+
-webkit-tap-highlight-color: transparent;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
.ms__message--visible {
|
|
497
|
+
opacity: 1;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
.ms__message--info { background: var(--ms-message-info-bg); color: var(--ms-message-info-color); }
|
|
501
|
+
.ms__message--warning { background: var(--ms-message-warning-bg); color: var(--ms-message-warning-color); }
|
|
502
|
+
.ms__message--error { background: var(--ms-message-error-bg); color: var(--ms-message-error-color); }
|
|
503
|
+
.ms__message--success { background: var(--ms-message-success-bg); color: var(--ms-message-success-color); }
|
|
504
|
+
|
|
505
|
+
/* Fullscreen: bottom-centre of the viewport, above the overlay. Its sizing vars are
|
|
506
|
+
--ms-rem-based (baked at :host), so rescale the key ones here against
|
|
507
|
+
--ms-fullscreen-rem to match the enlarged phone view. */
|
|
508
|
+
.ms__message--fullscreen {
|
|
509
|
+
left: 50%;
|
|
510
|
+
right: auto;
|
|
511
|
+
bottom: var(--ms-message-fullscreen-offset);
|
|
512
|
+
transform: translateX(-50%);
|
|
513
|
+
max-width: min(var(--ms-message-max-width), calc(100vw - 4 * var(--ms-fullscreen-rem)));
|
|
514
|
+
padding: calc(1.0 * var(--ms-fullscreen-rem)) calc(1.4 * var(--ms-fullscreen-rem));
|
|
515
|
+
font-size: calc(var(--base-font-size-sm, 1.4) * var(--ms-fullscreen-rem));
|
|
516
|
+
}
|
|
517
|
+
|
|
153
518
|
/* ==============================================================================
|
|
154
519
|
SELECTED-ITEMS POPOVER
|
|
155
520
|
==============================================================================
|
|
@@ -182,6 +547,37 @@
|
|
|
182
547
|
max-height: none;
|
|
183
548
|
}
|
|
184
549
|
|
|
550
|
+
/* ------------------------------------------------------------------------------
|
|
551
|
+
FULLSCREEN OVERLAY — phone / touch presentation (mirrors the dropdown overlay).
|
|
552
|
+
Set by JS (setPresentation('fullscreen')) instead of anchoring. The popover
|
|
553
|
+
already renders its own header + close button, so it just becomes a fixed,
|
|
554
|
+
full-viewport sheet. Declared AFTER --virtual so its `display:flex` wins the
|
|
555
|
+
large-selection (virtual) case; the virtual body flexes to fill (its inline
|
|
556
|
+
height is dropped in fullscreen — see renderSelectedPopoverVirtual).
|
|
557
|
+
------------------------------------------------------------------------------ */
|
|
558
|
+
.ms__selected-popover--fullscreen {
|
|
559
|
+
position: fixed;
|
|
560
|
+
inset: 0;
|
|
561
|
+
display: flex;
|
|
562
|
+
flex-direction: column;
|
|
563
|
+
width: 100vw;
|
|
564
|
+
max-width: 100vw;
|
|
565
|
+
height: 100dvh;
|
|
566
|
+
max-height: 100dvh;
|
|
567
|
+
border: none;
|
|
568
|
+
border-radius: 0;
|
|
569
|
+
overflow: hidden;
|
|
570
|
+
background: var(--ms-fullscreen-bg);
|
|
571
|
+
color: var(--ms-fullscreen-text-color);
|
|
572
|
+
z-index: var(--ms-z-index-fullscreen);
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
.ms__selected-popover--fullscreen .ms__selected-popover-body {
|
|
576
|
+
flex: 1 1 0;
|
|
577
|
+
min-height: 0;
|
|
578
|
+
max-height: none;
|
|
579
|
+
}
|
|
580
|
+
|
|
185
581
|
.ms__selected-popover-header {
|
|
186
582
|
display: flex;
|
|
187
583
|
align-items: center;
|
|
@@ -261,6 +657,10 @@
|
|
|
261
657
|
width: 100%;
|
|
262
658
|
min-height: fit-content; /* Allow badges to expand based on content */
|
|
263
659
|
line-height: var(--ms-line-height-relaxed); /* Override line-height: 1 to allow multi-line content */
|
|
660
|
+
/* The body is a flex column; without this, badges shrink (flex-shrink defaults to 1)
|
|
661
|
+
toward their min-content height once the list overflows — so rows visibly get
|
|
662
|
+
shorter as you select more. Pin the height and let the body scroll instead. */
|
|
663
|
+
flex-shrink: 0;
|
|
264
664
|
}
|
|
265
665
|
|
|
266
666
|
.ms__selected-popover-body .ms__badge-text {
|
package/src/css/options.css
CHANGED
|
@@ -98,11 +98,19 @@
|
|
|
98
98
|
not a text-selection one — stop the browser from highlighting the label. */
|
|
99
99
|
user-select: none;
|
|
100
100
|
-webkit-user-select: none;
|
|
101
|
+
/* Tap-highlight flash is suppressed once for the whole component on :host (base.css) —
|
|
102
|
+
an inherited property, so it reaches this row without a per-element declaration. */
|
|
101
103
|
}
|
|
102
104
|
|
|
103
|
-
.
|
|
104
|
-
|
|
105
|
-
|
|
105
|
+
/* Hover states are gated to real pointing devices. On touch, `:hover` "sticks"
|
|
106
|
+
after a tap until the next tap elsewhere, so a tapped row (or a tap on its info
|
|
107
|
+
affordance) would stay highlighted as if selected. `@media (hover: hover)` keeps
|
|
108
|
+
hover on mouse/trackpad and drops it on touch (phones, the fullscreen overlay). */
|
|
109
|
+
@media (hover: hover) {
|
|
110
|
+
.ms__option:hover {
|
|
111
|
+
background: var(--ms-option-bg-hover);
|
|
112
|
+
color: var(--ms-option-color-hover, inherit);
|
|
113
|
+
}
|
|
106
114
|
}
|
|
107
115
|
|
|
108
116
|
.ms__option--focused {
|
|
@@ -115,15 +123,17 @@
|
|
|
115
123
|
.ms__option--matched {
|
|
116
124
|
background: var(--ms-option-bg-matched);
|
|
117
125
|
color: var(--ms-option-color-matched, inherit);
|
|
118
|
-
border-
|
|
126
|
+
border-inline-start: var(--ms-option-border-matched); /* leading-edge accent bar; flips in RTL */
|
|
119
127
|
}
|
|
120
128
|
|
|
121
129
|
.ms__option--selected {
|
|
122
130
|
background: var(--ms-option-bg-selected);
|
|
123
131
|
}
|
|
124
132
|
|
|
125
|
-
|
|
126
|
-
|
|
133
|
+
@media (hover: hover) {
|
|
134
|
+
.ms__option--selected:hover {
|
|
135
|
+
background: var(--ms-option-bg-selected-hover, var(--ms-option-bg-selected));
|
|
136
|
+
}
|
|
127
137
|
}
|
|
128
138
|
|
|
129
139
|
.ms__option--disabled {
|
|
@@ -137,9 +147,11 @@
|
|
|
137
147
|
}
|
|
138
148
|
|
|
139
149
|
/* Focused + Hover */
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
150
|
+
@media (hover: hover) {
|
|
151
|
+
.ms__option--focused:hover {
|
|
152
|
+
background: var(--ms-option-bg-focused-hover);
|
|
153
|
+
color: var(--ms-option-color-focused-hover, var(--ms-option-color-focused, var(--ms-option-text-color)));
|
|
154
|
+
}
|
|
143
155
|
}
|
|
144
156
|
|
|
145
157
|
/* Matched + Hover */
|
|
@@ -158,7 +170,7 @@
|
|
|
158
170
|
/* Selected + Matched */
|
|
159
171
|
.ms__option--selected.ms__option--matched {
|
|
160
172
|
background: var(--ms-option-bg-selected-matched);
|
|
161
|
-
border-
|
|
173
|
+
border-inline-start: var(--ms-option-border-matched); /* leading-edge accent bar; flips in RTL */
|
|
162
174
|
}
|
|
163
175
|
|
|
164
176
|
/* Disabled + Selected */
|
|
@@ -195,9 +207,9 @@
|
|
|
195
207
|
flex-shrink: 0;
|
|
196
208
|
position: relative;
|
|
197
209
|
margin-top: var(--ms-checkbox-margin-top);
|
|
198
|
-
margin-
|
|
210
|
+
margin-inline-end: var(--ms-checkbox-margin-right);
|
|
199
211
|
margin-bottom: var(--ms-checkbox-margin-bottom);
|
|
200
|
-
margin-
|
|
212
|
+
margin-inline-start: var(--ms-checkbox-margin-left);
|
|
201
213
|
width: var(--ms-checkbox-size);
|
|
202
214
|
height: var(--ms-checkbox-size);
|
|
203
215
|
transform: scale(var(--ms-checkbox-scale));
|
|
@@ -346,16 +358,20 @@
|
|
|
346
358
|
}
|
|
347
359
|
|
|
348
360
|
/* Title color states (for solid background themes) */
|
|
349
|
-
|
|
350
|
-
|
|
361
|
+
@media (hover: hover) {
|
|
362
|
+
.ms__option:hover .ms__option-title {
|
|
363
|
+
color: var(--ms-option-title-color-hover, var(--ms-option-title-color));
|
|
364
|
+
}
|
|
351
365
|
}
|
|
352
366
|
|
|
353
367
|
.ms__option--selected .ms__option-title {
|
|
354
368
|
color: var(--ms-option-title-color-selected, var(--ms-option-title-color));
|
|
355
369
|
}
|
|
356
370
|
|
|
357
|
-
|
|
358
|
-
|
|
371
|
+
@media (hover: hover) {
|
|
372
|
+
.ms__option--selected:hover .ms__option-title {
|
|
373
|
+
color: var(--ms-option-title-color-selected-hover, var(--ms-option-title-color-selected, var(--ms-option-title-color)));
|
|
374
|
+
}
|
|
359
375
|
}
|
|
360
376
|
|
|
361
377
|
/* Highlight matched text */
|
|
@@ -374,16 +390,20 @@
|
|
|
374
390
|
}
|
|
375
391
|
|
|
376
392
|
/* Subtitle color states (for solid background themes) */
|
|
377
|
-
|
|
378
|
-
|
|
393
|
+
@media (hover: hover) {
|
|
394
|
+
.ms__option:hover .ms__option-subtitle {
|
|
395
|
+
color: var(--ms-option-subtitle-color-hover, var(--ms-option-subtitle-color));
|
|
396
|
+
}
|
|
379
397
|
}
|
|
380
398
|
|
|
381
399
|
.ms__option--selected .ms__option-subtitle {
|
|
382
400
|
color: var(--ms-option-subtitle-color-selected, var(--ms-option-subtitle-color));
|
|
383
401
|
}
|
|
384
402
|
|
|
385
|
-
|
|
386
|
-
|
|
403
|
+
@media (hover: hover) {
|
|
404
|
+
.ms__option--selected:hover .ms__option-subtitle {
|
|
405
|
+
color: var(--ms-option-subtitle-color-selected-hover, var(--ms-option-subtitle-color-selected, var(--ms-option-subtitle-color)));
|
|
406
|
+
}
|
|
387
407
|
}
|
|
388
408
|
|
|
389
409
|
/* ==============================================================================
|