@turtleclub/ui 0.3.0 → 0.4.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +46 -44
- package/CHANGELOG.md +12 -0
- package/dist/index.cjs +72 -43
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +8872 -7439
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types/components/features/data-table/data-table.d.ts +19 -0
- package/dist/types/components/features/data-table/data-table.d.ts.map +1 -0
- package/dist/types/components/features/data-table/expand-toggle.d.ts +5 -0
- package/dist/types/components/features/data-table/expand-toggle.d.ts.map +1 -0
- package/dist/types/components/features/data-table/fuzzy-filter.d.ts +4 -0
- package/dist/types/components/features/data-table/fuzzy-filter.d.ts.map +1 -0
- package/dist/types/components/features/data-table/index.d.ts +3 -0
- package/dist/types/components/features/data-table/index.d.ts.map +1 -0
- package/dist/types/components/features/data-table/sortable-header.d.ts +5 -0
- package/dist/types/components/features/data-table/sortable-header.d.ts.map +1 -0
- package/dist/types/components/features/page-heading.d.ts +1 -1
- package/dist/types/components/features/page-heading.d.ts.map +1 -1
- package/dist/types/components/features/sidebar-layout.d.ts.map +1 -1
- package/dist/types/components/icons/beta.d.ts.map +1 -1
- package/dist/types/components/icons/dot.d.ts.map +1 -1
- package/dist/types/components/icons/issue.d.ts.map +1 -1
- package/dist/types/components/icons/turtle.d.ts.map +1 -1
- package/dist/types/components/icons/update.d.ts.map +1 -1
- package/dist/types/components/icons/warning.d.ts.map +1 -1
- package/dist/types/components/molecules/opportunity/opportunity-disclaimer.d.ts.map +1 -1
- package/dist/types/components/molecules/opportunity/opportunity-list/hooks/use-opportunity-grouping.d.ts.map +1 -1
- package/dist/types/components/molecules/opportunity/opportunity-list/opportunity-list.d.ts.map +1 -1
- package/dist/types/components/molecules/opportunity/opportunity-rate-estimator.d.ts.map +1 -1
- package/dist/types/components/molecules/opportunity/opportunity-section.d.ts.map +1 -1
- package/dist/types/components/molecules/opportunity/opportunity-selector.d.ts +1 -1
- package/dist/types/components/molecules/opportunity/opportunity-selector.d.ts.map +1 -1
- package/dist/types/components/molecules/slippage-selector.d.ts.map +1 -1
- package/dist/types/components/molecules/swap-details.d.ts.map +1 -1
- package/dist/types/components/molecules/swap-input.d.ts.map +1 -1
- package/dist/types/components/molecules/tabs.d.ts +1 -1
- package/dist/types/components/molecules/tabs.d.ts.map +1 -1
- package/dist/types/components/molecules/token-selector.d.ts.map +1 -1
- package/dist/types/components/molecules/tx-status.d.ts.map +1 -1
- package/dist/types/components/molecules/widget/asset-list/asset-filters.d.ts.map +1 -1
- package/dist/types/components/molecules/widget/asset-list/asset-list.d.ts.map +1 -1
- package/dist/types/components/molecules/widget/asset-list/hooks/use-asset-filtering.d.ts.map +1 -1
- package/dist/types/components/molecules/widget/asset-list/hooks/use-asset-grouping.d.ts.map +1 -1
- package/dist/types/components/molecules/widget/campaign-item.d.ts.map +1 -1
- package/dist/types/components/molecules/widget/deal-item.d.ts.map +1 -1
- package/dist/types/components/molecules/widget/index.d.ts +1 -1
- package/dist/types/components/molecules/widget/index.d.ts.map +1 -1
- package/dist/types/components/molecules/widget/opportunity-item.d.ts.map +1 -1
- package/dist/types/components/ui/alert-dialog.d.ts.map +1 -1
- package/dist/types/components/ui/avatar.d.ts.map +1 -1
- package/dist/types/components/ui/badge.d.ts.map +1 -1
- package/dist/types/components/ui/banner.d.ts.map +1 -1
- package/dist/types/components/ui/button.d.ts.map +1 -1
- package/dist/types/components/ui/card.d.ts +1 -1
- package/dist/types/components/ui/card.d.ts.map +1 -1
- package/dist/types/components/ui/checkbox.d.ts.map +1 -1
- package/dist/types/components/ui/chip.d.ts.map +1 -1
- package/dist/types/components/ui/collapsible.d.ts.map +1 -1
- package/dist/types/components/ui/combobox.d.ts.map +1 -1
- package/dist/types/components/ui/command.d.ts.map +1 -1
- package/dist/types/components/ui/dialog.d.ts.map +1 -1
- package/dist/types/components/ui/dropdown.d.ts.map +1 -1
- package/dist/types/components/ui/field.d.ts.map +1 -1
- package/dist/types/components/ui/heading.d.ts.map +1 -1
- package/dist/types/components/ui/hover-card.d.ts +1 -1
- package/dist/types/components/ui/hover-card.d.ts.map +1 -1
- package/dist/types/components/ui/icon-list.d.ts.map +1 -1
- package/dist/types/components/ui/info-card.d.ts.map +1 -1
- package/dist/types/components/ui/input-group.d.ts.map +1 -1
- package/dist/types/components/ui/input.d.ts.map +1 -1
- package/dist/types/components/ui/label.d.ts.map +1 -1
- package/dist/types/components/ui/multi-select.d.ts.map +1 -1
- package/dist/types/components/ui/navigation-bar.d.ts +1 -1
- package/dist/types/components/ui/navigation-bar.d.ts.map +1 -1
- package/dist/types/components/ui/navigation-menu.d.ts.map +1 -1
- package/dist/types/components/ui/opportunity-details-v1.d.ts.map +1 -1
- package/dist/types/components/ui/popover.d.ts.map +1 -1
- package/dist/types/components/ui/scroll-area.d.ts.map +1 -1
- package/dist/types/components/ui/select.d.ts.map +1 -1
- package/dist/types/components/ui/separator.d.ts.map +1 -1
- package/dist/types/components/ui/sheet.d.ts.map +1 -1
- package/dist/types/components/ui/sidebar.d.ts.map +1 -1
- package/dist/types/components/ui/slider.d.ts.map +1 -1
- package/dist/types/components/ui/switch.d.ts.map +1 -1
- package/dist/types/components/ui/table-shadcn.d.ts.map +1 -1
- package/dist/types/components/ui/table.d.ts.map +1 -1
- package/dist/types/components/ui/toggle-group.d.ts.map +1 -1
- package/dist/types/components/ui/toggle.d.ts.map +1 -1
- package/dist/types/components/ui/tooltip.d.ts.map +1 -1
- package/dist/types/hooks/useIsMobile.d.ts.map +1 -1
- package/dist/types/lib/utils.d.ts.map +1 -1
- package/dist/types/tokens/index.d.ts +5 -5
- package/dist/types/tokens/index.d.ts.map +1 -1
- package/package.json +3 -2
- package/src/components/features/data-table/data-table.tsx +150 -0
- package/src/components/features/data-table/expand-toggle.tsx +17 -0
- package/src/components/features/data-table/fuzzy-filter.tsx +34 -0
- package/src/components/features/data-table/index.ts +2 -0
- package/src/components/features/data-table/sortable-header.tsx +37 -0
- package/src/components/features/page-heading.tsx +6 -1
- package/src/components/features/search-bar.tsx +1 -1
- package/src/components/features/sidebar-layout.tsx +6 -3
- package/src/components/icons/beta.tsx +11 -2
- package/src/components/icons/dot.tsx +16 -3
- package/src/components/icons/issue.tsx +11 -2
- package/src/components/icons/turtle.tsx +16 -3
- package/src/components/icons/update.tsx +6 -1
- package/src/components/icons/warning.tsx +11 -2
- package/src/components/molecules/opportunity/opportunity-disclaimer.tsx +13 -5
- package/src/components/molecules/opportunity/opportunity-list/hooks/index.ts +1 -1
- package/src/components/molecules/opportunity/opportunity-list/hooks/use-opportunity-filtering.ts +3 -3
- package/src/components/molecules/opportunity/opportunity-list/hooks/use-opportunity-grouping.ts +7 -3
- package/src/components/molecules/opportunity/opportunity-list/index.ts +1 -1
- package/src/components/molecules/opportunity/opportunity-list/opportunity-list.tsx +10 -4
- package/src/components/molecules/opportunity/opportunity-rate-estimator.tsx +5 -6
- package/src/components/molecules/opportunity/opportunity-section.tsx +23 -6
- package/src/components/molecules/opportunity/opportunity-selector.tsx +7 -3
- package/src/components/molecules/slippage-selector.tsx +44 -20
- package/src/components/molecules/swap-details.tsx +14 -5
- package/src/components/molecules/swap-input.tsx +12 -6
- package/src/components/molecules/tabs.tsx +16 -4
- package/src/components/molecules/token-selector.tsx +38 -20
- package/src/components/molecules/tx-status.tsx +105 -54
- package/src/components/molecules/widget/asset-list/asset-filters.tsx +4 -2
- package/src/components/molecules/widget/asset-list/asset-list.tsx +8 -3
- package/src/components/molecules/widget/asset-list/asset-row.tsx +1 -1
- package/src/components/molecules/widget/asset-list/hooks/index.ts +1 -1
- package/src/components/molecules/widget/asset-list/hooks/use-asset-filtering.ts +4 -2
- package/src/components/molecules/widget/asset-list/hooks/use-asset-grouping.ts +15 -6
- package/src/components/molecules/widget/base-selector.tsx +5 -5
- package/src/components/molecules/widget/campaign-item.tsx +12 -6
- package/src/components/molecules/widget/deal-item.tsx +20 -8
- package/src/components/molecules/widget/index.ts +4 -1
- package/src/components/molecules/widget/opportunity-item.tsx +22 -8
- package/src/components/molecules/widget/widget-item-stats.tsx +2 -2
- package/src/components/ui/alert-dialog.tsx +26 -9
- package/src/components/ui/animated-background/animated-background.tsx +14 -6
- package/src/components/ui/animated-background/index.ts +1 -1
- package/src/components/ui/avatar.tsx +12 -3
- package/src/components/ui/badge.tsx +5 -3
- package/src/components/ui/banner.tsx +9 -3
- package/src/components/ui/button.tsx +10 -5
- package/src/components/ui/card.tsx +32 -5
- package/src/components/ui/checkbox.tsx +5 -2
- package/src/components/ui/chip.tsx +10 -6
- package/src/components/ui/collapsible.tsx +15 -3
- package/src/components/ui/combobox.tsx +52 -25
- package/src/components/ui/command.tsx +31 -11
- package/src/components/ui/dialog.tsx +22 -8
- package/src/components/ui/dropdown.tsx +57 -20
- package/src/components/ui/field.tsx +40 -28
- package/src/components/ui/heading.tsx +31 -6
- package/src/components/ui/hover-card.tsx +35 -10
- package/src/components/ui/icon-animation.tsx +12 -12
- package/src/components/ui/icon-list.tsx +45 -18
- package/src/components/ui/info-card.tsx +13 -5
- package/src/components/ui/input-group.tsx +32 -20
- package/src/components/ui/input.tsx +5 -3
- package/src/components/ui/label.tsx +5 -2
- package/src/components/ui/multi-select.tsx +133 -61
- package/src/components/ui/navigation-bar.tsx +39 -22
- package/src/components/ui/navigation-menu.tsx +16 -9
- package/src/components/ui/opportunity-details-v1.tsx +9 -5
- package/src/components/ui/popover.tsx +10 -4
- package/src/components/ui/scroll-area.tsx +5 -3
- package/src/components/ui/select.tsx +25 -10
- package/src/components/ui/separator.tsx +6 -6
- package/src/components/ui/sheet.tsx +15 -6
- package/src/components/ui/sidebar.tsx +62 -26
- package/src/components/ui/slider.tsx +10 -5
- package/src/components/ui/switch.tsx +6 -3
- package/src/components/ui/table-shadcn.tsx +19 -9
- package/src/components/ui/table.tsx +12 -5
- package/src/components/ui/textarea.tsx +1 -1
- package/src/components/ui/toggle-group.tsx +12 -12
- package/src/components/ui/toggle.tsx +14 -14
- package/src/components/ui/tooltip.tsx +7 -3
- package/src/hooks/useIsMobile.ts +5 -2
- package/src/lib/utils.ts +3 -3
- package/src/styles/themes/index.css +1 -1
- package/src/styles/themes/semantic.css +51 -17
- package/src/styles/tokens/colors.css +54 -18
- package/src/styles/tokens/index.css +1 -1
- package/src/styles/tokens/spacing.css +39 -33
- package/src/styles/tokens/typography.css +61 -60
- package/src/tokens/index.ts +82 -82
- package/dist/types/components/features/data-table.d.ts +0 -9
- package/dist/types/components/features/data-table.d.ts.map +0 -1
- package/src/components/features/data-table.tsx +0 -96
|
@@ -26,7 +26,7 @@ const inputVariants = cva(
|
|
|
26
26
|
defaultVariants: {
|
|
27
27
|
variant: "default",
|
|
28
28
|
},
|
|
29
|
-
}
|
|
29
|
+
},
|
|
30
30
|
);
|
|
31
31
|
|
|
32
32
|
export interface InputProps
|
|
@@ -41,7 +41,9 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
|
|
41
41
|
if (prompt) {
|
|
42
42
|
return (
|
|
43
43
|
<div className="flex items-center gap-2">
|
|
44
|
-
<span className="text-primary shrink-0 text-sm font-medium">
|
|
44
|
+
<span className="text-primary shrink-0 text-sm font-medium">
|
|
45
|
+
{prompt}
|
|
46
|
+
</span>
|
|
45
47
|
<input
|
|
46
48
|
type={type}
|
|
47
49
|
data-slot="input"
|
|
@@ -62,7 +64,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
|
|
62
64
|
{...props}
|
|
63
65
|
/>
|
|
64
66
|
);
|
|
65
|
-
}
|
|
67
|
+
},
|
|
66
68
|
);
|
|
67
69
|
|
|
68
70
|
Input.displayName = "Input";
|
|
@@ -5,13 +5,16 @@ import * as LabelPrimitive from "@radix-ui/react-label";
|
|
|
5
5
|
|
|
6
6
|
import { cn } from "@/lib/utils";
|
|
7
7
|
|
|
8
|
-
function Label({
|
|
8
|
+
function Label({
|
|
9
|
+
className,
|
|
10
|
+
...props
|
|
11
|
+
}: React.ComponentProps<typeof LabelPrimitive.Root>) {
|
|
9
12
|
return (
|
|
10
13
|
<LabelPrimitive.Root
|
|
11
14
|
data-slot="label"
|
|
12
15
|
className={cn(
|
|
13
16
|
"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
|
|
14
|
-
className
|
|
17
|
+
className,
|
|
15
18
|
)}
|
|
16
19
|
{...props}
|
|
17
20
|
/>
|
|
@@ -4,7 +4,11 @@ import { cn } from "@/lib/utils";
|
|
|
4
4
|
import { Separator } from "@/components/ui/separator";
|
|
5
5
|
import { Button } from "@/components/ui/button";
|
|
6
6
|
import { Badge } from "@/components/ui/badge";
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
Popover,
|
|
9
|
+
PopoverContent,
|
|
10
|
+
PopoverTrigger,
|
|
11
|
+
} from "@/components/ui/popover";
|
|
8
12
|
import {
|
|
9
13
|
Command,
|
|
10
14
|
CommandEmpty,
|
|
@@ -44,7 +48,10 @@ interface MultiSelectGroup {
|
|
|
44
48
|
* Props for MultiSelect component
|
|
45
49
|
*/
|
|
46
50
|
interface MultiSelectProps
|
|
47
|
-
extends Omit<
|
|
51
|
+
extends Omit<
|
|
52
|
+
React.ButtonHTMLAttributes<HTMLButtonElement>,
|
|
53
|
+
"animationConfig"
|
|
54
|
+
> {
|
|
48
55
|
/**
|
|
49
56
|
* An array of option objects or groups to be displayed in the multi-select component.
|
|
50
57
|
*/
|
|
@@ -256,9 +263,10 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
256
263
|
closeOnSelect = false,
|
|
257
264
|
...props
|
|
258
265
|
},
|
|
259
|
-
ref
|
|
266
|
+
ref,
|
|
260
267
|
) => {
|
|
261
|
-
const [selectedValues, setSelectedValues] =
|
|
268
|
+
const [selectedValues, setSelectedValues] =
|
|
269
|
+
React.useState<string[]>(defaultValue);
|
|
262
270
|
const [isPopoverOpen, setIsPopoverOpen] = React.useState(false);
|
|
263
271
|
const [isAnimating, setIsAnimating] = React.useState(false);
|
|
264
272
|
const [searchValue, setSearchValue] = React.useState("");
|
|
@@ -279,7 +287,7 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
279
287
|
setTimeout(() => setPoliteMessage(""), 100);
|
|
280
288
|
}
|
|
281
289
|
},
|
|
282
|
-
[]
|
|
290
|
+
[],
|
|
283
291
|
);
|
|
284
292
|
|
|
285
293
|
const multiSelectId = React.useId();
|
|
@@ -290,18 +298,23 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
290
298
|
const prevDefaultValueRef = React.useRef<string[]>(defaultValue);
|
|
291
299
|
|
|
292
300
|
const isGroupedOptions = React.useCallback(
|
|
293
|
-
(
|
|
301
|
+
(
|
|
302
|
+
opts: MultiSelectOption[] | MultiSelectGroup[],
|
|
303
|
+
): opts is MultiSelectGroup[] => {
|
|
294
304
|
return opts.length > 0 && "heading" in opts[0];
|
|
295
305
|
},
|
|
296
|
-
[]
|
|
306
|
+
[],
|
|
297
307
|
);
|
|
298
308
|
|
|
299
|
-
const arraysEqual = React.useCallback(
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
309
|
+
const arraysEqual = React.useCallback(
|
|
310
|
+
(a: string[], b: string[]): boolean => {
|
|
311
|
+
if (a.length !== b.length) return false;
|
|
312
|
+
const sortedA = [...a].sort();
|
|
313
|
+
const sortedB = [...b].sort();
|
|
314
|
+
return sortedA.every((val, index) => val === sortedB[index]);
|
|
315
|
+
},
|
|
316
|
+
[],
|
|
317
|
+
);
|
|
305
318
|
|
|
306
319
|
const resetToDefault = React.useCallback(() => {
|
|
307
320
|
setSelectedValues(defaultValue);
|
|
@@ -341,10 +354,12 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
341
354
|
}
|
|
342
355
|
},
|
|
343
356
|
}),
|
|
344
|
-
[resetToDefault, selectedValues, onValueChange]
|
|
357
|
+
[resetToDefault, selectedValues, onValueChange],
|
|
345
358
|
);
|
|
346
359
|
|
|
347
|
-
const [screenSize, setScreenSize] = React.useState<
|
|
360
|
+
const [screenSize, setScreenSize] = React.useState<
|
|
361
|
+
"mobile" | "tablet" | "desktop"
|
|
362
|
+
>("desktop");
|
|
348
363
|
|
|
349
364
|
React.useEffect(() => {
|
|
350
365
|
if (typeof window === "undefined") return;
|
|
@@ -421,14 +436,16 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
421
436
|
}
|
|
422
437
|
});
|
|
423
438
|
if (process.env.NODE_ENV === "development" && duplicates.length > 0) {
|
|
424
|
-
const action = deduplicateOptions
|
|
439
|
+
const action = deduplicateOptions
|
|
440
|
+
? "automatically removed"
|
|
441
|
+
: "detected";
|
|
425
442
|
console.warn(
|
|
426
443
|
`MultiSelect: Duplicate option values ${action}: ${duplicates.join(", ")}. ` +
|
|
427
444
|
`${
|
|
428
445
|
deduplicateOptions
|
|
429
446
|
? "Duplicates have been removed automatically."
|
|
430
447
|
: "This may cause unexpected behavior. Consider setting 'deduplicateOptions={true}' or ensure all option values are unique."
|
|
431
|
-
}
|
|
448
|
+
}`,
|
|
432
449
|
);
|
|
433
450
|
}
|
|
434
451
|
return deduplicateOptions ? uniqueOptions : allOptions;
|
|
@@ -438,11 +455,13 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
438
455
|
(value: string): MultiSelectOption | undefined => {
|
|
439
456
|
const option = getAllOptions().find((option) => option.value === value);
|
|
440
457
|
if (!option && process.env.NODE_ENV === "development") {
|
|
441
|
-
console.warn(
|
|
458
|
+
console.warn(
|
|
459
|
+
`MultiSelect: Option with value "${value}" not found in options list`,
|
|
460
|
+
);
|
|
442
461
|
}
|
|
443
462
|
return option;
|
|
444
463
|
},
|
|
445
|
-
[getAllOptions]
|
|
464
|
+
[getAllOptions],
|
|
446
465
|
);
|
|
447
466
|
|
|
448
467
|
const filteredOptions = React.useMemo(() => {
|
|
@@ -454,8 +473,10 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
454
473
|
...group,
|
|
455
474
|
options: group.options.filter(
|
|
456
475
|
(option) =>
|
|
457
|
-
option.label
|
|
458
|
-
|
|
476
|
+
option.label
|
|
477
|
+
.toLowerCase()
|
|
478
|
+
.includes(searchValue.toLowerCase()) ||
|
|
479
|
+
option.value.toLowerCase().includes(searchValue.toLowerCase()),
|
|
459
480
|
),
|
|
460
481
|
}))
|
|
461
482
|
.filter((group) => group.options.length > 0);
|
|
@@ -463,11 +484,13 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
463
484
|
return options.filter(
|
|
464
485
|
(option) =>
|
|
465
486
|
option.label.toLowerCase().includes(searchValue.toLowerCase()) ||
|
|
466
|
-
option.value.toLowerCase().includes(searchValue.toLowerCase())
|
|
487
|
+
option.value.toLowerCase().includes(searchValue.toLowerCase()),
|
|
467
488
|
);
|
|
468
489
|
}, [options, searchValue, searchable, isGroupedOptions]);
|
|
469
490
|
|
|
470
|
-
const handleInputKeyDown = (
|
|
491
|
+
const handleInputKeyDown = (
|
|
492
|
+
event: React.KeyboardEvent<HTMLInputElement>,
|
|
493
|
+
) => {
|
|
471
494
|
if (event.key === "Enter") {
|
|
472
495
|
setIsPopoverOpen(true);
|
|
473
496
|
} else if (event.key === "Backspace" && !event.currentTarget.value) {
|
|
@@ -505,7 +528,10 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
505
528
|
|
|
506
529
|
const clearExtraOptions = () => {
|
|
507
530
|
if (disabled) return;
|
|
508
|
-
const newSelectedValues = selectedValues.slice(
|
|
531
|
+
const newSelectedValues = selectedValues.slice(
|
|
532
|
+
0,
|
|
533
|
+
responsiveSettings.maxCount,
|
|
534
|
+
);
|
|
509
535
|
setSelectedValues(newSelectedValues);
|
|
510
536
|
onValueChange(newSelectedValues);
|
|
511
537
|
};
|
|
@@ -565,20 +591,24 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
565
591
|
if (diff > 0) {
|
|
566
592
|
const addedItems = selectedValues.slice(-diff);
|
|
567
593
|
const addedLabels = addedItems
|
|
568
|
-
.map(
|
|
594
|
+
.map(
|
|
595
|
+
(value) => allOptions.find((opt) => opt.value === value)?.label,
|
|
596
|
+
)
|
|
569
597
|
.filter(Boolean);
|
|
570
598
|
|
|
571
599
|
if (addedLabels.length === 1) {
|
|
572
600
|
announce(
|
|
573
|
-
`${addedLabels[0]} selected. ${selectedCount} of ${totalOptions} options selected
|
|
601
|
+
`${addedLabels[0]} selected. ${selectedCount} of ${totalOptions} options selected.`,
|
|
574
602
|
);
|
|
575
603
|
} else {
|
|
576
604
|
announce(
|
|
577
|
-
`${addedLabels.length} options selected. ${selectedCount} of ${totalOptions} total selected
|
|
605
|
+
`${addedLabels.length} options selected. ${selectedCount} of ${totalOptions} total selected.`,
|
|
578
606
|
);
|
|
579
607
|
}
|
|
580
608
|
} else if (diff < 0) {
|
|
581
|
-
announce(
|
|
609
|
+
announce(
|
|
610
|
+
`Option removed. ${selectedCount} of ${totalOptions} options selected.`,
|
|
611
|
+
);
|
|
582
612
|
}
|
|
583
613
|
prevSelectedCount.current = selectedCount;
|
|
584
614
|
}
|
|
@@ -586,7 +616,7 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
586
616
|
if (isPopoverOpen !== prevIsOpen.current) {
|
|
587
617
|
if (isPopoverOpen) {
|
|
588
618
|
announce(
|
|
589
|
-
`Dropdown opened. ${totalOptions} options available. Use arrow keys to navigate
|
|
619
|
+
`Dropdown opened. ${totalOptions} options available. Use arrow keys to navigate.`,
|
|
590
620
|
);
|
|
591
621
|
} else {
|
|
592
622
|
announce("Dropdown closed.");
|
|
@@ -594,16 +624,19 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
594
624
|
prevIsOpen.current = isPopoverOpen;
|
|
595
625
|
}
|
|
596
626
|
|
|
597
|
-
if (
|
|
627
|
+
if (
|
|
628
|
+
searchValue !== prevSearchValue.current &&
|
|
629
|
+
searchValue !== undefined
|
|
630
|
+
) {
|
|
598
631
|
if (searchValue && isPopoverOpen) {
|
|
599
632
|
const filteredCount = allOptions.filter(
|
|
600
633
|
(opt) =>
|
|
601
634
|
opt.label.toLowerCase().includes(searchValue.toLowerCase()) ||
|
|
602
|
-
opt.value.toLowerCase().includes(searchValue.toLowerCase())
|
|
635
|
+
opt.value.toLowerCase().includes(searchValue.toLowerCase()),
|
|
603
636
|
).length;
|
|
604
637
|
|
|
605
638
|
announce(
|
|
606
|
-
`${filteredCount} option${filteredCount === 1 ? "" : "s"} found for "${searchValue}"
|
|
639
|
+
`${filteredCount} option${filteredCount === 1 ? "" : "s"} found for "${searchValue}"`,
|
|
607
640
|
);
|
|
608
641
|
}
|
|
609
642
|
prevSearchValue.current = searchValue;
|
|
@@ -621,9 +654,14 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
621
654
|
</div>
|
|
622
655
|
</div>
|
|
623
656
|
|
|
624
|
-
<Popover
|
|
657
|
+
<Popover
|
|
658
|
+
open={isPopoverOpen}
|
|
659
|
+
onOpenChange={setIsPopoverOpen}
|
|
660
|
+
modal={modalPopover}
|
|
661
|
+
>
|
|
625
662
|
<div id={triggerDescriptionId} className="sr-only">
|
|
626
|
-
Multi-select dropdown. Use arrow keys to navigate, Enter to select,
|
|
663
|
+
Multi-select dropdown. Use arrow keys to navigate, Enter to select,
|
|
664
|
+
and Escape to close.
|
|
627
665
|
</div>
|
|
628
666
|
<div id={selectedCountId} className="sr-only" aria-live="polite">
|
|
629
667
|
{selectedValues.length === 0
|
|
@@ -658,7 +696,7 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
658
696
|
responsiveSettings.compactMode && "h-8 text-sm",
|
|
659
697
|
screenSize === "mobile" && "h-12 text-base",
|
|
660
698
|
disabled && "cursor-not-allowed opacity-50",
|
|
661
|
-
className
|
|
699
|
+
className,
|
|
662
700
|
)}
|
|
663
701
|
style={{
|
|
664
702
|
...widthConstraints,
|
|
@@ -670,8 +708,10 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
670
708
|
<div
|
|
671
709
|
className={cn(
|
|
672
710
|
"flex items-center gap-1",
|
|
673
|
-
singleLine
|
|
674
|
-
|
|
711
|
+
singleLine
|
|
712
|
+
? "multiselect-singleline-scroll overflow-x-auto"
|
|
713
|
+
: "flex-wrap",
|
|
714
|
+
responsiveSettings.compactMode && "gap-0.5",
|
|
675
715
|
)}
|
|
676
716
|
style={
|
|
677
717
|
singleLine
|
|
@@ -697,10 +737,12 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
697
737
|
key={value}
|
|
698
738
|
className={cn(
|
|
699
739
|
"!pr-1.5 pl-3.5",
|
|
700
|
-
responsiveSettings.compactMode &&
|
|
701
|
-
|
|
740
|
+
responsiveSettings.compactMode &&
|
|
741
|
+
"px-1.5 py-0.5 text-xs",
|
|
742
|
+
screenSize === "mobile" &&
|
|
743
|
+
"max-w-[120px] truncate",
|
|
702
744
|
singleLine && "flex-shrink-0 whitespace-nowrap",
|
|
703
|
-
"[&>svg]:pointer-events-auto"
|
|
745
|
+
"[&>svg]:pointer-events-auto",
|
|
704
746
|
)}
|
|
705
747
|
style={badgeStyle}
|
|
706
748
|
>
|
|
@@ -708,11 +750,16 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
708
750
|
<IconComponent
|
|
709
751
|
className={cn(
|
|
710
752
|
"mr-2 size-3.5",
|
|
711
|
-
responsiveSettings.compactMode &&
|
|
753
|
+
responsiveSettings.compactMode &&
|
|
754
|
+
"mr-1 h-3 w-3",
|
|
712
755
|
)}
|
|
713
756
|
/>
|
|
714
757
|
)}
|
|
715
|
-
<span
|
|
758
|
+
<span
|
|
759
|
+
className={cn(
|
|
760
|
+
screenSize === "mobile" && "truncate",
|
|
761
|
+
)}
|
|
762
|
+
>
|
|
716
763
|
{option.label}
|
|
717
764
|
</span>
|
|
718
765
|
<div
|
|
@@ -723,7 +770,10 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
723
770
|
toggleOption(value);
|
|
724
771
|
}}
|
|
725
772
|
onKeyDown={(event) => {
|
|
726
|
-
if (
|
|
773
|
+
if (
|
|
774
|
+
event.key === "Enter" ||
|
|
775
|
+
event.key === " "
|
|
776
|
+
) {
|
|
727
777
|
event.preventDefault();
|
|
728
778
|
event.stopPropagation();
|
|
729
779
|
toggleOption(value);
|
|
@@ -742,9 +792,10 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
742
792
|
<Badge
|
|
743
793
|
className={cn(
|
|
744
794
|
"!pr-1.5 pl-3.5",
|
|
745
|
-
responsiveSettings.compactMode &&
|
|
795
|
+
responsiveSettings.compactMode &&
|
|
796
|
+
"px-1.5 py-0.5 text-xs",
|
|
746
797
|
singleLine && "flex-shrink-0 whitespace-nowrap",
|
|
747
|
-
"[&>svg]:pointer-events-auto"
|
|
798
|
+
"[&>svg]:pointer-events-auto",
|
|
748
799
|
)}
|
|
749
800
|
>
|
|
750
801
|
{`+ ${selectedValues.length - responsiveSettings.maxCount} more`}
|
|
@@ -782,7 +833,10 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
782
833
|
>
|
|
783
834
|
<XIcon className="size-3.5" />
|
|
784
835
|
</div>
|
|
785
|
-
<Separator
|
|
836
|
+
<Separator
|
|
837
|
+
orientation="vertical"
|
|
838
|
+
className="flex h-full min-h-6"
|
|
839
|
+
/>
|
|
786
840
|
<ChevronDown
|
|
787
841
|
className="text-muted-foreground mx-2 h-4 cursor-pointer"
|
|
788
842
|
aria-hidden="true"
|
|
@@ -791,7 +845,9 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
791
845
|
</div>
|
|
792
846
|
) : (
|
|
793
847
|
<div className="mx-auto flex w-full items-center justify-between">
|
|
794
|
-
<span className="text-muted-foreground text-sm">
|
|
848
|
+
<span className="text-muted-foreground text-sm">
|
|
849
|
+
{placeholder}
|
|
850
|
+
</span>
|
|
795
851
|
<ChevronDown className="text-muted-foreground mx-2 h-4 cursor-pointer" />
|
|
796
852
|
</div>
|
|
797
853
|
)}
|
|
@@ -807,7 +863,7 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
807
863
|
screenSize === "mobile" && "w-[85vw] max-w-[280px]",
|
|
808
864
|
screenSize === "tablet" && "w-[70vw] max-w-md",
|
|
809
865
|
screenSize === "desktop" && "min-w-[300px]",
|
|
810
|
-
popoverClassName
|
|
866
|
+
popoverClassName,
|
|
811
867
|
)}
|
|
812
868
|
style={{
|
|
813
869
|
maxWidth: `min(${widthConstraints.maxWidth}, 85vw)`,
|
|
@@ -837,10 +893,12 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
837
893
|
className={cn(
|
|
838
894
|
"multiselect-scrollbar max-h-[40vh] overflow-y-auto",
|
|
839
895
|
screenSize === "mobile" && "max-h-[50vh]",
|
|
840
|
-
"overscroll-behavior-y-contain"
|
|
896
|
+
"overscroll-behavior-y-contain",
|
|
841
897
|
)}
|
|
842
898
|
>
|
|
843
|
-
<CommandEmpty>
|
|
899
|
+
<CommandEmpty>
|
|
900
|
+
{emptyIndicator || "No results found."}
|
|
901
|
+
</CommandEmpty>{" "}
|
|
844
902
|
{!hideSelectAll && !searchValue && (
|
|
845
903
|
<CommandGroup>
|
|
846
904
|
<CommandItem
|
|
@@ -858,9 +916,10 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
858
916
|
className={cn(
|
|
859
917
|
"border-border mr-2 flex size-3.5 items-center justify-center rounded-xs border",
|
|
860
918
|
selectedValues.length ===
|
|
861
|
-
getAllOptions().filter((opt) => !opt.disabled)
|
|
919
|
+
getAllOptions().filter((opt) => !opt.disabled)
|
|
920
|
+
.length
|
|
862
921
|
? "bg-primary"
|
|
863
|
-
: "opacity-50 [&_svg]:invisible"
|
|
922
|
+
: "opacity-50 [&_svg]:invisible",
|
|
864
923
|
)}
|
|
865
924
|
aria-hidden="true"
|
|
866
925
|
>
|
|
@@ -868,7 +927,10 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
868
927
|
</div>
|
|
869
928
|
<span>
|
|
870
929
|
(Select All
|
|
871
|
-
{getAllOptions().length > 20
|
|
930
|
+
{getAllOptions().length > 20
|
|
931
|
+
? ` - ${getAllOptions().length} options`
|
|
932
|
+
: ""}
|
|
933
|
+
)
|
|
872
934
|
</span>
|
|
873
935
|
</CommandItem>
|
|
874
936
|
</CommandGroup>
|
|
@@ -877,7 +939,9 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
877
939
|
filteredOptions.map((group) => (
|
|
878
940
|
<CommandGroup key={group.heading} heading={group.heading}>
|
|
879
941
|
{group.options.map((option) => {
|
|
880
|
-
const isSelected = selectedValues.includes(
|
|
942
|
+
const isSelected = selectedValues.includes(
|
|
943
|
+
option.value,
|
|
944
|
+
);
|
|
881
945
|
return (
|
|
882
946
|
<CommandItem
|
|
883
947
|
key={option.value}
|
|
@@ -890,14 +954,17 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
890
954
|
}${option.disabled ? ", disabled" : ""}`}
|
|
891
955
|
className={cn(
|
|
892
956
|
"cursor-pointer",
|
|
893
|
-
option.disabled &&
|
|
957
|
+
option.disabled &&
|
|
958
|
+
"cursor-not-allowed opacity-50",
|
|
894
959
|
)}
|
|
895
960
|
disabled={option.disabled}
|
|
896
961
|
>
|
|
897
962
|
<div
|
|
898
963
|
className={cn(
|
|
899
964
|
"border-border mr-2 flex size-3.5 items-center justify-center rounded-xs border",
|
|
900
|
-
isSelected
|
|
965
|
+
isSelected
|
|
966
|
+
? "bg-primary"
|
|
967
|
+
: "opacity-50 [&_svg]:invisible",
|
|
901
968
|
)}
|
|
902
969
|
aria-hidden="true"
|
|
903
970
|
>
|
|
@@ -931,14 +998,16 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
931
998
|
}${option.disabled ? ", disabled" : ""}`}
|
|
932
999
|
className={cn(
|
|
933
1000
|
"cursor-pointer",
|
|
934
|
-
option.disabled && "cursor-not-allowed opacity-50"
|
|
1001
|
+
option.disabled && "cursor-not-allowed opacity-50",
|
|
935
1002
|
)}
|
|
936
1003
|
disabled={option.disabled}
|
|
937
1004
|
>
|
|
938
1005
|
<div
|
|
939
1006
|
className={cn(
|
|
940
1007
|
"border-border mr-2 flex size-3.5 items-center justify-center rounded-xs border",
|
|
941
|
-
isSelected
|
|
1008
|
+
isSelected
|
|
1009
|
+
? "bg-primary"
|
|
1010
|
+
: "opacity-50 [&_svg]:invisible",
|
|
942
1011
|
)}
|
|
943
1012
|
aria-hidden="true"
|
|
944
1013
|
>
|
|
@@ -967,7 +1036,10 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
967
1036
|
>
|
|
968
1037
|
Clear
|
|
969
1038
|
</CommandItem>
|
|
970
|
-
<Separator
|
|
1039
|
+
<Separator
|
|
1040
|
+
orientation="vertical"
|
|
1041
|
+
className="mx-1 flex h-full min-h-6"
|
|
1042
|
+
/>
|
|
971
1043
|
</>
|
|
972
1044
|
)}
|
|
973
1045
|
<CommandItem
|
|
@@ -985,7 +1057,7 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
985
1057
|
<WandSparkles
|
|
986
1058
|
className={cn(
|
|
987
1059
|
"text-foreground bg-background my-2 h-3 w-3 cursor-pointer",
|
|
988
|
-
isAnimating ? "" : "text-muted-foreground"
|
|
1060
|
+
isAnimating ? "" : "text-muted-foreground",
|
|
989
1061
|
)}
|
|
990
1062
|
onClick={() => setIsAnimating(!isAnimating)}
|
|
991
1063
|
/>
|
|
@@ -993,7 +1065,7 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
|
|
|
993
1065
|
</Popover>
|
|
994
1066
|
</>
|
|
995
1067
|
);
|
|
996
|
-
}
|
|
1068
|
+
},
|
|
997
1069
|
);
|
|
998
1070
|
|
|
999
1071
|
MultiSelect.displayName = "MultiSelect";
|
|
@@ -6,9 +6,11 @@ import { cn } from "@/lib/utils";
|
|
|
6
6
|
const navigationBarVariants = cva("flex w-full", {
|
|
7
7
|
variants: {
|
|
8
8
|
variant: {
|
|
9
|
-
default: "justify-between border
|
|
10
|
-
transparent:
|
|
11
|
-
|
|
9
|
+
default: "border-border bg-background justify-between border shadow-sm",
|
|
10
|
+
transparent:
|
|
11
|
+
"border-border justify-between border bg-transparent shadow-sm",
|
|
12
|
+
menuBar:
|
|
13
|
+
"border-border bg-background relative h-9 gap-2 rounded-full border font-medium shadow-sm",
|
|
12
14
|
},
|
|
13
15
|
},
|
|
14
16
|
defaultVariants: {
|
|
@@ -17,20 +19,22 @@ const navigationBarVariants = cva("flex w-full", {
|
|
|
17
19
|
});
|
|
18
20
|
|
|
19
21
|
const navigationItemVariants = cva(
|
|
20
|
-
"flex items-center justify-center whitespace-nowrap
|
|
22
|
+
"flex cursor-pointer items-center justify-center font-medium whitespace-nowrap transition-all disabled:pointer-events-none disabled:opacity-50",
|
|
21
23
|
{
|
|
22
24
|
variants: {
|
|
23
25
|
variant: {
|
|
24
|
-
default: "text-
|
|
25
|
-
active: "text-
|
|
26
|
-
menuBarDefault:
|
|
27
|
-
|
|
26
|
+
default: "text-muted-foreground hover:text-foreground text-sm",
|
|
27
|
+
active: "text-primary bg-muted text-sm",
|
|
28
|
+
menuBarDefault:
|
|
29
|
+
"text-foreground hover:text-primary relative z-[1] w-full rounded-full px-3 py-1.5 text-sm",
|
|
30
|
+
menuBarActive:
|
|
31
|
+
"text-primary relative z-[1] w-full rounded-full px-3 py-1.5 text-sm",
|
|
28
32
|
},
|
|
29
33
|
},
|
|
30
34
|
defaultVariants: {
|
|
31
35
|
variant: "default",
|
|
32
36
|
},
|
|
33
|
-
}
|
|
37
|
+
},
|
|
34
38
|
);
|
|
35
39
|
|
|
36
40
|
export interface NavigationBarProps
|
|
@@ -53,9 +57,16 @@ const NavigationBar = React.forwardRef<HTMLElement, NavigationBarProps>(
|
|
|
53
57
|
|
|
54
58
|
// Function to update the indicator position and size based on the active button
|
|
55
59
|
const updateIndicatorPosition = React.useCallback(() => {
|
|
56
|
-
if (
|
|
57
|
-
|
|
58
|
-
|
|
60
|
+
if (
|
|
61
|
+
variant !== "menuBar" ||
|
|
62
|
+
!containerRef.current ||
|
|
63
|
+
!indicatorRef.current
|
|
64
|
+
)
|
|
65
|
+
return;
|
|
66
|
+
|
|
67
|
+
const activeButton = containerRef.current.querySelector(
|
|
68
|
+
`[data-active="true"]`,
|
|
69
|
+
) as HTMLElement;
|
|
59
70
|
if (activeButton) {
|
|
60
71
|
indicatorRef.current.style.width = `${activeButton.offsetWidth}px`;
|
|
61
72
|
indicatorRef.current.style.left = `${activeButton.offsetLeft}px`;
|
|
@@ -65,7 +76,7 @@ const NavigationBar = React.forwardRef<HTMLElement, NavigationBarProps>(
|
|
|
65
76
|
// Create ResizeObserver to handle indicator container size changes
|
|
66
77
|
React.useEffect(() => {
|
|
67
78
|
if (variant !== "menuBar") return;
|
|
68
|
-
|
|
79
|
+
|
|
69
80
|
updateIndicatorPosition();
|
|
70
81
|
|
|
71
82
|
const resizeObserver = new ResizeObserver(updateIndicatorPosition);
|
|
@@ -80,21 +91,21 @@ const NavigationBar = React.forwardRef<HTMLElement, NavigationBarProps>(
|
|
|
80
91
|
}, [activeValue, updateIndicatorPosition, variant]);
|
|
81
92
|
|
|
82
93
|
return (
|
|
83
|
-
<nav
|
|
84
|
-
ref={ref || containerRef}
|
|
85
|
-
className={cn(navigationBarVariants({ variant, className }))}
|
|
94
|
+
<nav
|
|
95
|
+
ref={ref || containerRef}
|
|
96
|
+
className={cn(navigationBarVariants({ variant, className }))}
|
|
86
97
|
{...props}
|
|
87
98
|
>
|
|
88
99
|
{variant === "menuBar" && (
|
|
89
100
|
<div
|
|
90
101
|
ref={indicatorRef}
|
|
91
|
-
className="absolute bottom-0 h-full origin-left rounded-full
|
|
102
|
+
className="bg-secondary absolute bottom-0 h-full origin-left rounded-full transition-all duration-300"
|
|
92
103
|
/>
|
|
93
104
|
)}
|
|
94
105
|
{children}
|
|
95
106
|
</nav>
|
|
96
107
|
);
|
|
97
|
-
}
|
|
108
|
+
},
|
|
98
109
|
);
|
|
99
110
|
|
|
100
111
|
NavigationBar.displayName = "NavigationBar";
|
|
@@ -110,7 +121,8 @@ const NavigationItem = React.forwardRef<HTMLButtonElement, NavigationItemProps>(
|
|
|
110
121
|
};
|
|
111
122
|
|
|
112
123
|
const appliedVariant = getItemVariant();
|
|
113
|
-
const isMenuBar =
|
|
124
|
+
const isMenuBar =
|
|
125
|
+
appliedVariant === "menuBarDefault" || appliedVariant === "menuBarActive";
|
|
114
126
|
|
|
115
127
|
return (
|
|
116
128
|
<button
|
|
@@ -122,14 +134,19 @@ const NavigationItem = React.forwardRef<HTMLButtonElement, NavigationItemProps>(
|
|
|
122
134
|
variant: appliedVariant,
|
|
123
135
|
className,
|
|
124
136
|
}),
|
|
125
|
-
!isMenuBar && "px-4 py-2
|
|
137
|
+
!isMenuBar && "rounded-md px-4 py-2",
|
|
126
138
|
)}
|
|
127
139
|
{...props}
|
|
128
140
|
/>
|
|
129
141
|
);
|
|
130
|
-
}
|
|
142
|
+
},
|
|
131
143
|
);
|
|
132
144
|
|
|
133
145
|
NavigationItem.displayName = "NavigationItem";
|
|
134
146
|
|
|
135
|
-
export {
|
|
147
|
+
export {
|
|
148
|
+
NavigationBar,
|
|
149
|
+
NavigationItem,
|
|
150
|
+
navigationBarVariants,
|
|
151
|
+
navigationItemVariants,
|
|
152
|
+
};
|