@finsweet/webflow-apps-utils 1.0.28 → 1.0.29
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/dist/ui/components/index.d.ts +1 -0
- package/dist/ui/components/index.js +1 -0
- package/dist/ui/components/regions/RegionSelector.stories.svelte +383 -0
- package/dist/ui/components/regions/RegionSelector.stories.svelte.d.ts +19 -0
- package/dist/ui/components/regions/RegionSelector.svelte +1110 -0
- package/dist/ui/components/regions/RegionSelector.svelte.d.ts +4 -0
- package/dist/ui/components/regions/index.d.ts +2 -0
- package/dist/ui/components/regions/index.js +2 -0
- package/dist/ui/components/regions/types.d.ts +32 -0
- package/dist/ui/components/regions/types.js +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,1110 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { SvelteSet } from 'svelte/reactivity';
|
|
3
|
+
|
|
4
|
+
import { Checkbox } from '../checkbox';
|
|
5
|
+
import type { ExtendedRegionGroup, Region, RegionGroup, RegionSelectorProps } from './types.js';
|
|
6
|
+
|
|
7
|
+
let {
|
|
8
|
+
regionGroups,
|
|
9
|
+
selectedRegions = [],
|
|
10
|
+
onRegionsChange,
|
|
11
|
+
usedRegions = {
|
|
12
|
+
regions: new Set(),
|
|
13
|
+
isGlobalUsed: false,
|
|
14
|
+
isEUGroupUsed: false,
|
|
15
|
+
byInstance: new Map()
|
|
16
|
+
},
|
|
17
|
+
isLoading = false,
|
|
18
|
+
error,
|
|
19
|
+
maxVisibleBadges = 2,
|
|
20
|
+
searchPlaceholder = 'Search regions...',
|
|
21
|
+
class: className = '',
|
|
22
|
+
...restProps
|
|
23
|
+
}: RegionSelectorProps = $props();
|
|
24
|
+
|
|
25
|
+
let searchQuery = $state('');
|
|
26
|
+
let tempSelectedRegions = $state<string[]>([...selectedRegions]);
|
|
27
|
+
let expandedGroups = new SvelteSet<string>();
|
|
28
|
+
let previousSelectedRegions = $state<string[]>([...selectedRegions]);
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Sync with prop changes and trigger callback
|
|
32
|
+
*/
|
|
33
|
+
$effect(() => {
|
|
34
|
+
// Sync from prop to internal state when prop changes externally
|
|
35
|
+
if (JSON.stringify(selectedRegions) !== JSON.stringify(previousSelectedRegions)) {
|
|
36
|
+
tempSelectedRegions = [...selectedRegions];
|
|
37
|
+
previousSelectedRegions = [...selectedRegions];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Trigger callback when internal state changes
|
|
41
|
+
if (JSON.stringify(tempSelectedRegions) !== JSON.stringify(selectedRegions)) {
|
|
42
|
+
onRegionsChange?.(tempSelectedRegions);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
let restructuredGroups = $derived.by((): ExtendedRegionGroup[] => {
|
|
47
|
+
const globalGroup = regionGroups.find((g) => g.regions.some((r) => r.code === 'Global'));
|
|
48
|
+
const euGroup = regionGroups.find(
|
|
49
|
+
(g) => g.key.toLowerCase().includes('eu') || g.name.toLowerCase().includes('european')
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
const usGroup = regionGroups.find(
|
|
53
|
+
(g) => g.key === 'us' || g.name.toLowerCase() === 'united states'
|
|
54
|
+
);
|
|
55
|
+
const otherCountries = regionGroups.filter(
|
|
56
|
+
(g) =>
|
|
57
|
+
g !== globalGroup &&
|
|
58
|
+
g !== euGroup &&
|
|
59
|
+
g !== usGroup &&
|
|
60
|
+
!g.regions.some((r) => r.code === 'Global')
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
const mainGroups: ExtendedRegionGroup[] = [];
|
|
64
|
+
|
|
65
|
+
if (globalGroup) {
|
|
66
|
+
mainGroups.push({
|
|
67
|
+
...globalGroup,
|
|
68
|
+
isMainParent: true,
|
|
69
|
+
parentKey: 'global-parent'
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (euGroup) {
|
|
74
|
+
mainGroups.push({
|
|
75
|
+
...euGroup,
|
|
76
|
+
isMainParent: true,
|
|
77
|
+
parentKey: 'eu-parent'
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (otherCountries.length > 0 || usGroup) {
|
|
82
|
+
const selectCountriesRegions: Region[] = [];
|
|
83
|
+
const selectCountriesSubGroups: RegionGroup[] = [];
|
|
84
|
+
|
|
85
|
+
if (usGroup) {
|
|
86
|
+
selectCountriesSubGroups.push(usGroup);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
otherCountries.forEach((group) => {
|
|
90
|
+
selectCountriesRegions.push(...group.regions);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
mainGroups.push({
|
|
94
|
+
name: 'Select Countries',
|
|
95
|
+
key: 'select-countries-parent',
|
|
96
|
+
regions: selectCountriesRegions,
|
|
97
|
+
total: selectCountriesRegions.length + (usGroup ? usGroup.total : 0),
|
|
98
|
+
isMainParent: true,
|
|
99
|
+
parentKey: 'select-countries-parent',
|
|
100
|
+
subGroups: selectCountriesSubGroups
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return mainGroups;
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
let selectedMainParent = $derived.by(() => {
|
|
108
|
+
if (tempSelectedRegions.includes('Global')) return 'global-parent';
|
|
109
|
+
|
|
110
|
+
if (tempSelectedRegions.includes('EU')) {
|
|
111
|
+
return 'eu-parent';
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const selectCountriesGroup = restructuredGroups.find(
|
|
115
|
+
(g) => g.parentKey === 'select-countries-parent'
|
|
116
|
+
);
|
|
117
|
+
if (selectCountriesGroup) {
|
|
118
|
+
const hasAnySelected =
|
|
119
|
+
selectCountriesGroup.regions.some((r) => tempSelectedRegions.includes(r.code)) ||
|
|
120
|
+
selectCountriesGroup.subGroups?.some((sg) =>
|
|
121
|
+
sg.regions.some((r) => tempSelectedRegions.includes(r.code))
|
|
122
|
+
);
|
|
123
|
+
if (hasAnySelected) return 'select-countries-parent';
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return null;
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
let isGlobalSelected = $derived(tempSelectedRegions.includes('Global'));
|
|
130
|
+
|
|
131
|
+
let filteredGroups = $derived.by(() => {
|
|
132
|
+
if (!searchQuery) return restructuredGroups;
|
|
133
|
+
|
|
134
|
+
const filtered = restructuredGroups
|
|
135
|
+
.map((group) => {
|
|
136
|
+
const filteredRegions = group.regions.filter(
|
|
137
|
+
(region) =>
|
|
138
|
+
region.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
|
139
|
+
region.code.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
|
140
|
+
group.name.toLowerCase().includes(searchQuery.toLowerCase())
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
const filteredSubGroups = group.subGroups
|
|
144
|
+
?.map((subGroup) => ({
|
|
145
|
+
...subGroup,
|
|
146
|
+
regions: subGroup.regions.filter(
|
|
147
|
+
(region) =>
|
|
148
|
+
region.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
|
149
|
+
region.code.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
|
150
|
+
subGroup.name.toLowerCase().includes(searchQuery.toLowerCase())
|
|
151
|
+
)
|
|
152
|
+
}))
|
|
153
|
+
.filter((sg) => sg.regions.length > 0);
|
|
154
|
+
|
|
155
|
+
return {
|
|
156
|
+
...group,
|
|
157
|
+
regions: filteredRegions,
|
|
158
|
+
subGroups: filteredSubGroups
|
|
159
|
+
};
|
|
160
|
+
})
|
|
161
|
+
.filter(
|
|
162
|
+
(group) => group.regions.length > 0 || (group.subGroups && group.subGroups.length > 0)
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
return filtered;
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Auto-expand groups when searching
|
|
170
|
+
*/
|
|
171
|
+
$effect(() => {
|
|
172
|
+
if (searchQuery) {
|
|
173
|
+
// Clear first
|
|
174
|
+
expandedGroups.clear();
|
|
175
|
+
|
|
176
|
+
restructuredGroups.forEach((group) => {
|
|
177
|
+
// Check if this group has matching content
|
|
178
|
+
const hasMatchingRegions = group.regions.some(
|
|
179
|
+
(region) =>
|
|
180
|
+
region.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
|
181
|
+
region.code.toLowerCase().includes(searchQuery.toLowerCase())
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
const hasMatchingSubGroups = group.subGroups?.some((sg) =>
|
|
185
|
+
sg.regions.some(
|
|
186
|
+
(region) =>
|
|
187
|
+
region.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
|
188
|
+
region.code.toLowerCase().includes(searchQuery.toLowerCase())
|
|
189
|
+
)
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
if (hasMatchingRegions || hasMatchingSubGroups) {
|
|
193
|
+
expandedGroups.add(group.key);
|
|
194
|
+
group.subGroups?.forEach((sg) => {
|
|
195
|
+
const sgHasMatching = sg.regions.some(
|
|
196
|
+
(region) =>
|
|
197
|
+
region.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
|
198
|
+
region.code.toLowerCase().includes(searchQuery.toLowerCase())
|
|
199
|
+
);
|
|
200
|
+
if (sgHasMatching) {
|
|
201
|
+
expandedGroups.add(sg.key);
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
let tempSelectedRegionObjects = $derived.by(() => {
|
|
210
|
+
const selected: Region[] = [];
|
|
211
|
+
|
|
212
|
+
if (tempSelectedRegions.includes('Global')) {
|
|
213
|
+
const globalGroup = regionGroups.find((g) => g.regions.some((r) => r.code === 'Global'));
|
|
214
|
+
const globalRegion = globalGroup?.regions.find((r) => r.code === 'Global');
|
|
215
|
+
if (globalRegion) {
|
|
216
|
+
selected.push(globalRegion);
|
|
217
|
+
}
|
|
218
|
+
} else if (tempSelectedRegions.includes('EU')) {
|
|
219
|
+
const euGroup = regionGroups.find((g) => g.key === 'europe');
|
|
220
|
+
if (euGroup) {
|
|
221
|
+
selected.push({
|
|
222
|
+
code: 'EU',
|
|
223
|
+
name: euGroup.name
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
} else {
|
|
227
|
+
const allRegions = regionGroups.flatMap((g) => g.regions);
|
|
228
|
+
tempSelectedRegions.forEach((code) => {
|
|
229
|
+
const region = allRegions.find((r) => r.code === code);
|
|
230
|
+
if (region) {
|
|
231
|
+
selected.push(region);
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return selected;
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
let visibleBadges = $derived(tempSelectedRegionObjects.slice(0, maxVisibleBadges));
|
|
240
|
+
let remainingBadgesCount = $derived(
|
|
241
|
+
Math.max(0, tempSelectedRegionObjects.length - maxVisibleBadges)
|
|
242
|
+
);
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Toggle group expansion
|
|
246
|
+
*/
|
|
247
|
+
const toggleGroupExpansion = (groupKey: string) => {
|
|
248
|
+
if (expandedGroups.has(groupKey)) {
|
|
249
|
+
expandedGroups.delete(groupKey);
|
|
250
|
+
} else {
|
|
251
|
+
expandedGroups.add(groupKey);
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Check if group is expanded
|
|
257
|
+
*/
|
|
258
|
+
const isGroupExpanded = (groupKey: string): boolean => {
|
|
259
|
+
return expandedGroups.has(groupKey);
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Toggle region selection
|
|
264
|
+
*/
|
|
265
|
+
const toggleRegion = (code: string) => {
|
|
266
|
+
if (code === 'Global') {
|
|
267
|
+
if (tempSelectedRegions.includes('Global')) {
|
|
268
|
+
tempSelectedRegions = [];
|
|
269
|
+
} else {
|
|
270
|
+
// Clear all and select only Global
|
|
271
|
+
tempSelectedRegions = ['Global'];
|
|
272
|
+
}
|
|
273
|
+
} else if (code === 'EU') {
|
|
274
|
+
if (tempSelectedRegions.includes('EU')) {
|
|
275
|
+
tempSelectedRegions = [];
|
|
276
|
+
} else {
|
|
277
|
+
// Clear all and select only EU
|
|
278
|
+
tempSelectedRegions = ['EU'];
|
|
279
|
+
}
|
|
280
|
+
} else {
|
|
281
|
+
// Selecting a country - clear Global and EU
|
|
282
|
+
const filteredRegions = tempSelectedRegions.filter((c) => c !== 'Global' && c !== 'EU');
|
|
283
|
+
|
|
284
|
+
if (filteredRegions.includes(code)) {
|
|
285
|
+
tempSelectedRegions = filteredRegions.filter((c) => c !== code);
|
|
286
|
+
} else {
|
|
287
|
+
tempSelectedRegions = [...filteredRegions, code];
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Remove region from selection
|
|
294
|
+
*/
|
|
295
|
+
const removeRegion = (code: string) => {
|
|
296
|
+
if (code === 'Global' || code === 'EU') {
|
|
297
|
+
tempSelectedRegions = [];
|
|
298
|
+
} else {
|
|
299
|
+
tempSelectedRegions = tempSelectedRegions.filter(
|
|
300
|
+
(c) => c !== code && c !== 'Global' && c !== 'EU'
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
onRegionsChange?.(tempSelectedRegions);
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Clear all selections
|
|
308
|
+
*/
|
|
309
|
+
const clearAll = () => {
|
|
310
|
+
tempSelectedRegions = [];
|
|
311
|
+
onRegionsChange?.([]);
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Check if all group regions are in use
|
|
316
|
+
*/
|
|
317
|
+
const areAllGroupRegionsInUse = (group: RegionGroup): boolean => {
|
|
318
|
+
return group.regions.every((region) => usedRegions.regions.has(region.code));
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Check if all group and sub-group regions are in use
|
|
323
|
+
*/
|
|
324
|
+
const areAllGroupAndSubGroupRegionsInUse = (group: ExtendedRegionGroup): boolean => {
|
|
325
|
+
const mainRegionsInUse = group.regions.every((region) => usedRegions.regions.has(region.code));
|
|
326
|
+
|
|
327
|
+
if (!group.subGroups || group.subGroups.length === 0) {
|
|
328
|
+
return mainRegionsInUse;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
const allSubGroupsInUse = group.subGroups.every((subGroup) =>
|
|
332
|
+
areAllGroupRegionsInUse(subGroup)
|
|
333
|
+
);
|
|
334
|
+
|
|
335
|
+
return mainRegionsInUse && allSubGroupsInUse;
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Check if all group regions are selected
|
|
340
|
+
*/
|
|
341
|
+
const isGroupFullySelected = (group: RegionGroup): boolean => {
|
|
342
|
+
return group.regions.every((region) => tempSelectedRegions.includes(region.code));
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Check if some group regions are selected
|
|
347
|
+
*/
|
|
348
|
+
const isGroupPartiallySelected = (group: RegionGroup): boolean => {
|
|
349
|
+
const selectedCount = group.regions.filter((region) =>
|
|
350
|
+
tempSelectedRegions.includes(region.code)
|
|
351
|
+
).length;
|
|
352
|
+
return selectedCount > 0 && selectedCount < group.regions.length;
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Toggle entire group selection
|
|
357
|
+
*/
|
|
358
|
+
const toggleGroup = (group: ExtendedRegionGroup) => {
|
|
359
|
+
const hasGlobal = group.regions.some((r) => r.code === 'Global');
|
|
360
|
+
const isEUGroup = group.key === 'europe' || group.parentKey === 'eu-parent';
|
|
361
|
+
|
|
362
|
+
if (hasGlobal) {
|
|
363
|
+
if (tempSelectedRegions.includes('Global')) {
|
|
364
|
+
tempSelectedRegions = [];
|
|
365
|
+
} else {
|
|
366
|
+
// Clear all and select only Global
|
|
367
|
+
tempSelectedRegions = ['Global'];
|
|
368
|
+
}
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
if (isEUGroup && group.isMainParent) {
|
|
373
|
+
if (tempSelectedRegions.includes('EU')) {
|
|
374
|
+
tempSelectedRegions = [];
|
|
375
|
+
} else {
|
|
376
|
+
// Clear all and select only EU
|
|
377
|
+
tempSelectedRegions = ['EU'];
|
|
378
|
+
}
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
if (group.isMainParent) {
|
|
383
|
+
// This is the "Select Countries" group
|
|
384
|
+
const allGroupAndSubGroupRegions = [
|
|
385
|
+
...group.regions.map((r) => r.code),
|
|
386
|
+
...(group.subGroups?.flatMap((sg) => sg.regions.map((r) => r.code)) || [])
|
|
387
|
+
];
|
|
388
|
+
|
|
389
|
+
// Filter out regions that are already in use
|
|
390
|
+
const availableRegions = allGroupAndSubGroupRegions.filter(
|
|
391
|
+
(code) => !usedRegions.regions.has(code)
|
|
392
|
+
);
|
|
393
|
+
|
|
394
|
+
// Clear Global and EU when selecting countries
|
|
395
|
+
const currentCountrySelections = tempSelectedRegions.filter(
|
|
396
|
+
(code) => code !== 'Global' && code !== 'EU'
|
|
397
|
+
);
|
|
398
|
+
|
|
399
|
+
// Check if all available (non-in-use) regions are selected
|
|
400
|
+
const allAvailableSelected = availableRegions.every((code) =>
|
|
401
|
+
currentCountrySelections.includes(code)
|
|
402
|
+
);
|
|
403
|
+
|
|
404
|
+
if (allAvailableSelected) {
|
|
405
|
+
// Deselect all available countries
|
|
406
|
+
tempSelectedRegions = currentCountrySelections.filter(
|
|
407
|
+
(code) => !availableRegions.includes(code)
|
|
408
|
+
);
|
|
409
|
+
} else {
|
|
410
|
+
// Select all available countries (excluding Global, EU, and in-use regions)
|
|
411
|
+
tempSelectedRegions = [...new Set([...currentCountrySelections, ...availableRegions])];
|
|
412
|
+
}
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// Sub-group toggle (like United States)
|
|
417
|
+
const isFullySelected = isGroupFullySelected(group);
|
|
418
|
+
const groupCodes = group.regions.map((r) => r.code);
|
|
419
|
+
|
|
420
|
+
// Filter out regions that are already in use
|
|
421
|
+
const availableGroupCodes = groupCodes.filter((code) => !usedRegions.regions.has(code));
|
|
422
|
+
|
|
423
|
+
// Clear Global and EU when selecting countries
|
|
424
|
+
const currentCountrySelections = tempSelectedRegions.filter(
|
|
425
|
+
(code) => code !== 'Global' && code !== 'EU'
|
|
426
|
+
);
|
|
427
|
+
|
|
428
|
+
if (isFullySelected) {
|
|
429
|
+
tempSelectedRegions = currentCountrySelections.filter((code) => !groupCodes.includes(code));
|
|
430
|
+
} else {
|
|
431
|
+
// Only select available (non-in-use) regions
|
|
432
|
+
tempSelectedRegions = [...new Set([...currentCountrySelections, ...availableGroupCodes])];
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Apply selections and trigger callback
|
|
438
|
+
*/
|
|
439
|
+
const applySelections = () => {
|
|
440
|
+
onRegionsChange?.(tempSelectedRegions);
|
|
441
|
+
};
|
|
442
|
+
</script>
|
|
443
|
+
|
|
444
|
+
<div class="region-selector {className}" {...restProps}>
|
|
445
|
+
<div class="search-actions-row">
|
|
446
|
+
<div class="search-section">
|
|
447
|
+
<input
|
|
448
|
+
type="text"
|
|
449
|
+
class="search-input"
|
|
450
|
+
placeholder={searchPlaceholder}
|
|
451
|
+
bind:value={searchQuery}
|
|
452
|
+
/>
|
|
453
|
+
</div>
|
|
454
|
+
{#if tempSelectedRegions.length > 0}
|
|
455
|
+
<button type="button" class="clear-btn" onclick={clearAll}>Clear all</button>
|
|
456
|
+
{/if}
|
|
457
|
+
</div>
|
|
458
|
+
|
|
459
|
+
{#if tempSelectedRegions.length > 0}
|
|
460
|
+
<div class="selection-display">
|
|
461
|
+
<div class="selected-items">
|
|
462
|
+
{#each visibleBadges as region (region.code)}
|
|
463
|
+
<span class="selected-badge">
|
|
464
|
+
{region.name}
|
|
465
|
+
<span
|
|
466
|
+
role="button"
|
|
467
|
+
tabindex="0"
|
|
468
|
+
class="remove-btn"
|
|
469
|
+
onclick={(e) => {
|
|
470
|
+
e.stopPropagation();
|
|
471
|
+
removeRegion(region.code);
|
|
472
|
+
}}
|
|
473
|
+
onkeydown={(e) => {
|
|
474
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
475
|
+
e.preventDefault();
|
|
476
|
+
e.stopPropagation();
|
|
477
|
+
removeRegion(region.code);
|
|
478
|
+
}
|
|
479
|
+
}}
|
|
480
|
+
>
|
|
481
|
+
×
|
|
482
|
+
</span>
|
|
483
|
+
</span>
|
|
484
|
+
{/each}
|
|
485
|
+
{#if remainingBadgesCount > 0}
|
|
486
|
+
<span class="more-badge"> + {remainingBadgesCount} more </span>
|
|
487
|
+
{/if}
|
|
488
|
+
</div>
|
|
489
|
+
</div>
|
|
490
|
+
{/if}
|
|
491
|
+
|
|
492
|
+
<div class="options-list">
|
|
493
|
+
{#if isLoading}
|
|
494
|
+
<div class="empty-state">
|
|
495
|
+
<span class="empty-text">Loading regions...</span>
|
|
496
|
+
</div>
|
|
497
|
+
{:else if error}
|
|
498
|
+
<div class="empty-state">
|
|
499
|
+
<span class="empty-text error">Failed to load regions</span>
|
|
500
|
+
<span class="empty-text-sub">{error}</span>
|
|
501
|
+
</div>
|
|
502
|
+
{:else if filteredGroups.length === 0}
|
|
503
|
+
<div class="empty-state">
|
|
504
|
+
<span class="empty-text">No regions found</span>
|
|
505
|
+
{#if searchQuery}
|
|
506
|
+
<span class="empty-text-sub">Try searching with different terms</span>
|
|
507
|
+
{/if}
|
|
508
|
+
</div>
|
|
509
|
+
{:else}
|
|
510
|
+
{#each filteredGroups as group (group.key)}
|
|
511
|
+
{@const isMainParent = group.isMainParent}
|
|
512
|
+
{@const isThisMainParentSelected = selectedMainParent === group.parentKey}
|
|
513
|
+
{@const hasGlobal = group.regions.some((r) => r.code === 'Global')}
|
|
514
|
+
{@const isEUGroup = group.key === 'europe' || group.parentKey === 'eu-parent'}
|
|
515
|
+
{@const isNonExpandable = hasGlobal || isEUGroup}
|
|
516
|
+
{@const isGlobalGroupUsed = hasGlobal && usedRegions.isGlobalUsed}
|
|
517
|
+
{@const isEUGroupUsed = isEUGroup && usedRegions.isEUGroupUsed}
|
|
518
|
+
{@const allGroupRegionsInUse = areAllGroupAndSubGroupRegionsInUse(group)}
|
|
519
|
+
{@const isGroupUsedByOther = isGlobalGroupUsed || isEUGroupUsed || allGroupRegionsInUse}
|
|
520
|
+
{@const isGroupDisabled = isGroupUsedByOther}
|
|
521
|
+
|
|
522
|
+
<div class="option-group" class:disabled={isGroupDisabled} class:main-parent={isMainParent}>
|
|
523
|
+
{#if isMainParent}
|
|
524
|
+
<button
|
|
525
|
+
type="button"
|
|
526
|
+
class="group-label main-parent-label"
|
|
527
|
+
class:fully-selected={isThisMainParentSelected}
|
|
528
|
+
class:expanded={isGroupExpanded(group.key)}
|
|
529
|
+
class:disabled={isGroupDisabled}
|
|
530
|
+
class:in-use={isGroupUsedByOther}
|
|
531
|
+
onclick={() => {
|
|
532
|
+
if (isGroupDisabled) return;
|
|
533
|
+
|
|
534
|
+
if (isNonExpandable) {
|
|
535
|
+
toggleGroup(group);
|
|
536
|
+
} else {
|
|
537
|
+
toggleGroupExpansion(group.key);
|
|
538
|
+
}
|
|
539
|
+
}}
|
|
540
|
+
onkeydown={(e) => {
|
|
541
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
542
|
+
e.preventDefault();
|
|
543
|
+
if (isGroupDisabled) return;
|
|
544
|
+
|
|
545
|
+
if (isNonExpandable) {
|
|
546
|
+
toggleGroup(group);
|
|
547
|
+
} else {
|
|
548
|
+
toggleGroupExpansion(group.key);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
}}
|
|
552
|
+
disabled={isGroupDisabled}
|
|
553
|
+
>
|
|
554
|
+
<div
|
|
555
|
+
role="radio"
|
|
556
|
+
tabindex="-1"
|
|
557
|
+
aria-checked={isThisMainParentSelected}
|
|
558
|
+
onclick={(e) => {
|
|
559
|
+
if (!isNonExpandable) {
|
|
560
|
+
e.stopPropagation();
|
|
561
|
+
if (!isGroupDisabled) {
|
|
562
|
+
toggleGroup(group);
|
|
563
|
+
if (!isGroupExpanded(group.key)) {
|
|
564
|
+
toggleGroupExpansion(group.key);
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
}}
|
|
569
|
+
onkeydown={(e) => {
|
|
570
|
+
if (!isNonExpandable && (e.key === 'Enter' || e.key === ' ')) {
|
|
571
|
+
e.preventDefault();
|
|
572
|
+
e.stopPropagation();
|
|
573
|
+
if (!isGroupDisabled) {
|
|
574
|
+
toggleGroup(group);
|
|
575
|
+
if (!isGroupExpanded(group.key)) {
|
|
576
|
+
toggleGroupExpansion(group.key);
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
}}
|
|
581
|
+
>
|
|
582
|
+
<Checkbox
|
|
583
|
+
checked={isThisMainParentSelected}
|
|
584
|
+
variant="radio"
|
|
585
|
+
disabled={isGroupDisabled}
|
|
586
|
+
/>
|
|
587
|
+
</div>
|
|
588
|
+
<span class="group-label-text">
|
|
589
|
+
{group.name}
|
|
590
|
+
{#if isGroupUsedByOther}
|
|
591
|
+
<span class="in-use-badge">(in-use)</span>
|
|
592
|
+
{/if}
|
|
593
|
+
</span>
|
|
594
|
+
{#if !isNonExpandable}
|
|
595
|
+
<span class="group-chevron">
|
|
596
|
+
<svg viewBox="0 0 20 20" fill="currentColor">
|
|
597
|
+
<path
|
|
598
|
+
fill-rule="evenodd"
|
|
599
|
+
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
|
|
600
|
+
clip-rule="evenodd"
|
|
601
|
+
/>
|
|
602
|
+
</svg>
|
|
603
|
+
</span>
|
|
604
|
+
{/if}
|
|
605
|
+
</button>
|
|
606
|
+
{/if}
|
|
607
|
+
|
|
608
|
+
{#if !isMainParent || isGroupExpanded(group.key)}
|
|
609
|
+
{#if group.subGroups && group.subGroups.length > 0}
|
|
610
|
+
{#each group.subGroups as subGroup (subGroup.key)}
|
|
611
|
+
{@const allSubGroupRegionsInUse = areAllGroupRegionsInUse(subGroup)}
|
|
612
|
+
{@const isSubGroupDisabled = allSubGroupRegionsInUse}
|
|
613
|
+
{@const isSubGroupFullySelected = isGroupFullySelected(subGroup)}
|
|
614
|
+
{@const isSubGroupPartiallySelected = isGroupPartiallySelected(subGroup)}
|
|
615
|
+
{@const isSubGroupExpanded = isGroupExpanded(subGroup.key)}
|
|
616
|
+
|
|
617
|
+
<div class="sub-group">
|
|
618
|
+
<button
|
|
619
|
+
type="button"
|
|
620
|
+
class="group-label sub-group-label"
|
|
621
|
+
class:fully-selected={isSubGroupFullySelected}
|
|
622
|
+
class:partially-selected={isSubGroupPartiallySelected}
|
|
623
|
+
class:expanded={isSubGroupExpanded}
|
|
624
|
+
class:disabled={isSubGroupDisabled}
|
|
625
|
+
class:in-use={allSubGroupRegionsInUse}
|
|
626
|
+
onclick={() => {
|
|
627
|
+
if (!isSubGroupDisabled) {
|
|
628
|
+
toggleGroupExpansion(subGroup.key);
|
|
629
|
+
}
|
|
630
|
+
}}
|
|
631
|
+
disabled={isSubGroupDisabled}
|
|
632
|
+
>
|
|
633
|
+
<div
|
|
634
|
+
role="checkbox"
|
|
635
|
+
tabindex="0"
|
|
636
|
+
aria-checked={isSubGroupFullySelected
|
|
637
|
+
? 'true'
|
|
638
|
+
: isSubGroupPartiallySelected
|
|
639
|
+
? 'mixed'
|
|
640
|
+
: 'false'}
|
|
641
|
+
onclick={(e) => {
|
|
642
|
+
e.stopPropagation();
|
|
643
|
+
if (!isSubGroupDisabled) {
|
|
644
|
+
toggleGroup(subGroup);
|
|
645
|
+
}
|
|
646
|
+
}}
|
|
647
|
+
onkeydown={(e) => {
|
|
648
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
649
|
+
e.preventDefault();
|
|
650
|
+
e.stopPropagation();
|
|
651
|
+
if (!isSubGroupDisabled) {
|
|
652
|
+
toggleGroup(subGroup);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
}}
|
|
656
|
+
>
|
|
657
|
+
{#if isSubGroupPartiallySelected}
|
|
658
|
+
<div class="partially-selected-box">
|
|
659
|
+
<svg viewBox="0 0 20 20" fill="currentColor">
|
|
660
|
+
<path d="M5 10h10v1H5z" />
|
|
661
|
+
</svg>
|
|
662
|
+
</div>
|
|
663
|
+
{:else}
|
|
664
|
+
<Checkbox checked={isSubGroupFullySelected} disabled={isSubGroupDisabled} />
|
|
665
|
+
{/if}
|
|
666
|
+
</div>
|
|
667
|
+
<span class="group-label-text sub-group-text">
|
|
668
|
+
{subGroup.name}
|
|
669
|
+
{#if allSubGroupRegionsInUse}
|
|
670
|
+
<span class="in-use-badge">(in-use)</span>
|
|
671
|
+
{/if}
|
|
672
|
+
</span>
|
|
673
|
+
<span class="group-chevron">
|
|
674
|
+
<svg viewBox="0 0 20 20" fill="currentColor">
|
|
675
|
+
<path
|
|
676
|
+
fill-rule="evenodd"
|
|
677
|
+
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
|
|
678
|
+
clip-rule="evenodd"
|
|
679
|
+
/>
|
|
680
|
+
</svg>
|
|
681
|
+
</span>
|
|
682
|
+
</button>
|
|
683
|
+
|
|
684
|
+
{#if isSubGroupExpanded}
|
|
685
|
+
{#each subGroup.regions as region (region.code)}
|
|
686
|
+
{@const isRegionInUse = usedRegions.regions.has(region.code)}
|
|
687
|
+
{@const isRegionDisabled = isRegionInUse}
|
|
688
|
+
|
|
689
|
+
<button
|
|
690
|
+
type="button"
|
|
691
|
+
class="option-item sub-group-item"
|
|
692
|
+
class:disabled={isRegionDisabled}
|
|
693
|
+
class:in-use={isRegionInUse}
|
|
694
|
+
onclick={() => {
|
|
695
|
+
if (!isRegionDisabled) {
|
|
696
|
+
toggleRegion(region.code);
|
|
697
|
+
}
|
|
698
|
+
}}
|
|
699
|
+
disabled={isRegionDisabled}
|
|
700
|
+
>
|
|
701
|
+
<Checkbox
|
|
702
|
+
checked={tempSelectedRegions.includes(region.code)}
|
|
703
|
+
disabled={isRegionDisabled}
|
|
704
|
+
/>
|
|
705
|
+
<span class="option-label">
|
|
706
|
+
{region.name}
|
|
707
|
+
<span class="region-code-badge">
|
|
708
|
+
{region.code}
|
|
709
|
+
{#if isRegionInUse}
|
|
710
|
+
<span class="in-use-badge">(in-use)</span>
|
|
711
|
+
{/if}
|
|
712
|
+
</span>
|
|
713
|
+
</span>
|
|
714
|
+
</button>
|
|
715
|
+
{/each}
|
|
716
|
+
{/if}
|
|
717
|
+
</div>
|
|
718
|
+
{/each}
|
|
719
|
+
{/if}
|
|
720
|
+
|
|
721
|
+
{#if !isMainParent || group.regions.length > 0}
|
|
722
|
+
{#each group.regions as region (region.code)}
|
|
723
|
+
{@const isRegionInUse = usedRegions.regions.has(region.code)}
|
|
724
|
+
{@const isRegionDisabled = isRegionInUse}
|
|
725
|
+
|
|
726
|
+
<button
|
|
727
|
+
type="button"
|
|
728
|
+
class="option-item"
|
|
729
|
+
class:indented={isMainParent}
|
|
730
|
+
class:disabled={isRegionDisabled}
|
|
731
|
+
class:in-use={isRegionInUse}
|
|
732
|
+
onclick={() => {
|
|
733
|
+
if (!isRegionDisabled) {
|
|
734
|
+
toggleRegion(region.code);
|
|
735
|
+
}
|
|
736
|
+
}}
|
|
737
|
+
disabled={isRegionDisabled}
|
|
738
|
+
>
|
|
739
|
+
<Checkbox
|
|
740
|
+
checked={tempSelectedRegions.includes(region.code)}
|
|
741
|
+
disabled={isRegionDisabled}
|
|
742
|
+
/>
|
|
743
|
+
<span class="option-label">
|
|
744
|
+
{region.name}
|
|
745
|
+
<span class="region-code-badge">
|
|
746
|
+
{region.code}
|
|
747
|
+
{#if isRegionInUse}
|
|
748
|
+
<span class="in-use-badge">(in-use)</span>
|
|
749
|
+
{/if}
|
|
750
|
+
</span>
|
|
751
|
+
</span>
|
|
752
|
+
</button>
|
|
753
|
+
{/each}
|
|
754
|
+
{/if}
|
|
755
|
+
{/if}
|
|
756
|
+
</div>
|
|
757
|
+
{/each}
|
|
758
|
+
{/if}
|
|
759
|
+
</div>
|
|
760
|
+
</div>
|
|
761
|
+
|
|
762
|
+
<style>
|
|
763
|
+
.region-selector {
|
|
764
|
+
display: flex;
|
|
765
|
+
flex-direction: column;
|
|
766
|
+
gap: 12px;
|
|
767
|
+
height: 100%;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
.search-actions-row {
|
|
771
|
+
display: flex;
|
|
772
|
+
gap: 8px;
|
|
773
|
+
align-items: flex-start;
|
|
774
|
+
position: sticky;
|
|
775
|
+
top: 0;
|
|
776
|
+
background: var(--background2);
|
|
777
|
+
z-index: 10;
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
.search-section {
|
|
781
|
+
flex: 1;
|
|
782
|
+
min-width: 0;
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
.search-input {
|
|
786
|
+
width: 100%;
|
|
787
|
+
padding: 6px 10px;
|
|
788
|
+
background: var(--background3);
|
|
789
|
+
border: 1px solid var(--border1);
|
|
790
|
+
border-radius: 4px;
|
|
791
|
+
color: var(--text1);
|
|
792
|
+
font-size: 11.5px;
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
.search-input:focus {
|
|
796
|
+
outline: none;
|
|
797
|
+
border-color: var(--actionPrimaryBackground);
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
.clear-btn {
|
|
801
|
+
padding: 6px 12px;
|
|
802
|
+
background: var(--background3);
|
|
803
|
+
border: 1px solid var(--border1);
|
|
804
|
+
border-radius: 4px;
|
|
805
|
+
font-size: 11px;
|
|
806
|
+
cursor: pointer;
|
|
807
|
+
color: var(--text1);
|
|
808
|
+
white-space: nowrap;
|
|
809
|
+
flex-shrink: 0;
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
.clear-btn:hover {
|
|
813
|
+
background: var(--background3);
|
|
814
|
+
border-color: var(--blueBorder);
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
.selection-display {
|
|
818
|
+
padding: 8px 0;
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
.selected-items {
|
|
822
|
+
display: flex;
|
|
823
|
+
flex-wrap: wrap;
|
|
824
|
+
gap: 6px;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
.selected-badge {
|
|
828
|
+
display: inline-flex;
|
|
829
|
+
align-items: center;
|
|
830
|
+
gap: 4px;
|
|
831
|
+
padding: 4px 8px;
|
|
832
|
+
background: var(--background3);
|
|
833
|
+
border: 1px solid var(--border1);
|
|
834
|
+
border-radius: 4px;
|
|
835
|
+
font-size: 11px;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
.selected-badge:hover {
|
|
839
|
+
background: var(--background3);
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
.more-badge {
|
|
843
|
+
display: inline-flex;
|
|
844
|
+
align-items: center;
|
|
845
|
+
padding: 4px 8px;
|
|
846
|
+
background: var(--background3);
|
|
847
|
+
border: 1px solid var(--border1);
|
|
848
|
+
border-radius: 4px;
|
|
849
|
+
font-size: 11px;
|
|
850
|
+
color: var(--text2);
|
|
851
|
+
font-weight: 500;
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
.remove-btn {
|
|
855
|
+
display: flex;
|
|
856
|
+
align-items: end;
|
|
857
|
+
justify-content: center;
|
|
858
|
+
padding: 0;
|
|
859
|
+
width: 14px;
|
|
860
|
+
height: 14px;
|
|
861
|
+
background: none;
|
|
862
|
+
border: none;
|
|
863
|
+
border-radius: 3px;
|
|
864
|
+
cursor: pointer;
|
|
865
|
+
font-size: 1rem;
|
|
866
|
+
line-height: 1;
|
|
867
|
+
color: var(--text3);
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
.options-list {
|
|
871
|
+
overflow-y: auto;
|
|
872
|
+
padding-right: 4px;
|
|
873
|
+
flex: 1;
|
|
874
|
+
max-height: 300px;
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
.empty-state {
|
|
878
|
+
display: flex;
|
|
879
|
+
flex-direction: column;
|
|
880
|
+
align-items: center;
|
|
881
|
+
justify-content: center;
|
|
882
|
+
gap: 4px;
|
|
883
|
+
padding: 40px 20px;
|
|
884
|
+
text-align: center;
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
.empty-text {
|
|
888
|
+
font-size: 11px;
|
|
889
|
+
color: var(--text2);
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
.empty-text.error {
|
|
893
|
+
color: var(--redText);
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
.empty-text-sub {
|
|
897
|
+
font-size: 11px;
|
|
898
|
+
color: var(--text3);
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
.option-group {
|
|
902
|
+
margin-bottom: 8px;
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
.option-group:last-child {
|
|
906
|
+
margin-bottom: 0;
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
.option-group.main-parent:last-child {
|
|
910
|
+
border-bottom: none;
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
.sub-group {
|
|
914
|
+
margin-bottom: 4px;
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
.group-label {
|
|
918
|
+
width: 100%;
|
|
919
|
+
display: flex;
|
|
920
|
+
align-items: center;
|
|
921
|
+
gap: 10px;
|
|
922
|
+
padding: 8px;
|
|
923
|
+
background: none;
|
|
924
|
+
border: none;
|
|
925
|
+
border-radius: 4px;
|
|
926
|
+
cursor: pointer;
|
|
927
|
+
text-align: left;
|
|
928
|
+
margin-bottom: 4px;
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
.group-label:hover {
|
|
932
|
+
background: var(--background3);
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
.group-label.partially-selected {
|
|
936
|
+
background: var(--background3);
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
.main-parent-label:hover {
|
|
940
|
+
background: var(--background3);
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
.main-parent-label.fully-selected {
|
|
944
|
+
background: var(--background3);
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
.sub-group-label {
|
|
948
|
+
padding: 6px 12px;
|
|
949
|
+
width: calc(100% - 28px);
|
|
950
|
+
margin-left: 20px;
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
.group-label-text {
|
|
954
|
+
flex: 1;
|
|
955
|
+
font-size: 11px;
|
|
956
|
+
font-weight: 600;
|
|
957
|
+
text-transform: uppercase;
|
|
958
|
+
letter-spacing: 0.05em;
|
|
959
|
+
color: var(--text2);
|
|
960
|
+
display: flex;
|
|
961
|
+
align-items: center;
|
|
962
|
+
gap: 6px;
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
.main-parent-label .group-label-text {
|
|
966
|
+
font-size: 12px;
|
|
967
|
+
font-weight: 700;
|
|
968
|
+
color: var(--text1);
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
.sub-group-text {
|
|
972
|
+
font-size: 10.5px;
|
|
973
|
+
font-weight: 500;
|
|
974
|
+
text-transform: none;
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
.group-chevron {
|
|
978
|
+
display: flex;
|
|
979
|
+
align-items: center;
|
|
980
|
+
justify-content: center;
|
|
981
|
+
width: 16px;
|
|
982
|
+
height: 16px;
|
|
983
|
+
margin-left: auto;
|
|
984
|
+
flex-shrink: 0;
|
|
985
|
+
color: var(--text3);
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
.group-label.expanded .group-chevron {
|
|
989
|
+
transform: rotate(180deg);
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
.group-chevron svg {
|
|
993
|
+
width: 14px;
|
|
994
|
+
height: 14px;
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
.group-checkbox {
|
|
998
|
+
width: 18px;
|
|
999
|
+
height: 18px;
|
|
1000
|
+
cursor: pointer;
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
.group-checkbox:hover {
|
|
1004
|
+
opacity: 0.8;
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
.option-item {
|
|
1008
|
+
width: 100%;
|
|
1009
|
+
display: flex;
|
|
1010
|
+
align-items: center;
|
|
1011
|
+
gap: 10px;
|
|
1012
|
+
padding: 8px 12px;
|
|
1013
|
+
background: none;
|
|
1014
|
+
border: none;
|
|
1015
|
+
border-radius: 4px;
|
|
1016
|
+
cursor: pointer;
|
|
1017
|
+
text-align: left;
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
.option-item:hover {
|
|
1021
|
+
background: var(--background3);
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
.option-item.indented {
|
|
1025
|
+
width: calc(100% - 28px);
|
|
1026
|
+
margin-left: 20px;
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
.sub-group-item {
|
|
1030
|
+
width: calc(100% - 56px);
|
|
1031
|
+
margin-left: 56px;
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
.option-item :global(.checkbox),
|
|
1035
|
+
.group-label :global(.checkbox) {
|
|
1036
|
+
flex-shrink: 0;
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
.partially-selected-box {
|
|
1040
|
+
width: 16px;
|
|
1041
|
+
height: 16px;
|
|
1042
|
+
flex-shrink: 0;
|
|
1043
|
+
border: 2px solid var(--border1);
|
|
1044
|
+
border-radius: 4px;
|
|
1045
|
+
display: flex;
|
|
1046
|
+
align-items: center;
|
|
1047
|
+
justify-content: center;
|
|
1048
|
+
background: var(--actionPrimaryBackground);
|
|
1049
|
+
border-color: var(--actionPrimaryBackground);
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
.partially-selected-box svg {
|
|
1053
|
+
width: 14px;
|
|
1054
|
+
height: 14px;
|
|
1055
|
+
color: white;
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
.option-item.disabled,
|
|
1059
|
+
.group-label.disabled,
|
|
1060
|
+
.option-group.disabled {
|
|
1061
|
+
opacity: 0.5;
|
|
1062
|
+
cursor: not-allowed;
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
.option-item.disabled:hover,
|
|
1066
|
+
.group-label.disabled:hover {
|
|
1067
|
+
background: none;
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
.option-label {
|
|
1071
|
+
flex: 1;
|
|
1072
|
+
font-size: 11.5px;
|
|
1073
|
+
display: flex;
|
|
1074
|
+
justify-content: space-between;
|
|
1075
|
+
align-items: center;
|
|
1076
|
+
gap: 8px;
|
|
1077
|
+
color: var(--text2);
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
.region-code-badge {
|
|
1081
|
+
font-size: 10px;
|
|
1082
|
+
color: var(--text3);
|
|
1083
|
+
font-family: monospace;
|
|
1084
|
+
display: inline-flex;
|
|
1085
|
+
align-items: center;
|
|
1086
|
+
gap: 4px;
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
.in-use-badge {
|
|
1090
|
+
font-size: 9px;
|
|
1091
|
+
color: var(--yellowText, #f59e0b);
|
|
1092
|
+
font-family:
|
|
1093
|
+
system-ui,
|
|
1094
|
+
-apple-system,
|
|
1095
|
+
sans-serif;
|
|
1096
|
+
font-weight: 500;
|
|
1097
|
+
font-style: italic;
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
.option-item.in-use,
|
|
1101
|
+
.group-label.in-use {
|
|
1102
|
+
opacity: 0.6;
|
|
1103
|
+
cursor: not-allowed;
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
.option-item.in-use:hover,
|
|
1107
|
+
.group-label.in-use:hover {
|
|
1108
|
+
background: none;
|
|
1109
|
+
}
|
|
1110
|
+
</style>
|