tyrell-components 1.0.0-TC52 → 1.0.0-TC53
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/css/tyrell-theme.css +25 -2
- package/css/tyrell.css +4 -0
- package/dist/tyrell-colors-static.css +1 -316
- package/dist/tyrell-theme.css +1 -1443
- package/dist/tyrell.css +1 -1390
- package/dist/tyrell.js +1 -1
- package/lib/base/ty-component.js +196 -196
- package/lib/components/button.d.ts +1 -1
- package/lib/components/button.js +260 -259
- package/lib/components/calendar-month.d.ts +2 -2
- package/lib/components/calendar-month.js +426 -416
- package/lib/components/calendar-navigation.js +238 -238
- package/lib/components/calendar.js +605 -602
- package/lib/components/checkbox.d.ts +1 -1
- package/lib/components/checkbox.js +273 -272
- package/lib/components/copy.d.ts +1 -1
- package/lib/components/copy.js +279 -278
- package/lib/components/date-picker.d.ts +1 -1
- package/lib/components/date-picker.js +1103 -1108
- package/lib/components/file-upload.js +404 -404
- package/lib/components/icon.js +141 -141
- package/lib/components/input.d.ts +1 -1
- package/lib/components/input.js +593 -596
- package/lib/components/modal.js +319 -319
- package/lib/components/option.js +167 -167
- package/lib/components/popup.js +233 -233
- package/lib/components/radio.d.ts +2 -2
- package/lib/components/radio.js +407 -406
- package/lib/components/resize-observer.js +67 -67
- package/lib/components/scroll-container.js +294 -294
- package/lib/components/select.d.ts +1 -1
- package/lib/components/select.js +1524 -1532
- package/lib/components/selected-tags.js +184 -184
- package/lib/components/step.js +62 -62
- package/lib/components/switch.d.ts +1 -1
- package/lib/components/switch.js +214 -213
- package/lib/components/tab.js +62 -62
- package/lib/components/tabs.js +507 -507
- package/lib/components/tag.d.ts +1 -1
- package/lib/components/tag.js +236 -235
- package/lib/components/textarea.d.ts +1 -1
- package/lib/components/textarea.js +457 -456
- package/lib/components/tooltip.js +283 -283
- package/lib/components/wizard.js +384 -384
- package/lib/icons/heroicons/micro.js +392 -392
- package/lib/icons/heroicons/mini.js +382 -382
- package/lib/icons/heroicons/outline.js +337 -337
- package/lib/icons/heroicons/solid.js +407 -407
- package/lib/icons/lucide.js +22843 -22843
- package/lib/icons/material/filled.js +9653 -9653
- package/lib/icons/material/outlined.js +10271 -10271
- package/lib/icons/material/round.js +10495 -10495
- package/lib/icons/material/sharp.js +9905 -9905
- package/lib/icons/material/two-tone.js +12792 -12792
- package/lib/index.js +21 -21
- package/lib/styles/button.js +176 -288
- package/lib/styles/calendar-month.js +123 -183
- package/lib/styles/calendar-navigation.js +60 -79
- package/lib/styles/calendar.js +8 -9
- package/lib/styles/checkbox.js +45 -72
- package/lib/styles/copy.js +67 -91
- package/lib/styles/custom-scrollbar.js +80 -100
- package/lib/styles/date-picker.js +261 -331
- package/lib/styles/field-size.d.ts +6 -0
- package/lib/styles/field-size.js +91 -0
- package/lib/styles/file-upload.js +139 -169
- package/lib/styles/icon.js +92 -156
- package/lib/styles/input.js +125 -241
- package/lib/styles/modal.js +67 -102
- package/lib/styles/option.d.ts +1 -1
- package/lib/styles/option.js +47 -67
- package/lib/styles/popup.js +34 -65
- package/lib/styles/radio.js +69 -96
- package/lib/styles/resize-observer.js +2 -5
- package/lib/styles/scroll-container.js +100 -130
- package/lib/styles/select-base.js +525 -778
- package/lib/styles/select.js +140 -228
- package/lib/styles/step.js +22 -29
- package/lib/styles/switch.js +34 -55
- package/lib/styles/tab.js +22 -29
- package/lib/styles/tabs.js +171 -252
- package/lib/styles/tag.js +135 -188
- package/lib/styles/textarea.d.ts +1 -1
- package/lib/styles/textarea.js +205 -271
- package/lib/styles/tooltip.js +3 -3
- package/lib/styles/wizard.js +170 -226
- package/lib/types/common.d.ts +2 -0
- package/lib/types/common.js +6 -5
- package/lib/utils/calendar-utils.js +100 -100
- package/lib/utils/custom-scrollbar.js +272 -272
- package/lib/utils/flavor-sheet.js +14 -14
- package/lib/utils/icon-registry.js +127 -127
- package/lib/utils/loader-registry.js +3 -3
- package/lib/utils/locale.js +34 -34
- package/lib/utils/mobile.js +1 -1
- package/lib/utils/number-format.js +54 -54
- package/lib/utils/positioning.js +212 -212
- package/lib/utils/property-capture.js +36 -36
- package/lib/utils/property-manager.js +125 -125
- package/lib/utils/resize-observer.js +23 -23
- package/lib/utils/scroll-lock.js +57 -57
- package/lib/utils/styles.js +17 -17
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +4 -4
|
@@ -1,971 +1,718 @@
|
|
|
1
1
|
import { FLAVORS } from "../types/common.js";
|
|
2
|
+
import { fieldSizeVars } from "./field-size.js";
|
|
2
3
|
import { customScrollbarStyles } from "./custom-scrollbar.js";
|
|
3
4
|
const selectFlavor = (f, fb) => {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
const c = (s) => fb
|
|
6
|
+
? s
|
|
7
|
+
? `var(--ty-color-${f}${s}, var(--ty-color-${f}, var(--ty-color-${fb}${s})))`
|
|
8
|
+
: `var(--ty-color-${f}, var(--ty-color-${fb}))`
|
|
9
|
+
: s
|
|
10
|
+
? `var(--ty-color-${f}${s}, var(--ty-color-${f}))`
|
|
11
|
+
: `var(--ty-color-${f})`;
|
|
12
|
+
return `
|
|
12
13
|
:host([flavor="${f}"]) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
--select-accent: var(--ty-input-${f}-border, ${c("-soft")});
|
|
15
|
+
--select-accent-bold: ${c("")};
|
|
16
|
+
--select-ring: color-mix(in oklab, ${c("")} 15%, transparent);
|
|
16
17
|
}
|
|
17
18
|
:host([flavor="${f}+"]) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
--select-accent: ${c("")};
|
|
20
|
+
--select-accent-bold: ${c("-strong")};
|
|
21
|
+
--select-ring: color-mix(in oklab, ${c("-strong")} 15%, transparent);
|
|
21
22
|
}
|
|
22
23
|
:host([flavor="${f}-"]) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
--select-accent: ${c("-faint")};
|
|
25
|
+
--select-accent-bold: ${c("-soft")};
|
|
26
|
+
--select-ring: color-mix(in oklab, ${c("-soft")} 15%, transparent);
|
|
26
27
|
}
|
|
27
28
|
`;
|
|
28
29
|
};
|
|
29
30
|
export const selectCustomFlavorCss = (base) => selectFlavor(base, "neutral");
|
|
30
31
|
export const selectBaseStyles = `
|
|
32
|
+
${fieldSizeVars}
|
|
31
33
|
:host {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/* compact is a toolbar/filter-bar trigger — it must hug its own content so
|
|
39
|
-
it can sit inline next to other toolbar items, not claim a full row.
|
|
40
|
-
inline-block (not plain inline): a block box still ignores width and
|
|
41
|
-
collapses vertical margin, which is what we're fixing above. */
|
|
34
|
+
display: block;
|
|
35
|
+
width: 100%;
|
|
36
|
+
font-family: inherit;
|
|
37
|
+
--mobile-border-color: var(--ty-border, #5858587d);
|
|
38
|
+
}
|
|
42
39
|
:host([compact]) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/* A custom slot="trigger" is the same situation as compact: the trigger is
|
|
48
|
-
the consumer's own button, not a form field — hug it so chips/toolbar
|
|
49
|
-
items can sit right next to it. [has-trigger] is reflected by
|
|
50
|
-
setupTriggerSlot() because Blink does not parse :has() inside :host(). */
|
|
40
|
+
display: inline-block;
|
|
41
|
+
width: auto;
|
|
42
|
+
}
|
|
51
43
|
:host([has-trigger]) {
|
|
52
|
-
|
|
53
|
-
|
|
44
|
+
display: inline-block;
|
|
45
|
+
width: auto;
|
|
54
46
|
}
|
|
55
|
-
|
|
56
47
|
.dropdown-dialog {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
scale var(--ty-popup-duration, 180ms) var(--ty-popup-ease, cubic-bezier(0.34, 1.56, 0.64, 1)),
|
|
79
|
-
translate var(--ty-popup-duration, 180ms) var(--ty-popup-ease, cubic-bezier(0.34, 1.56, 0.64, 1));
|
|
80
|
-
|
|
81
|
-
transform: translate(var(--dropdown-offset-x, 0px), var(--dropdown-offset-y, 0px));
|
|
82
|
-
top: -1000px;
|
|
83
|
-
left: -1000px;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/* When opened via showModal(), apply flex layout and direction */
|
|
48
|
+
position: fixed;
|
|
49
|
+
width: var(--dropdown-width, 200px);
|
|
50
|
+
max-width: 100vw;
|
|
51
|
+
margin: 0;
|
|
52
|
+
padding: 0;
|
|
53
|
+
border: none;
|
|
54
|
+
background: transparent;
|
|
55
|
+
box-sizing: border-box;
|
|
56
|
+
padding: var(--dropdown-padding, 20px);
|
|
57
|
+
opacity: 0;
|
|
58
|
+
scale: 0.96;
|
|
59
|
+
translate: 0 -6px;
|
|
60
|
+
transform-origin: top center;
|
|
61
|
+
transition:
|
|
62
|
+
opacity var(--ty-popup-duration, 180ms) var(--ty-popup-ease, cubic-bezier(0.34, 1.56, 0.64, 1)),
|
|
63
|
+
scale var(--ty-popup-duration, 180ms) var(--ty-popup-ease, cubic-bezier(0.34, 1.56, 0.64, 1)),
|
|
64
|
+
translate var(--ty-popup-duration, 180ms) var(--ty-popup-ease, cubic-bezier(0.34, 1.56, 0.64, 1));
|
|
65
|
+
transform: translate(var(--dropdown-offset-x, 0px), var(--dropdown-offset-y, 0px));
|
|
66
|
+
top: -1000px;
|
|
67
|
+
left: -1000px;
|
|
68
|
+
}
|
|
87
69
|
.dropdown-dialog[open] {
|
|
88
|
-
|
|
89
|
-
|
|
70
|
+
display: flex;
|
|
71
|
+
flex-direction: column;
|
|
90
72
|
}
|
|
91
|
-
|
|
92
73
|
.dropdown-dialog.position-below {
|
|
93
|
-
|
|
94
|
-
|
|
74
|
+
left: var(--dropdown-x);
|
|
75
|
+
top: var(--dropdown-y);
|
|
95
76
|
}
|
|
96
|
-
|
|
97
77
|
.dropdown-dialog.position-above {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
}
|
|
105
|
-
|
|
78
|
+
left: var(--dropdown-x);
|
|
79
|
+
bottom: var(--dropdown-y);
|
|
80
|
+
top: auto;
|
|
81
|
+
flex-direction: column-reverse;
|
|
82
|
+
translate: 0 6px;
|
|
83
|
+
transform-origin: bottom center;
|
|
84
|
+
}
|
|
106
85
|
.dropdown-dialog.position-above .dropdown-header {
|
|
107
|
-
|
|
86
|
+
margin-top: 4px;
|
|
108
87
|
}
|
|
109
|
-
|
|
110
88
|
.dropdown-dialog.position-below .dropdown-header {
|
|
111
|
-
|
|
89
|
+
margin-bottom: 4px;
|
|
112
90
|
}
|
|
113
|
-
|
|
114
91
|
.dropdown-dialog.position-below .dropdown-options {
|
|
115
|
-
|
|
92
|
+
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1), var(--ty-shadow-md);
|
|
116
93
|
}
|
|
117
|
-
|
|
118
94
|
.dropdown-dialog.position-above .dropdown-options {
|
|
119
|
-
|
|
120
|
-
|
|
95
|
+
transform: translateY(6px) scale(0.96);
|
|
96
|
+
transform-origin: bottom center;
|
|
121
97
|
}
|
|
122
|
-
|
|
123
98
|
.dropdown-dialog.open {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
99
|
+
opacity: 1;
|
|
100
|
+
scale: 1;
|
|
101
|
+
translate: 0 0;
|
|
127
102
|
}
|
|
128
|
-
|
|
129
103
|
.dropdown-dialog.open .dropdown-options {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/* Transitions never start on an element that was display:none last frame —
|
|
135
|
-
showModal() + .open land in the same frame, so the enter transition was
|
|
136
|
-
silently skipped. @starting-style supplies the first-frame "from" values
|
|
137
|
-
(this is the platform mechanism for animating dialog/top-layer entry). */
|
|
104
|
+
opacity: 1;
|
|
105
|
+
transform: translateY(0) scale(1);
|
|
106
|
+
}
|
|
138
107
|
@starting-style {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
transform: translateY(6px) scale(0.96);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
108
|
+
.dropdown-dialog.open {
|
|
109
|
+
opacity: 0;
|
|
110
|
+
scale: 0.96;
|
|
111
|
+
translate: 0 -6px;
|
|
112
|
+
}
|
|
113
|
+
.dropdown-dialog.open.position-above {
|
|
114
|
+
translate: 0 6px;
|
|
115
|
+
}
|
|
116
|
+
.dropdown-dialog.open .dropdown-options {
|
|
117
|
+
opacity: 0;
|
|
118
|
+
transform: translateY(-6px) scale(0.96);
|
|
119
|
+
}
|
|
120
|
+
.dropdown-dialog.open.position-above .dropdown-options {
|
|
121
|
+
transform: translateY(6px) scale(0.96);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
159
124
|
.dropdown-dialog::backdrop {
|
|
160
|
-
|
|
125
|
+
background: transparent;
|
|
161
126
|
}
|
|
162
|
-
|
|
163
127
|
.dropdown-header {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
128
|
+
display: flex;
|
|
129
|
+
align-items: center;
|
|
130
|
+
gap: var(--ty-spacing-2);
|
|
131
|
+
position: relative;
|
|
168
132
|
}
|
|
169
|
-
|
|
170
133
|
.dropdown-search-input {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
}
|
|
190
|
-
|
|
134
|
+
font-family: inherit;
|
|
135
|
+
width: 100%;
|
|
136
|
+
min-width: 0;
|
|
137
|
+
box-sizing: border-box;
|
|
138
|
+
background: var(--input-bg, var(--ty-input-bg));
|
|
139
|
+
color: var(--input-color, var(--ty-input-color));
|
|
140
|
+
border: 1px solid var(--input-border, var(--ty-input-border));
|
|
141
|
+
border-radius: var(--ty-radius-md);
|
|
142
|
+
font-family: inherit;
|
|
143
|
+
font-size: var(--ty-font-sm);
|
|
144
|
+
line-height: var(--ty-leading-sm);
|
|
145
|
+
letter-spacing: var(--ty-tracking-sm);
|
|
146
|
+
font-weight: var(--ty-font-normal);
|
|
147
|
+
min-height: var(--ty-size-md);
|
|
148
|
+
padding: var(--ty-spacing-2) var(--ty-spacing-3);
|
|
149
|
+
padding-right: calc(var(--ty-spacing-3) + 1rem + var(--ty-spacing-2));
|
|
150
|
+
transition: var(--ty-transition-all);
|
|
151
|
+
outline: none;
|
|
152
|
+
}
|
|
191
153
|
.dropdown-search-input:focus {
|
|
192
|
-
|
|
193
|
-
|
|
154
|
+
border-color: var(--input-border-focus, var(--ty-input-border-focus));
|
|
155
|
+
box-shadow: 0 0 0 3px var(--input-shadow-focus, var(--ty-input-shadow-focus));
|
|
194
156
|
}
|
|
195
|
-
|
|
196
157
|
.dropdown-search-input:disabled {
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
158
|
+
background-color: var(--input-disabled-bg, var(--ty-input-disabled-bg));
|
|
159
|
+
color: var(--input-disabled-color, var(--ty-input-disabled-color));
|
|
160
|
+
cursor: not-allowed;
|
|
161
|
+
opacity: 0.6;
|
|
201
162
|
}
|
|
202
|
-
|
|
203
163
|
.dropdown-search-input::placeholder {
|
|
204
|
-
|
|
164
|
+
color: var(--input-placeholder, var(--ty-input-placeholder));
|
|
205
165
|
}
|
|
206
|
-
|
|
207
166
|
.dropdown-search-chevron {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
}
|
|
218
|
-
|
|
167
|
+
position: absolute;
|
|
168
|
+
top: 50%;
|
|
169
|
+
right: var(--ty-spacing-3);
|
|
170
|
+
transform: translateY(-50%);
|
|
171
|
+
width: 1rem;
|
|
172
|
+
height: 1rem;
|
|
173
|
+
color: var(--input-placeholder, var(--ty-input-placeholder));
|
|
174
|
+
transition: var(--ty-transition-transform);
|
|
175
|
+
pointer-events: none;
|
|
176
|
+
}
|
|
219
177
|
.dropdown-search-chevron.open {
|
|
220
|
-
|
|
178
|
+
transform: translateY(-50%) rotate(180deg);
|
|
221
179
|
}
|
|
222
|
-
|
|
223
180
|
.dropdown-search-chevron svg {
|
|
224
|
-
|
|
225
|
-
|
|
181
|
+
width: 100%;
|
|
182
|
+
height: 100%;
|
|
183
|
+
}
|
|
184
|
+
.select-stub {
|
|
185
|
+
min-height: var(--ty-size-md);
|
|
186
|
+
display: flex;
|
|
187
|
+
flex-wrap: wrap;
|
|
188
|
+
gap: 0.25rem;
|
|
189
|
+
align-items: center;
|
|
190
|
+
padding: 0 2.5rem 0 0.75rem;
|
|
191
|
+
transition: var(--ty-transition-all), opacity 0.2s ease;
|
|
192
|
+
outline: none;
|
|
193
|
+
background: var(--input-bg, var(--ty-input-bg));
|
|
194
|
+
color: var(--input-color, var(--ty-input-color));
|
|
195
|
+
border: 1px solid var(--select-accent, var(--input-border, var(--ty-input-border)));
|
|
196
|
+
border-radius: var(--ty-radius-md);
|
|
197
|
+
font-family: inherit;
|
|
198
|
+
font-size: var(--ty-field-font);
|
|
199
|
+
line-height: var(--ty-field-leading);
|
|
200
|
+
letter-spacing: var(--ty-field-tracking);
|
|
201
|
+
cursor: pointer;
|
|
202
|
+
position: relative;
|
|
203
|
+
width: 100%;
|
|
204
|
+
box-sizing: border-box;
|
|
226
205
|
}
|
|
227
|
-
|
|
228
206
|
.select-stub {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
gap: 0.25rem;
|
|
233
|
-
align-items: center;
|
|
234
|
-
padding: 0 2.5rem 0 0.75rem;
|
|
235
|
-
transition: var(--ty-transition-all), opacity 0.2s ease;
|
|
236
|
-
outline: none;
|
|
237
|
-
background: var(--input-bg, var(--ty-input-bg));
|
|
238
|
-
color: var(--input-color, var(--ty-input-color));
|
|
239
|
-
border: 1px solid var(--select-accent, var(--input-border, var(--ty-input-border)));
|
|
240
|
-
border-radius: var(--ty-radius-md);
|
|
241
|
-
font-family: inherit;
|
|
242
|
-
font-size: var(--ty-font-sm);
|
|
243
|
-
line-height: var(--ty-leading-sm);
|
|
244
|
-
letter-spacing: var(--ty-tracking-sm);
|
|
245
|
-
cursor: pointer;
|
|
246
|
-
position: relative;
|
|
247
|
-
width: 100%;
|
|
248
|
-
box-sizing: border-box;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
/* buildStubClasses() always stamps exactly one size class on .select-stub.
|
|
252
|
-
min-height comes from the shared --ty-size-* tokens (same ones ty-input
|
|
253
|
-
and ty-date-picker consume) so a given size is the same height on every
|
|
254
|
-
field. Right padding stays 2.5rem for chevron room. Zero vertical
|
|
255
|
-
padding — same fix as ty-input: with align-items:center on a flex
|
|
256
|
-
container, ANY vertical padding adds on top of min-height instead of
|
|
257
|
-
being absorbed by it, so a padded stub silently overflows past the
|
|
258
|
-
shared field height (measured +3px at sm/md before this was zeroed).
|
|
259
|
-
min-height + centering alone gets the exact height. */
|
|
260
|
-
.select-stub.sm {
|
|
261
|
-
min-height: var(--ty-size-sm);
|
|
262
|
-
padding: 0 2.5rem 0 0.625rem;
|
|
263
|
-
font-size: var(--ty-font-sm);
|
|
264
|
-
line-height: var(--ty-leading-sm);
|
|
265
|
-
letter-spacing: var(--ty-tracking-sm);
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
/* md matches the base rule; listed for parity/overrides */
|
|
269
|
-
.select-stub.md {
|
|
270
|
-
min-height: var(--ty-size-md);
|
|
271
|
-
padding: 0 2.5rem 0 0.75rem;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
.select-stub.lg {
|
|
275
|
-
min-height: var(--ty-size-lg);
|
|
276
|
-
padding: 0 2.5rem 0 0.875rem;
|
|
277
|
-
font-size: var(--ty-font-base);
|
|
278
|
-
line-height: var(--ty-leading-base);
|
|
279
|
-
letter-spacing: var(--ty-tracking-base);
|
|
280
|
-
}
|
|
281
|
-
|
|
207
|
+
min-height: var(--ty-field-height);
|
|
208
|
+
padding: 0 2.5rem 0 var(--ty-field-pad-x);
|
|
209
|
+
}
|
|
282
210
|
.select-stub:hover {
|
|
283
|
-
|
|
211
|
+
border-color: var(--select-accent-bold, var(--input-border-hover, var(--ty-input-border-hover)));
|
|
284
212
|
}
|
|
285
|
-
|
|
286
213
|
.select-stub[disabled] {
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
214
|
+
background-color: var(--input-disabled-bg, var(--ty-input-disabled-bg));
|
|
215
|
+
color: var(--input-disabled-color, var(--ty-input-disabled-color));
|
|
216
|
+
cursor: not-allowed;
|
|
217
|
+
opacity: 0.6;
|
|
291
218
|
}
|
|
292
|
-
|
|
293
219
|
.dropdown-wrapper:has(.dropdown-chevron.open) .select-stub {
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
/* Open state — same escalation as ty-input's .focused: bolder border + ring.
|
|
299
|
-
Applies whenever the stub stays visible while open (field skin without
|
|
300
|
-
the opacity-hide above kicking in — e.g. single-select with no tags).
|
|
301
|
-
:not(.custom-trigger) — that skin has its own unconditional box-shadow:
|
|
302
|
-
none reset below; excluding it here keeps the two rules from competing
|
|
303
|
-
on specificity (:has()/:not() here would otherwise outrank it).
|
|
304
|
-
:not(:has(search:focus)) — the search row auto-focuses on open, which
|
|
305
|
-
already carries its own real :focus ring (below); without this guard the
|
|
306
|
-
stub's "fake" open-ring stacks on top of it, and the field reads as two
|
|
307
|
-
simultaneously-focused controls. Real focus wins; the stub ring is only
|
|
308
|
-
for select skins that have nothing else to show it. */
|
|
220
|
+
opacity: 0;
|
|
221
|
+
pointer-events: none;
|
|
222
|
+
}
|
|
309
223
|
.dropdown-wrapper:has(.dropdown-chevron.open):not(:has(.dropdown-search-input:focus)) .select-stub:not(.custom-trigger),
|
|
310
224
|
.select-stub:focus,
|
|
311
225
|
.select-stub:focus-visible {
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
/* Custom trigger (slot="trigger"): setupTriggerSlot() toggles this class when
|
|
317
|
-
the consumer assigns their own content — the slot's fallback (start/selected/
|
|
318
|
-
placeholder/end/chevron, i.e. the whole default field skin) is entirely
|
|
319
|
-
replaced at that point, so the wrapping .select-stub itself must go bare.
|
|
320
|
-
Without this, the stub's own border/background/padding and the open/focus
|
|
321
|
-
ring above still wrapped the custom content in a second, unwanted outline. */
|
|
226
|
+
border-color: var(--select-accent-bold, var(--input-border-focus, var(--ty-input-border-focus)));
|
|
227
|
+
box-shadow: 0 0 0 3px var(--select-ring, var(--input-shadow-focus, var(--ty-input-shadow-focus)));
|
|
228
|
+
}
|
|
322
229
|
.select-stub.custom-trigger {
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
230
|
+
min-height: 0;
|
|
231
|
+
padding: 0;
|
|
232
|
+
border: none;
|
|
233
|
+
background: transparent;
|
|
327
234
|
}
|
|
328
235
|
.select-stub.custom-trigger:hover,
|
|
329
236
|
.dropdown-wrapper:has(.dropdown-chevron.open) .select-stub.custom-trigger,
|
|
330
237
|
.select-stub.custom-trigger:focus,
|
|
331
238
|
.select-stub.custom-trigger:focus-visible {
|
|
332
|
-
|
|
333
|
-
|
|
239
|
+
border-color: transparent;
|
|
240
|
+
box-shadow: none;
|
|
334
241
|
}
|
|
335
|
-
|
|
336
|
-
/* Hide stub chips when mobile dialog is open (let modal show them) */
|
|
337
242
|
.dropdown-mode-mobile .dropdown-wrapper:has(.mobile-dialog[open]) .select-chips {
|
|
338
|
-
|
|
243
|
+
display: none;
|
|
339
244
|
}
|
|
340
|
-
|
|
341
|
-
/* When tags are present, reduce padding to make room */
|
|
342
245
|
.select-stub.has-tags {
|
|
343
|
-
|
|
344
|
-
|
|
246
|
+
padding: 0.25rem 2.5rem 0.25rem 0.5rem;
|
|
247
|
+
width: 100%;
|
|
345
248
|
}
|
|
346
|
-
|
|
347
249
|
.select-stub.has-tags slot[name="selected"] {
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
250
|
+
display: flex;
|
|
251
|
+
flex-wrap: wrap;
|
|
252
|
+
gap: 0.25rem;
|
|
351
253
|
}
|
|
352
|
-
|
|
353
254
|
.dropdown-chevron {
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
}
|
|
364
|
-
|
|
255
|
+
position: absolute;
|
|
256
|
+
top: 50%;
|
|
257
|
+
right: var(--ty-spacing-3);
|
|
258
|
+
transform: translateY(-50%);
|
|
259
|
+
width: 1rem;
|
|
260
|
+
height: 1rem;
|
|
261
|
+
color: var(--input-placeholder, var(--ty-input-placeholder));
|
|
262
|
+
transition: var(--ty-transition-transform);
|
|
263
|
+
pointer-events: none;
|
|
264
|
+
}
|
|
365
265
|
.dropdown-chevron.open {
|
|
366
|
-
|
|
266
|
+
transform: translateY(-50%) rotate(180deg);
|
|
367
267
|
}
|
|
368
|
-
|
|
369
268
|
.dropdown-chevron svg {
|
|
370
|
-
|
|
371
|
-
|
|
269
|
+
width: 100%;
|
|
270
|
+
height: 100%;
|
|
372
271
|
}
|
|
373
|
-
|
|
374
|
-
|
|
375
272
|
.select-chips {
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
/* No flex-grow here — the placeholder only ever renders inside .select-stub,
|
|
384
|
-
and select.ts sets flex: 1 1 0% on it. A bare flex-grow: 1 (implicit
|
|
385
|
-
flex-basis:auto) is the wrap bug that fix exists to prevent; leaving it
|
|
386
|
-
here would silently reintroduce it if the specific rule ever moved. */
|
|
273
|
+
display: flex;
|
|
274
|
+
flex-wrap: wrap;
|
|
275
|
+
gap: 0.5rem;
|
|
276
|
+
align-items: center;
|
|
277
|
+
min-width: 0;
|
|
278
|
+
}
|
|
387
279
|
.dropdown-placeholder {
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
}
|
|
395
|
-
|
|
280
|
+
color: var(--input-placeholder, var(--ty-input-placeholder, #9ca3af));
|
|
281
|
+
font-size: var(--ty-field-font);
|
|
282
|
+
line-height: var(--ty-field-leading);
|
|
283
|
+
letter-spacing: var(--ty-field-tracking);
|
|
284
|
+
font-weight: var(--ty-font-light);
|
|
285
|
+
font-style: italic;
|
|
286
|
+
}
|
|
396
287
|
.dropdown-placeholder.hidden {
|
|
397
|
-
|
|
288
|
+
display: none;
|
|
398
289
|
}
|
|
399
|
-
|
|
400
290
|
.dropdown-options {
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
opacity var(--ty-popup-duration, 180ms) var(--ty-popup-ease, cubic-bezier(0.34, 1.56, 0.64, 1)),
|
|
427
|
-
transform var(--ty-popup-duration, 180ms) var(--ty-popup-ease, cubic-bezier(0.34, 1.56, 0.64, 1));
|
|
428
|
-
|
|
429
|
-
display: flex;
|
|
430
|
-
flex-wrap: wrap;
|
|
431
|
-
padding: 0.5rem;
|
|
432
|
-
gap: 0.5rem;
|
|
433
|
-
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
/* Hide native scrollbar only when custom scrollbar is active */
|
|
291
|
+
opacity: 0;
|
|
292
|
+
background: var(--ty-surface-floating);
|
|
293
|
+
border: 1px solid var(--ty-floating-border);
|
|
294
|
+
border-radius: var(--ty-radius-lg);
|
|
295
|
+
max-height: 16rem;
|
|
296
|
+
width: 100%;
|
|
297
|
+
max-width: 100%;
|
|
298
|
+
overflow-x: hidden;
|
|
299
|
+
overflow-y: auto;
|
|
300
|
+
scroll-behavior: smooth;
|
|
301
|
+
box-sizing: border-box;
|
|
302
|
+
position: relative;
|
|
303
|
+
box-shadow:
|
|
304
|
+
0 20px 25px -5px rgba(0, 0, 0, 0.1),
|
|
305
|
+
0 10px 10px -5px rgba(0, 0, 0, 0.04);
|
|
306
|
+
transform: translateY(-6px) scale(0.96);
|
|
307
|
+
transform-origin: top center;
|
|
308
|
+
transition:
|
|
309
|
+
opacity var(--ty-popup-duration, 180ms) var(--ty-popup-ease, cubic-bezier(0.34, 1.56, 0.64, 1)),
|
|
310
|
+
transform var(--ty-popup-duration, 180ms) var(--ty-popup-ease, cubic-bezier(0.34, 1.56, 0.64, 1));
|
|
311
|
+
display: flex;
|
|
312
|
+
flex-wrap: wrap;
|
|
313
|
+
padding: 0.5rem;
|
|
314
|
+
gap: 0.5rem;
|
|
315
|
+
}
|
|
437
316
|
.dropdown-options.ty-custom-scroll {
|
|
438
|
-
|
|
439
|
-
|
|
317
|
+
scrollbar-width: none;
|
|
318
|
+
-ms-overflow-style: none;
|
|
440
319
|
}
|
|
441
|
-
|
|
442
320
|
.dropdown-options.ty-custom-scroll::-webkit-scrollbar {
|
|
443
|
-
|
|
321
|
+
display: none;
|
|
444
322
|
}
|
|
445
|
-
|
|
446
|
-
/* Options wrapper - positioned container for scrollbar track */
|
|
447
323
|
.dropdown-options-wrapper {
|
|
448
|
-
|
|
324
|
+
position: relative;
|
|
449
325
|
}
|
|
450
|
-
|
|
451
326
|
.dropdown-options-wrapper:hover .ty-scrollbar-track-y.has-overflow {
|
|
452
|
-
|
|
327
|
+
opacity: 1;
|
|
453
328
|
}
|
|
454
|
-
|
|
455
329
|
.dropdown-options ty-tag {
|
|
456
|
-
|
|
457
|
-
|
|
330
|
+
user-select: none;
|
|
331
|
+
transition: transform 0.1s ease;
|
|
458
332
|
}
|
|
459
|
-
|
|
460
333
|
.dropdown-options ty-tag:hover {
|
|
461
|
-
|
|
334
|
+
transform: scale(1.02);
|
|
462
335
|
}
|
|
463
|
-
|
|
464
336
|
.dropdown-options ty-tag:active {
|
|
465
|
-
|
|
337
|
+
transform: scale(0.98);
|
|
466
338
|
}
|
|
467
|
-
|
|
468
339
|
.dropdown-options ty-tag[selected] {
|
|
469
|
-
|
|
340
|
+
opacity: 0.5;
|
|
470
341
|
}
|
|
471
|
-
|
|
472
342
|
.select-chips ty-tag {
|
|
473
|
-
|
|
343
|
+
max-width: 150px;
|
|
474
344
|
}
|
|
475
|
-
|
|
476
345
|
@media (max-width: 640px) {
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
346
|
+
.select-chips ty-tag {
|
|
347
|
+
max-width: 100px;
|
|
348
|
+
}
|
|
480
349
|
}
|
|
481
|
-
|
|
482
|
-
|
|
483
350
|
.select-container {
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
margin-bottom (6px), same as ty-input/ty-date-picker/ty-textarea.
|
|
488
|
-
A flex gap would STACK on that margin (flex margins don't collapse),
|
|
489
|
-
which is exactly the 4px misalignment this used to cause. */
|
|
490
|
-
}
|
|
491
|
-
|
|
351
|
+
display: flex;
|
|
352
|
+
flex-direction: column;
|
|
353
|
+
}
|
|
492
354
|
.dropdown-wrapper {
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
355
|
+
position: relative;
|
|
356
|
+
display: block;
|
|
357
|
+
width: 100%;
|
|
496
358
|
}
|
|
497
|
-
|
|
498
359
|
.ty-field-label {
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
}
|
|
509
|
-
|
|
360
|
+
font-size: var(--ty-field-label-font);
|
|
361
|
+
line-height: var(--ty-field-label-leading);
|
|
362
|
+
letter-spacing: var(--ty-tracking-sm);
|
|
363
|
+
font-weight: var(--ty-font-medium);
|
|
364
|
+
color: var(--ty-label-color);
|
|
365
|
+
margin-bottom: var(--ty-field-label-gap);
|
|
366
|
+
padding-left: var(--ty-field-outer-pad-x);
|
|
367
|
+
display: flex;
|
|
368
|
+
align-items: center;
|
|
369
|
+
}
|
|
510
370
|
.required-icon {
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
}
|
|
519
|
-
|
|
371
|
+
display: inline-flex;
|
|
372
|
+
align-items: center;
|
|
373
|
+
color: #ef4444;
|
|
374
|
+
width: 12px;
|
|
375
|
+
height: 12px;
|
|
376
|
+
vertical-align: middle;
|
|
377
|
+
margin-left: 4px;
|
|
378
|
+
}
|
|
520
379
|
.required-icon svg {
|
|
521
|
-
|
|
522
|
-
|
|
380
|
+
width: 100%;
|
|
381
|
+
height: 100%;
|
|
523
382
|
}
|
|
524
|
-
|
|
525
383
|
:host([disabled]) .select-container {
|
|
526
|
-
|
|
384
|
+
pointer-events: none;
|
|
527
385
|
}
|
|
528
|
-
|
|
529
386
|
.dropdown-mode-mobile .mobile-dialog {
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
/* Note: Don't set display - browser controls <dialog> visibility */
|
|
550
|
-
align-items: flex-start;
|
|
551
|
-
justify-content: center;
|
|
552
|
-
opacity: 0;
|
|
553
|
-
transition: opacity 300ms ease;
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
/* When opened via showModal(), add flex layout */
|
|
387
|
+
position: fixed;
|
|
388
|
+
top: 0;
|
|
389
|
+
left: 0;
|
|
390
|
+
right: 0;
|
|
391
|
+
bottom: 0;
|
|
392
|
+
width: 100vw;
|
|
393
|
+
height: 100dvh;
|
|
394
|
+
max-width: 100vw;
|
|
395
|
+
max-height: 100dvh;
|
|
396
|
+
margin: 0;
|
|
397
|
+
padding: 0;
|
|
398
|
+
padding-top: 6dvh;
|
|
399
|
+
border: none;
|
|
400
|
+
background: transparent;
|
|
401
|
+
align-items: flex-start;
|
|
402
|
+
justify-content: center;
|
|
403
|
+
opacity: 0;
|
|
404
|
+
transition: opacity 300ms ease;
|
|
405
|
+
}
|
|
557
406
|
.dropdown-mode-mobile .mobile-dialog[open] {
|
|
558
|
-
|
|
407
|
+
display: flex;
|
|
559
408
|
}
|
|
560
|
-
|
|
561
409
|
.dropdown-mode-mobile .mobile-dialog.open {
|
|
562
|
-
|
|
410
|
+
opacity: 1;
|
|
563
411
|
}
|
|
564
|
-
|
|
565
|
-
/* Native dialog backdrop with blur */
|
|
566
412
|
.dropdown-mode-mobile .mobile-dialog::backdrop {
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
backdrop-filter: blur(8px);
|
|
571
|
-
-webkit-backdrop-filter: blur(8px);
|
|
413
|
+
background: rgba(0, 0, 0, 0.65);
|
|
414
|
+
backdrop-filter: blur(8px);
|
|
415
|
+
-webkit-backdrop-filter: blur(8px);
|
|
572
416
|
}
|
|
573
|
-
|
|
574
417
|
.dropdown-mode-mobile .mobile-dialog-content {
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
}
|
|
588
|
-
|
|
418
|
+
position: relative;
|
|
419
|
+
display: flex;
|
|
420
|
+
flex-direction: column;
|
|
421
|
+
width: calc(100% - 32px);
|
|
422
|
+
max-width: 400px;
|
|
423
|
+
min-height: 200px;
|
|
424
|
+
max-height: 90dvh;
|
|
425
|
+
opacity: 0;
|
|
426
|
+
transform: scale(0.95);
|
|
427
|
+
transition:
|
|
428
|
+
opacity 300ms cubic-bezier(0.16, 1, 0.3, 1),
|
|
429
|
+
transform 300ms cubic-bezier(0.16, 1, 0.3, 1);
|
|
430
|
+
}
|
|
589
431
|
.dropdown-mode-mobile .mobile-dialog.open .mobile-dialog-content {
|
|
590
|
-
|
|
591
|
-
|
|
432
|
+
opacity: 1;
|
|
433
|
+
transform: scale(1);
|
|
592
434
|
}
|
|
593
|
-
|
|
594
435
|
.dropdown-mode-mobile .mobile-search-input:focus {
|
|
595
|
-
|
|
436
|
+
border-color: var(--ty-border);
|
|
596
437
|
}
|
|
597
|
-
|
|
598
|
-
/* Mobile search header - label floats above, search + close below */
|
|
599
438
|
.dropdown-mode-mobile .mobile-search-header {
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
}
|
|
608
|
-
|
|
439
|
+
flex-shrink: 0;
|
|
440
|
+
display: flex;
|
|
441
|
+
flex-direction: column;
|
|
442
|
+
margin-bottom: 16px;
|
|
443
|
+
padding: 0;
|
|
444
|
+
background: transparent;
|
|
445
|
+
position: relative;
|
|
446
|
+
}
|
|
609
447
|
.dropdown-mode-mobile .mobile-header-content {
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
without this it falls back to flex-start and strands the button on the
|
|
617
|
-
left. Harmless when search IS shown: the input's flex:1 already
|
|
618
|
-
consumes all remaining space, so justify-content never gets a say. */
|
|
619
|
-
justify-content: flex-end;
|
|
620
|
-
}
|
|
621
|
-
|
|
448
|
+
display: flex;
|
|
449
|
+
align-items: center;
|
|
450
|
+
gap: 12px;
|
|
451
|
+
width: 100%;
|
|
452
|
+
justify-content: flex-end;
|
|
453
|
+
}
|
|
622
454
|
.dropdown-mode-mobile .mobile-header-label {
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
a dark blurred backdrop is the wrong combination. Fixed white, same
|
|
635
|
-
reasoning as ty-tooltip's deliberately theme-independent default in
|
|
636
|
-
tyrell.css — this element's job is to pop against a dark backdrop in
|
|
637
|
-
both themes, not to track the page's light/dark state. */
|
|
638
|
-
color: #ffffff;
|
|
639
|
-
pointer-events: none;
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
/* Close button — borderless ghost icon button (was a bordered circle badge,
|
|
643
|
-
which read as a heavy, disconnected "chip" next to the plain search icon).
|
|
644
|
-
Matches ty-button's ghost treatment: transparent at rest, soft neutral
|
|
645
|
-
fill on hover/active, no border ever. */
|
|
455
|
+
position: absolute;
|
|
456
|
+
bottom: 100%;
|
|
457
|
+
left: 2px;
|
|
458
|
+
margin-bottom: 8px;
|
|
459
|
+
font-size: var(--ty-font-base);
|
|
460
|
+
line-height: var(--ty-leading-base);
|
|
461
|
+
letter-spacing: var(--ty-tracking-base);
|
|
462
|
+
font-weight: 600;
|
|
463
|
+
color: #ffffff;
|
|
464
|
+
pointer-events: none;
|
|
465
|
+
}
|
|
646
466
|
.dropdown-mode-mobile .mobile-close-button {
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
transition: var(--ty-transition-all);
|
|
662
|
-
padding: 0;
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
/* Hover/active fills also go fixed-white-tinted rather than theme neutral —
|
|
666
|
-
--ty-bg-neutral-soft is a LIGHT fill in light mode, which would swallow
|
|
667
|
-
the white icon it's meant to sit behind. */
|
|
467
|
+
flex-shrink: 0;
|
|
468
|
+
width: 32px;
|
|
469
|
+
height: 32px;
|
|
470
|
+
display: flex;
|
|
471
|
+
align-items: center;
|
|
472
|
+
justify-content: center;
|
|
473
|
+
background: transparent;
|
|
474
|
+
border: none;
|
|
475
|
+
border-radius: 50%;
|
|
476
|
+
color: #ffffff;
|
|
477
|
+
cursor: pointer;
|
|
478
|
+
transition: var(--ty-transition-all);
|
|
479
|
+
padding: 0;
|
|
480
|
+
}
|
|
668
481
|
.dropdown-mode-mobile .mobile-close-button:hover {
|
|
669
|
-
|
|
670
|
-
|
|
482
|
+
background: rgba(255, 255, 255, 0.15);
|
|
483
|
+
color: #ffffff;
|
|
671
484
|
}
|
|
672
|
-
|
|
673
485
|
.dropdown-mode-mobile .mobile-close-button:active {
|
|
674
|
-
|
|
675
|
-
|
|
486
|
+
transform: scale(0.9);
|
|
487
|
+
background: rgba(255, 255, 255, 0.25);
|
|
676
488
|
}
|
|
677
|
-
|
|
678
489
|
.dropdown-mode-mobile .mobile-close-button svg {
|
|
679
|
-
|
|
680
|
-
|
|
490
|
+
width: 18px;
|
|
491
|
+
height: 18px;
|
|
681
492
|
}
|
|
682
|
-
|
|
683
493
|
.dropdown-mode-mobile .mobile-search-input {
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
}
|
|
703
|
-
|
|
494
|
+
font-family: inherit;
|
|
495
|
+
flex: 1;
|
|
496
|
+
min-width: 0;
|
|
497
|
+
box-sizing: border-box;
|
|
498
|
+
background: var(--ty-surface-floating);
|
|
499
|
+
color: var(--ty-text);
|
|
500
|
+
border: 2px solid;
|
|
501
|
+
border-color: var(--mobile-border-color);
|
|
502
|
+
border-radius: var(--ty-radius-md);
|
|
503
|
+
font-family: inherit;
|
|
504
|
+
font-size: var(--ty-font-sm);
|
|
505
|
+
line-height: var(--ty-leading-sm);
|
|
506
|
+
letter-spacing: var(--ty-tracking-sm);
|
|
507
|
+
font-weight: var(--ty-font-normal);
|
|
508
|
+
padding: var(--ty-spacing-2) var(--ty-spacing-3);
|
|
509
|
+
height: 40px;
|
|
510
|
+
transition: var(--ty-transition-all);
|
|
511
|
+
outline: none;
|
|
512
|
+
}
|
|
704
513
|
.dropdown-mode-mobile .mobile-search-input::placeholder {
|
|
705
|
-
|
|
514
|
+
color: var(--ty-text-faint);
|
|
706
515
|
}
|
|
707
|
-
|
|
708
516
|
.dropdown-mode-mobile .mobile-search-input:focus {
|
|
709
|
-
|
|
517
|
+
border-color: var(--ty-border);
|
|
710
518
|
}
|
|
711
|
-
|
|
712
|
-
/* Mobile body - contains both sections */
|
|
713
519
|
.dropdown-mode-mobile .mobile-body {
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
/* Section headers are labels, not buttons */
|
|
730
|
-
|
|
520
|
+
position: relative;
|
|
521
|
+
display: flex;
|
|
522
|
+
flex-direction: column;
|
|
523
|
+
height: var(--body-height, 350px);
|
|
524
|
+
max-height: 350px;
|
|
525
|
+
overflow: hidden;
|
|
526
|
+
background: var(--ty-surface-floating);
|
|
527
|
+
border-radius: var(--ty-radius-lg);
|
|
528
|
+
box-shadow:
|
|
529
|
+
0 20px 25px -5px rgba(0, 0, 0, 0.1),
|
|
530
|
+
0 10px 10px -5px rgba(0, 0, 0, 0.04);
|
|
531
|
+
border: 2px solid;
|
|
532
|
+
border-color: var(--mobile-border-color);
|
|
533
|
+
}
|
|
731
534
|
.dropdown-mode-mobile .section-header {
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
}
|
|
747
|
-
|
|
535
|
+
display: flex;
|
|
536
|
+
align-items: center;
|
|
537
|
+
justify-content: space-between;
|
|
538
|
+
height: 36px;
|
|
539
|
+
flex-shrink: 0;
|
|
540
|
+
padding: 0 16px;
|
|
541
|
+
font-size: 11px;
|
|
542
|
+
font-weight: 600;
|
|
543
|
+
text-transform: uppercase;
|
|
544
|
+
letter-spacing: 0.06em;
|
|
545
|
+
color: var(--ty-text-bold);
|
|
546
|
+
background: transparent;
|
|
547
|
+
cursor: default;
|
|
548
|
+
user-select: none;
|
|
549
|
+
}
|
|
748
550
|
.dropdown-mode-mobile .section-header .section-title {
|
|
749
|
-
|
|
551
|
+
flex: 1;
|
|
750
552
|
}
|
|
751
|
-
|
|
752
553
|
.dropdown-mode-mobile .section-header .section-count {
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
554
|
+
font-weight: 500;
|
|
555
|
+
color: var(--ty-text-faint);
|
|
556
|
+
margin-left: 0.25rem;
|
|
756
557
|
}
|
|
757
|
-
|
|
758
|
-
/* Selected strip: pinned, capped height, collapses when empty */
|
|
759
|
-
|
|
760
558
|
.dropdown-mode-mobile .mobile-selected-section {
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
}
|
|
769
|
-
|
|
770
|
-
/* Empty: collapse to header only */
|
|
559
|
+
display: flex;
|
|
560
|
+
flex-direction: column;
|
|
561
|
+
background: var(--ty-input-bg);
|
|
562
|
+
overflow: hidden;
|
|
563
|
+
flex: 0 0 auto;
|
|
564
|
+
max-height: 40%;
|
|
565
|
+
transition: max-height 200ms cubic-bezier(0.4, 0, 0.2, 1);
|
|
566
|
+
}
|
|
771
567
|
.dropdown-mode-mobile .mobile-selected-section[data-empty="true"] {
|
|
772
|
-
|
|
773
|
-
|
|
568
|
+
max-height: 36px;
|
|
569
|
+
flex: 0 0 36px;
|
|
774
570
|
}
|
|
775
|
-
|
|
776
571
|
.dropdown-mode-mobile .mobile-selected-section .section-content {
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
}
|
|
790
|
-
|
|
791
|
-
/* Available list takes the remaining space */
|
|
792
|
-
|
|
572
|
+
flex: 1;
|
|
573
|
+
min-height: 0;
|
|
574
|
+
overflow-y: auto;
|
|
575
|
+
overscroll-behavior: contain;
|
|
576
|
+
padding: 0.75rem 1rem;
|
|
577
|
+
display: flex;
|
|
578
|
+
flex-wrap: wrap;
|
|
579
|
+
gap: 0.5rem;
|
|
580
|
+
align-content: flex-start;
|
|
581
|
+
-webkit-mask-image: linear-gradient(to bottom, black calc(100% - 12px), transparent);
|
|
582
|
+
mask-image: linear-gradient(to bottom, black calc(100% - 12px), transparent);
|
|
583
|
+
}
|
|
793
584
|
.dropdown-mode-mobile .mobile-available-section {
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
}
|
|
801
|
-
|
|
585
|
+
display: flex;
|
|
586
|
+
flex-direction: column;
|
|
587
|
+
background: var(--ty-input-bg);
|
|
588
|
+
overflow: hidden;
|
|
589
|
+
flex: 1 1 auto;
|
|
590
|
+
min-height: 0;
|
|
591
|
+
}
|
|
802
592
|
.dropdown-mode-mobile .mobile-available-section .section-content {
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
}
|
|
813
|
-
|
|
814
|
-
/* Selected strip collapses (no text needed).
|
|
815
|
-
Available shows the empty message only when there are zero tags total. */
|
|
816
|
-
|
|
593
|
+
flex: 1;
|
|
594
|
+
min-height: 0;
|
|
595
|
+
overflow-y: auto;
|
|
596
|
+
overscroll-behavior: contain;
|
|
597
|
+
padding: 0.75rem 1rem;
|
|
598
|
+
display: flex;
|
|
599
|
+
flex-wrap: wrap;
|
|
600
|
+
gap: 0.5rem;
|
|
601
|
+
align-content: flex-start;
|
|
602
|
+
}
|
|
817
603
|
.dropdown-mode-mobile .empty-state {
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
}
|
|
828
|
-
|
|
604
|
+
display: none;
|
|
605
|
+
width: 100%;
|
|
606
|
+
padding: 2rem 1rem;
|
|
607
|
+
text-align: center;
|
|
608
|
+
color: var(--ty-text-faint);
|
|
609
|
+
font-size: var(--ty-font-sm);
|
|
610
|
+
line-height: var(--ty-leading-sm);
|
|
611
|
+
letter-spacing: var(--ty-tracking-sm);
|
|
612
|
+
font-style: italic;
|
|
613
|
+
}
|
|
829
614
|
.dropdown-mode-mobile .mobile-available-section[data-empty="true"] .empty-state {
|
|
830
|
-
|
|
615
|
+
display: block;
|
|
831
616
|
}
|
|
832
|
-
|
|
833
617
|
.dropdown-mode-mobile .mobile-selected-section[data-empty="true"] .section-content,
|
|
834
618
|
.dropdown-mode-mobile .mobile-available-section[data-empty="true"] slot {
|
|
835
|
-
|
|
619
|
+
display: none;
|
|
836
620
|
}
|
|
837
|
-
|
|
838
621
|
.dropdown-mode-mobile .section-content ::slotted(ty-tag) {
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
animation: ty-select-tag-enter 180ms cubic-bezier(0.16, 1, 0.3, 1);
|
|
846
|
-
}
|
|
847
|
-
|
|
622
|
+
cursor: pointer;
|
|
623
|
+
user-select: none;
|
|
624
|
+
transition: transform 0.1s ease;
|
|
625
|
+
margin: 2px 0;
|
|
626
|
+
animation: ty-select-tag-enter 180ms cubic-bezier(0.16, 1, 0.3, 1);
|
|
627
|
+
}
|
|
848
628
|
@media (hover: hover) {
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
629
|
+
.dropdown-mode-mobile .section-content ::slotted(ty-tag:hover) {
|
|
630
|
+
transform: scale(1.02);
|
|
631
|
+
}
|
|
852
632
|
}
|
|
853
|
-
|
|
854
633
|
.dropdown-mode-mobile .section-content ::slotted(ty-tag:active) {
|
|
855
|
-
|
|
634
|
+
transform: scale(0.96);
|
|
856
635
|
}
|
|
857
|
-
|
|
858
636
|
.dropdown-mode-mobile .section-content ::slotted(ty-tag[hidden]) {
|
|
859
|
-
|
|
637
|
+
display: none !important;
|
|
860
638
|
}
|
|
861
|
-
|
|
862
639
|
@keyframes ty-select-tag-enter {
|
|
863
|
-
|
|
864
|
-
|
|
640
|
+
from { opacity: 0; transform: scale(0.85); }
|
|
641
|
+
to { opacity: 1; transform: scale(1); }
|
|
865
642
|
}
|
|
866
|
-
|
|
867
643
|
@media (prefers-reduced-motion: reduce) {
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
}
|
|
872
|
-
|
|
873
|
-
/* Spinner overlay shown inside the options area while the parent
|
|
874
|
-
(external-search mode) is fetching. Search input stays usable.
|
|
875
|
-
|
|
876
|
-
Carries its own surface so it stays visible even when the host
|
|
877
|
-
has restyled the popup with a transparent or unusual background.
|
|
878
|
-
Override with --ty-loader-bg / --ty-loader-radius / --ty-loader-border.
|
|
879
|
-
*/
|
|
644
|
+
.dropdown-mode-mobile .section-content ::slotted(ty-tag) {
|
|
645
|
+
animation: none;
|
|
646
|
+
}
|
|
647
|
+
}
|
|
880
648
|
.dropdown-loading {
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
}
|
|
896
|
-
|
|
649
|
+
display: none;
|
|
650
|
+
align-items: center;
|
|
651
|
+
justify-content: center;
|
|
652
|
+
gap: var(--ty-spacing-2);
|
|
653
|
+
padding: var(--ty-spacing-4) var(--ty-spacing-3);
|
|
654
|
+
color: var(--ty-text-soft);
|
|
655
|
+
font-size: var(--ty-font-sm);
|
|
656
|
+
min-height: 4rem;
|
|
657
|
+
background: var(--ty-loader-bg, var(--ty-surface-floating));
|
|
658
|
+
border: 1px solid var(--ty-loader-border, var(--ty-floating-border));
|
|
659
|
+
border-radius: var(--ty-loader-radius, var(--ty-radius-lg));
|
|
660
|
+
box-shadow: var(--ty-loader-shadow, 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04));
|
|
661
|
+
box-sizing: border-box;
|
|
662
|
+
}
|
|
897
663
|
.dropdown-options-wrapper.loading .dropdown-loading {
|
|
898
|
-
|
|
664
|
+
display: flex;
|
|
899
665
|
}
|
|
900
|
-
|
|
901
|
-
/* Slot is transparent for layout — fallback (spinner + text) and user-provided
|
|
902
|
-
slotted content both act as direct flex children of .dropdown-loading. */
|
|
903
666
|
.dropdown-loading > slot[name="loading"] {
|
|
904
|
-
|
|
667
|
+
display: contents;
|
|
905
668
|
}
|
|
906
|
-
|
|
907
|
-
/* Mobile: full-screen dialog is the surface — drop the card chrome,
|
|
908
|
-
stack vertically, scale up so it feels native to a fullscreen view.
|
|
909
|
-
Slotted content adapts automatically since the slot is display:contents. */
|
|
910
669
|
.dropdown-mode-mobile .dropdown-loading {
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
}
|
|
920
|
-
|
|
670
|
+
background: transparent;
|
|
671
|
+
border: none;
|
|
672
|
+
box-shadow: none;
|
|
673
|
+
flex: 1;
|
|
674
|
+
flex-direction: column;
|
|
675
|
+
gap: var(--ty-spacing-3);
|
|
676
|
+
padding: var(--ty-spacing-8) var(--ty-spacing-4);
|
|
677
|
+
min-height: 12rem;
|
|
678
|
+
}
|
|
921
679
|
.dropdown-mode-mobile .dropdown-loading-spinner {
|
|
922
|
-
|
|
923
|
-
|
|
680
|
+
width: 2rem;
|
|
681
|
+
height: 2rem;
|
|
924
682
|
}
|
|
925
|
-
|
|
926
683
|
.dropdown-mode-mobile .dropdown-loading-text {
|
|
927
|
-
|
|
684
|
+
font-size: var(--ty-font-base);
|
|
928
685
|
}
|
|
929
|
-
|
|
930
686
|
.dropdown-options-wrapper.loading .dropdown-options,
|
|
931
687
|
.dropdown-options-wrapper.loading > slot#options-slot,
|
|
932
688
|
.dropdown-options-wrapper.loading .empty-state {
|
|
933
|
-
|
|
689
|
+
display: none;
|
|
934
690
|
}
|
|
935
|
-
|
|
936
691
|
.dropdown-loading-spinner {
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
}
|
|
947
|
-
|
|
692
|
+
display: inline-flex;
|
|
693
|
+
align-items: center;
|
|
694
|
+
justify-content: center;
|
|
695
|
+
width: 1.125rem;
|
|
696
|
+
height: 1.125rem;
|
|
697
|
+
flex-shrink: 0;
|
|
698
|
+
animation: ty-select-spin 0.7s linear infinite;
|
|
699
|
+
color: var(--select-accent-bold, var(--ty-color-primary));
|
|
700
|
+
}
|
|
948
701
|
.dropdown-loading-spinner svg {
|
|
949
|
-
|
|
950
|
-
|
|
702
|
+
width: 100%;
|
|
703
|
+
height: 100%;
|
|
951
704
|
}
|
|
952
|
-
|
|
953
705
|
.dropdown-loading-text {
|
|
954
|
-
|
|
706
|
+
color: var(--ty-text-soft);
|
|
955
707
|
}
|
|
956
|
-
|
|
957
708
|
@keyframes ty-select-spin {
|
|
958
|
-
|
|
709
|
+
to { transform: rotate(360deg); }
|
|
959
710
|
}
|
|
960
|
-
|
|
961
711
|
@media (prefers-reduced-motion: reduce) {
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
712
|
+
.dropdown-loading-spinner {
|
|
713
|
+
animation-duration: 1.6s;
|
|
714
|
+
}
|
|
965
715
|
}
|
|
966
|
-
|
|
967
716
|
${customScrollbarStyles}
|
|
968
|
-
|
|
969
|
-
/* Flavor variants set --select-accent*, consumed above */
|
|
970
717
|
${FLAVORS.filter((f) => f !== "neutral").map((f) => selectFlavor(f)).join("")}
|
|
971
718
|
`;
|