myoperator-ui 0.0.82 → 0.0.84
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/index.js +273 -150
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -221,22 +221,22 @@ import { Loader2 } from "lucide-react"
|
|
|
221
221
|
import { cn } from "../../lib/utils"
|
|
222
222
|
|
|
223
223
|
const buttonVariants = cva(
|
|
224
|
-
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded text-sm font-medium transition-all duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-
|
|
224
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded text-sm font-medium transition-all duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#343E55] focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
225
225
|
{
|
|
226
226
|
variants: {
|
|
227
227
|
variant: {
|
|
228
|
-
default: "bg-[#343E55] text-white hover:bg-[#
|
|
229
|
-
primary: "bg-[#343E55] text-white hover:bg-[#
|
|
228
|
+
default: "bg-[#343E55] text-white hover:bg-[#2F384D]",
|
|
229
|
+
primary: "bg-[#343E55] text-white hover:bg-[#2F384D]",
|
|
230
230
|
destructive:
|
|
231
|
-
"bg-
|
|
231
|
+
"bg-[#F04438] text-white hover:bg-[#D92D20]",
|
|
232
232
|
outline:
|
|
233
233
|
"border border-[#343E55] bg-transparent text-[#343E55] hover:bg-[#343E55] hover:text-white",
|
|
234
234
|
secondary:
|
|
235
|
-
"bg-[#
|
|
236
|
-
ghost: "text-[#
|
|
235
|
+
"bg-[#EBECEE] text-[#343E55] hover:bg-[#D5D7DA]",
|
|
236
|
+
ghost: "text-[#717680] hover:bg-[#F5F5F5] hover:text-[#181D27]",
|
|
237
237
|
link: "text-[#343E55] underline-offset-4 hover:underline",
|
|
238
238
|
dashed:
|
|
239
|
-
"border border-dashed border-[#
|
|
239
|
+
"border border-dashed border-[#D5D7DA] bg-transparent text-[#717680] hover:border-[#343E55] hover:text-[#343E55] hover:bg-[#FAFAFA]",
|
|
240
240
|
},
|
|
241
241
|
size: {
|
|
242
242
|
default: "py-2.5 px-4 [&_svg]:size-4",
|
|
@@ -353,15 +353,15 @@ const badgeVariants = cva(
|
|
|
353
353
|
variants: {
|
|
354
354
|
variant: {
|
|
355
355
|
// Status-based variants (existing)
|
|
356
|
-
active: "bg-[#
|
|
357
|
-
failed: "bg-[#
|
|
358
|
-
disabled: "bg-[#
|
|
359
|
-
default: "bg-[#
|
|
360
|
-
primary: "bg-[#
|
|
356
|
+
active: "bg-[#ECFDF3] text-[#17B26A]",
|
|
357
|
+
failed: "bg-[#FEF3F2] text-[#F04438]",
|
|
358
|
+
disabled: "bg-[#F5F5F5] text-[#717680]",
|
|
359
|
+
default: "bg-[#F5F5F5] text-[#181D27]",
|
|
360
|
+
primary: "bg-[#F5F5F5] text-[#181D27]",
|
|
361
361
|
// shadcn-style variants (new)
|
|
362
|
-
secondary: "bg-[#
|
|
363
|
-
outline: "border border-[#
|
|
364
|
-
destructive: "bg-[#
|
|
362
|
+
secondary: "bg-[#F5F5F5] text-[#181D27]",
|
|
363
|
+
outline: "border border-[#E9EAEB] bg-transparent text-[#181D27]",
|
|
364
|
+
destructive: "bg-[#FEF3F2] text-[#F04438]",
|
|
365
365
|
},
|
|
366
366
|
size: {
|
|
367
367
|
default: "px-3 py-1",
|
|
@@ -462,12 +462,12 @@ import { cn } from "../../lib/utils"
|
|
|
462
462
|
* Input variants for different visual states
|
|
463
463
|
*/
|
|
464
464
|
const inputVariants = cva(
|
|
465
|
-
"h-10 w-full rounded bg-white px-4 py-2.5 text-sm text-[#
|
|
465
|
+
"h-10 w-full rounded bg-white px-4 py-2.5 text-sm text-[#181D27] transition-all file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-[#181D27] placeholder:text-[#A2A6B1] disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-[#FAFAFA]",
|
|
466
466
|
{
|
|
467
467
|
variants: {
|
|
468
468
|
state: {
|
|
469
|
-
default: "border border-[#
|
|
470
|
-
error: "border border-[#
|
|
469
|
+
default: "border border-[#E9EAEB] focus:outline-none focus:border-[#2BBCCA]/50 focus:shadow-[0_0_0_1px_rgba(43,188,202,0.15)]",
|
|
470
|
+
error: "border border-[#F04438]/40 focus:outline-none focus:border-[#F04438]/60 focus:shadow-[0_0_0_1px_rgba(240,68,56,0.1)]",
|
|
471
471
|
},
|
|
472
472
|
},
|
|
473
473
|
defaultVariants: {
|
|
@@ -533,12 +533,12 @@ import { cn } from "../../lib/utils"
|
|
|
533
533
|
* SelectTrigger variants matching TextField styling
|
|
534
534
|
*/
|
|
535
535
|
const selectTriggerVariants = cva(
|
|
536
|
-
"flex h-10 w-full items-center justify-between rounded bg-white px-4 py-2.5 text-sm text-[#
|
|
536
|
+
"flex h-10 w-full items-center justify-between rounded bg-white px-4 py-2.5 text-sm text-[#181D27] transition-all disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-[#FAFAFA] [&>span]:line-clamp-1",
|
|
537
537
|
{
|
|
538
538
|
variants: {
|
|
539
539
|
state: {
|
|
540
|
-
default: "border border-[#
|
|
541
|
-
error: "border border-[#
|
|
540
|
+
default: "border border-[#E9EAEB] focus:outline-none focus:border-[#2BBCCA]/50 focus:shadow-[0_0_0_1px_rgba(43,188,202,0.15)]",
|
|
541
|
+
error: "border border-[#F04438]/40 focus:outline-none focus:border-[#F04438]/60 focus:shadow-[0_0_0_1px_rgba(240,68,56,0.1)]",
|
|
542
542
|
},
|
|
543
543
|
},
|
|
544
544
|
defaultVariants: {
|
|
@@ -568,7 +568,7 @@ const SelectTrigger = React.forwardRef<
|
|
|
568
568
|
>
|
|
569
569
|
{children}
|
|
570
570
|
<SelectPrimitive.Icon asChild>
|
|
571
|
-
<ChevronDown className="size-4 text-[#
|
|
571
|
+
<ChevronDown className="size-4 text-[#717680] opacity-70" />
|
|
572
572
|
</SelectPrimitive.Icon>
|
|
573
573
|
</SelectPrimitive.Trigger>
|
|
574
574
|
))
|
|
@@ -586,7 +586,7 @@ const SelectScrollUpButton = React.forwardRef<
|
|
|
586
586
|
)}
|
|
587
587
|
{...props}
|
|
588
588
|
>
|
|
589
|
-
<ChevronUp className="size-4 text-[#
|
|
589
|
+
<ChevronUp className="size-4 text-[#717680]" />
|
|
590
590
|
</SelectPrimitive.ScrollUpButton>
|
|
591
591
|
))
|
|
592
592
|
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName
|
|
@@ -603,7 +603,7 @@ const SelectScrollDownButton = React.forwardRef<
|
|
|
603
603
|
)}
|
|
604
604
|
{...props}
|
|
605
605
|
>
|
|
606
|
-
<ChevronDown className="size-4 text-[#
|
|
606
|
+
<ChevronDown className="size-4 text-[#717680]" />
|
|
607
607
|
</SelectPrimitive.ScrollDownButton>
|
|
608
608
|
))
|
|
609
609
|
SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName
|
|
@@ -616,7 +616,7 @@ const SelectContent = React.forwardRef<
|
|
|
616
616
|
<SelectPrimitive.Content
|
|
617
617
|
ref={ref}
|
|
618
618
|
className={cn(
|
|
619
|
-
"relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded bg-white border border-[#
|
|
619
|
+
"relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded bg-white border border-[#E9EAEB] shadow-md",
|
|
620
620
|
"data-[state=open]:animate-in data-[state=closed]:animate-out",
|
|
621
621
|
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
622
622
|
"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
|
|
@@ -651,7 +651,7 @@ const SelectLabel = React.forwardRef<
|
|
|
651
651
|
>(({ className, ...props }, ref) => (
|
|
652
652
|
<SelectPrimitive.Label
|
|
653
653
|
ref={ref}
|
|
654
|
-
className={cn("px-4 py-1.5 text-xs font-medium text-[#
|
|
654
|
+
className={cn("px-4 py-1.5 text-xs font-medium text-[#717680]", className)}
|
|
655
655
|
{...props}
|
|
656
656
|
/>
|
|
657
657
|
))
|
|
@@ -664,8 +664,8 @@ const SelectItem = React.forwardRef<
|
|
|
664
664
|
<SelectPrimitive.Item
|
|
665
665
|
ref={ref}
|
|
666
666
|
className={cn(
|
|
667
|
-
"relative flex w-full cursor-pointer select-none items-center rounded-sm py-2 pl-4 pr-8 text-sm text-[#
|
|
668
|
-
"hover:bg-[#
|
|
667
|
+
"relative flex w-full cursor-pointer select-none items-center rounded-sm py-2 pl-4 pr-8 text-sm text-[#181D27] outline-none",
|
|
668
|
+
"hover:bg-[#F5F5F5] focus:bg-[#F5F5F5]",
|
|
669
669
|
"data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
670
670
|
className
|
|
671
671
|
)}
|
|
@@ -673,7 +673,7 @@ const SelectItem = React.forwardRef<
|
|
|
673
673
|
>
|
|
674
674
|
<span className="absolute right-2 flex size-4 items-center justify-center">
|
|
675
675
|
<SelectPrimitive.ItemIndicator>
|
|
676
|
-
<Check className="size-4 text-[#
|
|
676
|
+
<Check className="size-4 text-[#2BBCCA]" />
|
|
677
677
|
</SelectPrimitive.ItemIndicator>
|
|
678
678
|
</span>
|
|
679
679
|
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
|
|
@@ -687,7 +687,7 @@ const SelectSeparator = React.forwardRef<
|
|
|
687
687
|
>(({ className, ...props }, ref) => (
|
|
688
688
|
<SelectPrimitive.Separator
|
|
689
689
|
ref={ref}
|
|
690
|
-
className={cn("-mx-1 my-1 h-px bg-[#
|
|
690
|
+
className={cn("-mx-1 my-1 h-px bg-[#E9EAEB]", className)}
|
|
691
691
|
{...props}
|
|
692
692
|
/>
|
|
693
693
|
))
|
|
@@ -734,7 +734,7 @@ import { cn } from "../../lib/utils"
|
|
|
734
734
|
* Checkbox box variants (the outer container)
|
|
735
735
|
*/
|
|
736
736
|
const checkboxVariants = cva(
|
|
737
|
-
"peer inline-flex items-center justify-center shrink-0 rounded border-2 transition-colors duration-200 ease-in-out focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#343E55] focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-[#343E55] data-[state=checked]:border-[#343E55] data-[state=checked]:text-white data-[state=indeterminate]:bg-[#343E55] data-[state=indeterminate]:border-[#343E55] data-[state=indeterminate]:text-white data-[state=unchecked]:bg-white data-[state=unchecked]:border-[#
|
|
737
|
+
"peer inline-flex items-center justify-center shrink-0 rounded border-2 transition-colors duration-200 ease-in-out focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#343E55] focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-[#343E55] data-[state=checked]:border-[#343E55] data-[state=checked]:text-white data-[state=indeterminate]:bg-[#343E55] data-[state=indeterminate]:border-[#343E55] data-[state=indeterminate]:text-white data-[state=unchecked]:bg-white data-[state=unchecked]:border-[#E9EAEB] data-[state=unchecked]:hover:border-[#A4A7AE]",
|
|
738
738
|
{
|
|
739
739
|
variants: {
|
|
740
740
|
size: {
|
|
@@ -862,7 +862,7 @@ const Checkbox = React.forwardRef<
|
|
|
862
862
|
htmlFor={id}
|
|
863
863
|
className={cn(
|
|
864
864
|
labelSizeVariants({ size }),
|
|
865
|
-
"text-[#
|
|
865
|
+
"text-[#181D27] cursor-pointer",
|
|
866
866
|
disabled && "opacity-50 cursor-not-allowed",
|
|
867
867
|
labelClassName
|
|
868
868
|
)}
|
|
@@ -876,7 +876,7 @@ const Checkbox = React.forwardRef<
|
|
|
876
876
|
htmlFor={id}
|
|
877
877
|
className={cn(
|
|
878
878
|
labelSizeVariants({ size }),
|
|
879
|
-
"text-[#
|
|
879
|
+
"text-[#181D27] cursor-pointer",
|
|
880
880
|
disabled && "opacity-50 cursor-not-allowed",
|
|
881
881
|
labelClassName
|
|
882
882
|
)}
|
|
@@ -892,13 +892,13 @@ const Checkbox = React.forwardRef<
|
|
|
892
892
|
return (
|
|
893
893
|
<label className={cn("inline-flex items-center gap-2 cursor-pointer", disabled && "cursor-not-allowed")}>
|
|
894
894
|
{labelPosition === "left" && (
|
|
895
|
-
<span className={cn(labelSizeVariants({ size }), "text-[#
|
|
895
|
+
<span className={cn(labelSizeVariants({ size }), "text-[#181D27]", disabled && "opacity-50", labelClassName)}>
|
|
896
896
|
{label}
|
|
897
897
|
</span>
|
|
898
898
|
)}
|
|
899
899
|
{checkbox}
|
|
900
900
|
{labelPosition === "right" && (
|
|
901
|
-
<span className={cn(labelSizeVariants({ size }), "text-[#
|
|
901
|
+
<span className={cn(labelSizeVariants({ size }), "text-[#181D27]", disabled && "opacity-50", labelClassName)}>
|
|
902
902
|
{label}
|
|
903
903
|
</span>
|
|
904
904
|
)}
|
|
@@ -938,7 +938,7 @@ import { cn } from "../../lib/utils"
|
|
|
938
938
|
* Switch track variants (the outer container)
|
|
939
939
|
*/
|
|
940
940
|
const switchVariants = cva(
|
|
941
|
-
"peer inline-flex shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#343E55] focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-[#343E55] data-[state=unchecked]:bg-[#
|
|
941
|
+
"peer inline-flex shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#343E55] focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-[#343E55] data-[state=unchecked]:bg-[#E9EAEB]",
|
|
942
942
|
{
|
|
943
943
|
variants: {
|
|
944
944
|
size: {
|
|
@@ -1042,7 +1042,7 @@ const Switch = React.forwardRef<
|
|
|
1042
1042
|
{labelPosition === "left" && (
|
|
1043
1043
|
<span className={cn(
|
|
1044
1044
|
labelSizeVariants({ size }),
|
|
1045
|
-
"text-[#
|
|
1045
|
+
"text-[#181D27]",
|
|
1046
1046
|
disabled && "opacity-50"
|
|
1047
1047
|
)}>
|
|
1048
1048
|
{label}
|
|
@@ -1052,7 +1052,7 @@ const Switch = React.forwardRef<
|
|
|
1052
1052
|
{labelPosition === "right" && (
|
|
1053
1053
|
<span className={cn(
|
|
1054
1054
|
labelSizeVariants({ size }),
|
|
1055
|
-
"text-[#
|
|
1055
|
+
"text-[#181D27]",
|
|
1056
1056
|
disabled && "opacity-50"
|
|
1057
1057
|
)}>
|
|
1058
1058
|
{label}
|
|
@@ -1098,11 +1098,11 @@ const textFieldContainerVariants = cva(
|
|
|
1098
1098
|
{
|
|
1099
1099
|
variants: {
|
|
1100
1100
|
state: {
|
|
1101
|
-
default: "border border-[#
|
|
1102
|
-
error: "border border-[#
|
|
1101
|
+
default: "border border-[#E9EAEB] focus-within:border-[#2BBCCA]/50 focus-within:shadow-[0_0_0_1px_rgba(43,188,202,0.15)]",
|
|
1102
|
+
error: "border border-[#F04438]/40 focus-within:border-[#F04438]/60 focus-within:shadow-[0_0_0_1px_rgba(240,68,56,0.1)]",
|
|
1103
1103
|
},
|
|
1104
1104
|
disabled: {
|
|
1105
|
-
true: "cursor-not-allowed opacity-50 bg-[#
|
|
1105
|
+
true: "cursor-not-allowed opacity-50 bg-[#FAFAFA]",
|
|
1106
1106
|
false: "",
|
|
1107
1107
|
},
|
|
1108
1108
|
},
|
|
@@ -1117,12 +1117,12 @@ const textFieldContainerVariants = cva(
|
|
|
1117
1117
|
* TextField input variants (standalone without container)
|
|
1118
1118
|
*/
|
|
1119
1119
|
const textFieldInputVariants = cva(
|
|
1120
|
-
"h-10 w-full rounded bg-white px-4 py-2.5 text-sm text-[#
|
|
1120
|
+
"h-10 w-full rounded bg-white px-4 py-2.5 text-sm text-[#181D27] transition-all file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-[#181D27] placeholder:text-[#A2A6B1] disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-[#FAFAFA]",
|
|
1121
1121
|
{
|
|
1122
1122
|
variants: {
|
|
1123
1123
|
state: {
|
|
1124
|
-
default: "border border-[#
|
|
1125
|
-
error: "border border-[#
|
|
1124
|
+
default: "border border-[#E9EAEB] focus:outline-none focus:border-[#2BBCCA]/50 focus:shadow-[0_0_0_1px_rgba(43,188,202,0.15)]",
|
|
1125
|
+
error: "border border-[#F04438]/40 focus:outline-none focus:border-[#F04438]/60 focus:shadow-[0_0_0_1px_rgba(240,68,56,0.1)]",
|
|
1126
1126
|
},
|
|
1127
1127
|
},
|
|
1128
1128
|
defaultVariants: {
|
|
@@ -1240,7 +1240,7 @@ const TextField = React.forwardRef<HTMLInputElement, TextFieldProps>(
|
|
|
1240
1240
|
id={inputId}
|
|
1241
1241
|
className={cn(
|
|
1242
1242
|
hasAddons
|
|
1243
|
-
? "flex-1 bg-transparent border-0 outline-none focus:ring-0 px-0 h-full text-sm text-[#
|
|
1243
|
+
? "flex-1 bg-transparent border-0 outline-none focus:ring-0 px-0 h-full text-sm text-[#181D27] placeholder:text-[#A2A6B1] disabled:cursor-not-allowed"
|
|
1244
1244
|
: textFieldInputVariants({ state: derivedState, className })
|
|
1245
1245
|
)}
|
|
1246
1246
|
disabled={disabled || loading}
|
|
@@ -1260,10 +1260,10 @@ const TextField = React.forwardRef<HTMLInputElement, TextFieldProps>(
|
|
|
1260
1260
|
{label && (
|
|
1261
1261
|
<label
|
|
1262
1262
|
htmlFor={inputId}
|
|
1263
|
-
className={cn("text-sm font-medium text-[#
|
|
1263
|
+
className={cn("text-sm font-medium text-[#181D27]", labelClassName)}
|
|
1264
1264
|
>
|
|
1265
1265
|
{label}
|
|
1266
|
-
{required && <span className="text-[#
|
|
1266
|
+
{required && <span className="text-[#F04438] ml-0.5">*</span>}
|
|
1267
1267
|
</label>
|
|
1268
1268
|
)}
|
|
1269
1269
|
|
|
@@ -1276,12 +1276,12 @@ const TextField = React.forwardRef<HTMLInputElement, TextFieldProps>(
|
|
|
1276
1276
|
inputContainerClassName
|
|
1277
1277
|
)}
|
|
1278
1278
|
>
|
|
1279
|
-
{prefix && <span className="text-sm text-[#
|
|
1280
|
-
{leftIcon && <span className="mr-2 text-[#
|
|
1279
|
+
{prefix && <span className="text-sm text-[#717680] mr-2 select-none">{prefix}</span>}
|
|
1280
|
+
{leftIcon && <span className="mr-2 text-[#717680] [&_svg]:size-4 flex-shrink-0">{leftIcon}</span>}
|
|
1281
1281
|
{inputElement}
|
|
1282
|
-
{loading && <Loader2 className="animate-spin size-4 text-[#
|
|
1283
|
-
{!loading && rightIcon && <span className="ml-2 text-[#
|
|
1284
|
-
{suffix && <span className="text-sm text-[#
|
|
1282
|
+
{loading && <Loader2 className="animate-spin size-4 text-[#717680] ml-2 flex-shrink-0" />}
|
|
1283
|
+
{!loading && rightIcon && <span className="ml-2 text-[#717680] [&_svg]:size-4 flex-shrink-0">{rightIcon}</span>}
|
|
1284
|
+
{suffix && <span className="text-sm text-[#717680] ml-2 select-none">{suffix}</span>}
|
|
1285
1285
|
</div>
|
|
1286
1286
|
) : (
|
|
1287
1287
|
inputElement
|
|
@@ -1291,11 +1291,11 @@ const TextField = React.forwardRef<HTMLInputElement, TextFieldProps>(
|
|
|
1291
1291
|
{(error || helperText || (showCount && maxLength)) && (
|
|
1292
1292
|
<div className="flex justify-between items-start gap-2">
|
|
1293
1293
|
{error ? (
|
|
1294
|
-
<span id={errorId} className="text-xs text-[#
|
|
1294
|
+
<span id={errorId} className="text-xs text-[#F04438]">
|
|
1295
1295
|
{error}
|
|
1296
1296
|
</span>
|
|
1297
1297
|
) : helperText ? (
|
|
1298
|
-
<span id={helperId} className="text-xs text-[#
|
|
1298
|
+
<span id={helperId} className="text-xs text-[#717680]">
|
|
1299
1299
|
{helperText}
|
|
1300
1300
|
</span>
|
|
1301
1301
|
) : (
|
|
@@ -1305,7 +1305,7 @@ const TextField = React.forwardRef<HTMLInputElement, TextFieldProps>(
|
|
|
1305
1305
|
<span
|
|
1306
1306
|
className={cn(
|
|
1307
1307
|
"text-xs",
|
|
1308
|
-
charCount > maxLength ? "text-[#
|
|
1308
|
+
charCount > maxLength ? "text-[#F04438]" : "text-[#717680]"
|
|
1309
1309
|
)}
|
|
1310
1310
|
>
|
|
1311
1311
|
{charCount}/{maxLength}
|
|
@@ -1502,10 +1502,10 @@ const SelectField = React.forwardRef<HTMLButtonElement, SelectFieldProps>(
|
|
|
1502
1502
|
{label && (
|
|
1503
1503
|
<label
|
|
1504
1504
|
htmlFor={selectId}
|
|
1505
|
-
className={cn("text-sm font-medium text-[#
|
|
1505
|
+
className={cn("text-sm font-medium text-[#181D27]", labelClassName)}
|
|
1506
1506
|
>
|
|
1507
1507
|
{label}
|
|
1508
|
-
{required && <span className="text-[#
|
|
1508
|
+
{required && <span className="text-[#F04438] ml-0.5">*</span>}
|
|
1509
1509
|
</label>
|
|
1510
1510
|
)}
|
|
1511
1511
|
|
|
@@ -1531,7 +1531,7 @@ const SelectField = React.forwardRef<HTMLButtonElement, SelectFieldProps>(
|
|
|
1531
1531
|
>
|
|
1532
1532
|
<SelectValue placeholder={placeholder} />
|
|
1533
1533
|
{loading && (
|
|
1534
|
-
<Loader2 className="absolute right-8 size-4 animate-spin text-[#
|
|
1534
|
+
<Loader2 className="absolute right-8 size-4 animate-spin text-[#717680]" />
|
|
1535
1535
|
)}
|
|
1536
1536
|
</SelectTrigger>
|
|
1537
1537
|
<SelectContent>
|
|
@@ -1543,7 +1543,7 @@ const SelectField = React.forwardRef<HTMLButtonElement, SelectFieldProps>(
|
|
|
1543
1543
|
placeholder={searchPlaceholder}
|
|
1544
1544
|
value={searchQuery}
|
|
1545
1545
|
onChange={handleSearchChange}
|
|
1546
|
-
className="w-full h-8 px-3 text-sm border border-[#
|
|
1546
|
+
className="w-full h-8 px-3 text-sm border border-[#E9EAEB] rounded bg-white placeholder:text-[#A2A6B1] focus:outline-none focus:border-[#2BBCCA]/50"
|
|
1547
1547
|
// Prevent closing dropdown when clicking input
|
|
1548
1548
|
onClick={(e) => e.stopPropagation()}
|
|
1549
1549
|
onKeyDown={(e) => e.stopPropagation()}
|
|
@@ -1584,7 +1584,7 @@ const SelectField = React.forwardRef<HTMLButtonElement, SelectFieldProps>(
|
|
|
1584
1584
|
searchQuery &&
|
|
1585
1585
|
groupedOptions.ungrouped.length === 0 &&
|
|
1586
1586
|
Object.keys(groupedOptions.groups).length === 0 && (
|
|
1587
|
-
<div className="py-6 text-center text-sm text-[#
|
|
1587
|
+
<div className="py-6 text-center text-sm text-[#717680]">
|
|
1588
1588
|
No results found
|
|
1589
1589
|
</div>
|
|
1590
1590
|
)}
|
|
@@ -1595,11 +1595,11 @@ const SelectField = React.forwardRef<HTMLButtonElement, SelectFieldProps>(
|
|
|
1595
1595
|
{(error || helperText) && (
|
|
1596
1596
|
<div className="flex justify-between items-start gap-2">
|
|
1597
1597
|
{error ? (
|
|
1598
|
-
<span id={errorId} className="text-xs text-[#
|
|
1598
|
+
<span id={errorId} className="text-xs text-[#F04438]">
|
|
1599
1599
|
{error}
|
|
1600
1600
|
</span>
|
|
1601
1601
|
) : helperText ? (
|
|
1602
|
-
<span id={helperId} className="text-xs text-[#
|
|
1602
|
+
<span id={helperId} className="text-xs text-[#717680]">
|
|
1603
1603
|
{helperText}
|
|
1604
1604
|
</span>
|
|
1605
1605
|
) : null}
|
|
@@ -1638,12 +1638,12 @@ import { cn } from "../../lib/utils"
|
|
|
1638
1638
|
* MultiSelect trigger variants matching TextField styling
|
|
1639
1639
|
*/
|
|
1640
1640
|
const multiSelectTriggerVariants = cva(
|
|
1641
|
-
"flex min-h-10 w-full items-center justify-between rounded bg-white px-4 py-2 text-sm text-[#
|
|
1641
|
+
"flex min-h-10 w-full items-center justify-between rounded bg-white px-4 py-2 text-sm text-[#181D27] transition-all disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-[#FAFAFA]",
|
|
1642
1642
|
{
|
|
1643
1643
|
variants: {
|
|
1644
1644
|
state: {
|
|
1645
|
-
default: "border border-[#
|
|
1646
|
-
error: "border border-[#
|
|
1645
|
+
default: "border border-[#E9EAEB] focus:outline-none focus:border-[#2BBCCA]/50 focus:shadow-[0_0_0_1px_rgba(43,188,202,0.15)]",
|
|
1646
|
+
error: "border border-[#F04438]/40 focus:outline-none focus:border-[#F04438]/60 focus:shadow-[0_0_0_1px_rgba(240,68,56,0.1)]",
|
|
1647
1647
|
},
|
|
1648
1648
|
},
|
|
1649
1649
|
defaultVariants: {
|
|
@@ -1854,10 +1854,10 @@ const MultiSelect = React.forwardRef<HTMLButtonElement, MultiSelectProps>(
|
|
|
1854
1854
|
{label && (
|
|
1855
1855
|
<label
|
|
1856
1856
|
htmlFor={selectId}
|
|
1857
|
-
className={cn("text-sm font-medium text-[#
|
|
1857
|
+
className={cn("text-sm font-medium text-[#181D27]", labelClassName)}
|
|
1858
1858
|
>
|
|
1859
1859
|
{label}
|
|
1860
|
-
{required && <span className="text-[#
|
|
1860
|
+
{required && <span className="text-[#F04438] ml-0.5">*</span>}
|
|
1861
1861
|
</label>
|
|
1862
1862
|
)}
|
|
1863
1863
|
|
|
@@ -1882,12 +1882,12 @@ const MultiSelect = React.forwardRef<HTMLButtonElement, MultiSelectProps>(
|
|
|
1882
1882
|
>
|
|
1883
1883
|
<div className="flex-1 flex flex-wrap gap-1">
|
|
1884
1884
|
{selectedValues.length === 0 ? (
|
|
1885
|
-
<span className="text-[#
|
|
1885
|
+
<span className="text-[#A2A6B1]">{placeholder}</span>
|
|
1886
1886
|
) : (
|
|
1887
1887
|
selectedLabels.map((label, index) => (
|
|
1888
1888
|
<span
|
|
1889
1889
|
key={selectedValues[index]}
|
|
1890
|
-
className="inline-flex items-center gap-1 bg-[#
|
|
1890
|
+
className="inline-flex items-center gap-1 bg-[#F5F5F5] text-[#181D27] text-xs px-2 py-0.5 rounded"
|
|
1891
1891
|
>
|
|
1892
1892
|
{label}
|
|
1893
1893
|
<span
|
|
@@ -1900,7 +1900,7 @@ const MultiSelect = React.forwardRef<HTMLButtonElement, MultiSelectProps>(
|
|
|
1900
1900
|
removeValue(selectedValues[index], e as unknown as React.MouseEvent)
|
|
1901
1901
|
}
|
|
1902
1902
|
}}
|
|
1903
|
-
className="cursor-pointer hover:text-[#
|
|
1903
|
+
className="cursor-pointer hover:text-[#F04438] focus:outline-none"
|
|
1904
1904
|
aria-label={\`Remove \${label}\`}
|
|
1905
1905
|
>
|
|
1906
1906
|
<X className="size-3" />
|
|
@@ -1921,18 +1921,18 @@ const MultiSelect = React.forwardRef<HTMLButtonElement, MultiSelectProps>(
|
|
|
1921
1921
|
clearAll(e as unknown as React.MouseEvent)
|
|
1922
1922
|
}
|
|
1923
1923
|
}}
|
|
1924
|
-
className="p-0.5 cursor-pointer hover:text-[#
|
|
1924
|
+
className="p-0.5 cursor-pointer hover:text-[#F04438] focus:outline-none"
|
|
1925
1925
|
aria-label="Clear all"
|
|
1926
1926
|
>
|
|
1927
|
-
<X className="size-4 text-[#
|
|
1927
|
+
<X className="size-4 text-[#717680]" />
|
|
1928
1928
|
</span>
|
|
1929
1929
|
)}
|
|
1930
1930
|
{loading ? (
|
|
1931
|
-
<Loader2 className="size-4 animate-spin text-[#
|
|
1931
|
+
<Loader2 className="size-4 animate-spin text-[#717680]" />
|
|
1932
1932
|
) : (
|
|
1933
1933
|
<ChevronDown
|
|
1934
1934
|
className={cn(
|
|
1935
|
-
"size-4 text-[#
|
|
1935
|
+
"size-4 text-[#717680] transition-transform",
|
|
1936
1936
|
isOpen && "rotate-180"
|
|
1937
1937
|
)}
|
|
1938
1938
|
/>
|
|
@@ -1944,7 +1944,7 @@ const MultiSelect = React.forwardRef<HTMLButtonElement, MultiSelectProps>(
|
|
|
1944
1944
|
{isOpen && (
|
|
1945
1945
|
<div
|
|
1946
1946
|
className={cn(
|
|
1947
|
-
"absolute z-50 mt-1 w-full rounded bg-white border border-[#
|
|
1947
|
+
"absolute z-50 mt-1 w-full rounded bg-white border border-[#E9EAEB] shadow-md",
|
|
1948
1948
|
"top-full"
|
|
1949
1949
|
)}
|
|
1950
1950
|
role="listbox"
|
|
@@ -1952,13 +1952,13 @@ const MultiSelect = React.forwardRef<HTMLButtonElement, MultiSelectProps>(
|
|
|
1952
1952
|
>
|
|
1953
1953
|
{/* Search input */}
|
|
1954
1954
|
{searchable && (
|
|
1955
|
-
<div className="p-2 border-b border-[#
|
|
1955
|
+
<div className="p-2 border-b border-[#E9EAEB]">
|
|
1956
1956
|
<input
|
|
1957
1957
|
type="text"
|
|
1958
1958
|
placeholder={searchPlaceholder}
|
|
1959
1959
|
value={searchQuery}
|
|
1960
1960
|
onChange={(e) => setSearchQuery(e.target.value)}
|
|
1961
|
-
className="w-full h-8 px-3 text-sm border border-[#
|
|
1961
|
+
className="w-full h-8 px-3 text-sm border border-[#E9EAEB] rounded bg-white placeholder:text-[#A2A6B1] focus:outline-none focus:border-[#2BBCCA]/50"
|
|
1962
1962
|
onClick={(e) => e.stopPropagation()}
|
|
1963
1963
|
/>
|
|
1964
1964
|
</div>
|
|
@@ -1967,7 +1967,7 @@ const MultiSelect = React.forwardRef<HTMLButtonElement, MultiSelectProps>(
|
|
|
1967
1967
|
{/* Options */}
|
|
1968
1968
|
<div className="max-h-60 overflow-auto p-1">
|
|
1969
1969
|
{filteredOptions.length === 0 ? (
|
|
1970
|
-
<div className="py-6 text-center text-sm text-[#
|
|
1970
|
+
<div className="py-6 text-center text-sm text-[#717680]">
|
|
1971
1971
|
No results found
|
|
1972
1972
|
</div>
|
|
1973
1973
|
) : (
|
|
@@ -1986,14 +1986,14 @@ const MultiSelect = React.forwardRef<HTMLButtonElement, MultiSelectProps>(
|
|
|
1986
1986
|
disabled={isDisabled}
|
|
1987
1987
|
onClick={() => !isDisabled && toggleOption(option.value)}
|
|
1988
1988
|
className={cn(
|
|
1989
|
-
"relative flex w-full cursor-pointer select-none items-center rounded-sm py-2 pl-4 pr-8 text-sm text-[#
|
|
1990
|
-
"hover:bg-[#
|
|
1991
|
-
isSelected && "bg-[#
|
|
1989
|
+
"relative flex w-full cursor-pointer select-none items-center rounded-sm py-2 pl-4 pr-8 text-sm text-[#181D27] outline-none",
|
|
1990
|
+
"hover:bg-[#F5F5F5] focus:bg-[#F5F5F5]",
|
|
1991
|
+
isSelected && "bg-[#F5F5F5]",
|
|
1992
1992
|
isDisabled && "pointer-events-none opacity-50"
|
|
1993
1993
|
)}
|
|
1994
1994
|
>
|
|
1995
1995
|
<span className="absolute right-2 flex size-4 items-center justify-center">
|
|
1996
|
-
{isSelected && <Check className="size-4 text-[#
|
|
1996
|
+
{isSelected && <Check className="size-4 text-[#2BBCCA]" />}
|
|
1997
1997
|
</span>
|
|
1998
1998
|
{option.label}
|
|
1999
1999
|
</button>
|
|
@@ -2004,7 +2004,7 @@ const MultiSelect = React.forwardRef<HTMLButtonElement, MultiSelectProps>(
|
|
|
2004
2004
|
|
|
2005
2005
|
{/* Footer with count */}
|
|
2006
2006
|
{maxSelections && (
|
|
2007
|
-
<div className="p-2 border-t border-[#
|
|
2007
|
+
<div className="p-2 border-t border-[#E9EAEB] text-xs text-[#717680]">
|
|
2008
2008
|
{selectedValues.length} / {maxSelections} selected
|
|
2009
2009
|
</div>
|
|
2010
2010
|
)}
|
|
@@ -2020,11 +2020,11 @@ const MultiSelect = React.forwardRef<HTMLButtonElement, MultiSelectProps>(
|
|
|
2020
2020
|
{(error || helperText) && (
|
|
2021
2021
|
<div className="flex justify-between items-start gap-2">
|
|
2022
2022
|
{error ? (
|
|
2023
|
-
<span id={errorId} className="text-xs text-[#
|
|
2023
|
+
<span id={errorId} className="text-xs text-[#F04438]">
|
|
2024
2024
|
{error}
|
|
2025
2025
|
</span>
|
|
2026
2026
|
) : helperText ? (
|
|
2027
|
-
<span id={helperId} className="text-xs text-[#
|
|
2027
|
+
<span id={helperId} className="text-xs text-[#717680]">
|
|
2028
2028
|
{helperText}
|
|
2029
2029
|
</span>
|
|
2030
2030
|
) : null}
|
|
@@ -2110,7 +2110,7 @@ const Table = React.forwardRef<HTMLTableElement, TableProps>(
|
|
|
2110
2110
|
({ className, size, withoutBorder, ...props }, ref) => (
|
|
2111
2111
|
<div className={cn(
|
|
2112
2112
|
"relative w-full overflow-auto",
|
|
2113
|
-
!withoutBorder && "rounded-lg border border-[#
|
|
2113
|
+
!withoutBorder && "rounded-lg border border-[#E9EAEB]"
|
|
2114
2114
|
)}>
|
|
2115
2115
|
<table
|
|
2116
2116
|
ref={ref}
|
|
@@ -2128,7 +2128,7 @@ const TableHeader = React.forwardRef<
|
|
|
2128
2128
|
>(({ className, ...props }, ref) => (
|
|
2129
2129
|
<thead
|
|
2130
2130
|
ref={ref}
|
|
2131
|
-
className={cn("bg-[#
|
|
2131
|
+
className={cn("bg-[#FAFAFA] [&_tr]:border-b", className)}
|
|
2132
2132
|
{...props}
|
|
2133
2133
|
/>
|
|
2134
2134
|
))
|
|
@@ -2153,7 +2153,7 @@ const TableFooter = React.forwardRef<
|
|
|
2153
2153
|
<tfoot
|
|
2154
2154
|
ref={ref}
|
|
2155
2155
|
className={cn(
|
|
2156
|
-
"border-t bg-[#
|
|
2156
|
+
"border-t bg-[#FAFAFA] font-medium [&>tr]:last:border-b-0",
|
|
2157
2157
|
className
|
|
2158
2158
|
)}
|
|
2159
2159
|
{...props}
|
|
@@ -2171,10 +2171,10 @@ const TableRow = React.forwardRef<HTMLTableRowElement, TableRowProps>(
|
|
|
2171
2171
|
<tr
|
|
2172
2172
|
ref={ref}
|
|
2173
2173
|
className={cn(
|
|
2174
|
-
"border-b border-[#
|
|
2174
|
+
"border-b border-[#E9EAEB] transition-colors",
|
|
2175
2175
|
highlighted
|
|
2176
|
-
? "bg-[#
|
|
2177
|
-
: "hover:bg-[#
|
|
2176
|
+
? "bg-[#ECF1FB]"
|
|
2177
|
+
: "hover:bg-[#FAFAFA]/50 data-[state=selected]:bg-[#F5F5F5]",
|
|
2178
2178
|
className
|
|
2179
2179
|
)}
|
|
2180
2180
|
{...props}
|
|
@@ -2197,8 +2197,8 @@ const TableHead = React.forwardRef<HTMLTableCellElement, TableHeadProps>(
|
|
|
2197
2197
|
<th
|
|
2198
2198
|
ref={ref}
|
|
2199
2199
|
className={cn(
|
|
2200
|
-
"h-12 px-4 text-left align-middle font-medium text-[#
|
|
2201
|
-
sticky && "sticky left-0 bg-[#
|
|
2200
|
+
"h-12 px-4 text-left align-middle font-medium text-[#717680] text-sm [&:has([role=checkbox])]:pr-0",
|
|
2201
|
+
sticky && "sticky left-0 bg-[#FAFAFA] z-10",
|
|
2202
2202
|
sortDirection && "cursor-pointer select-none",
|
|
2203
2203
|
className
|
|
2204
2204
|
)}
|
|
@@ -2207,12 +2207,12 @@ const TableHead = React.forwardRef<HTMLTableCellElement, TableHeadProps>(
|
|
|
2207
2207
|
<div className="flex items-center gap-1">
|
|
2208
2208
|
{children}
|
|
2209
2209
|
{sortDirection && (
|
|
2210
|
-
<span className="text-[#
|
|
2210
|
+
<span className="text-[#A4A7AE]">
|
|
2211
2211
|
{sortDirection === 'asc' ? '\u2191' : '\u2193'}
|
|
2212
2212
|
</span>
|
|
2213
2213
|
)}
|
|
2214
2214
|
{infoTooltip && (
|
|
2215
|
-
<span className="text-[#
|
|
2215
|
+
<span className="text-[#A4A7AE] cursor-help" title={infoTooltip}>
|
|
2216
2216
|
\u24D8
|
|
2217
2217
|
</span>
|
|
2218
2218
|
)}
|
|
@@ -2232,7 +2232,7 @@ const TableCell = React.forwardRef<HTMLTableCellElement, TableCellProps>(
|
|
|
2232
2232
|
<td
|
|
2233
2233
|
ref={ref}
|
|
2234
2234
|
className={cn(
|
|
2235
|
-
"px-4 align-middle text-[#
|
|
2235
|
+
"px-4 align-middle text-[#181D27] [&:has([role=checkbox])]:pr-0",
|
|
2236
2236
|
sticky && "sticky left-0 bg-white z-10",
|
|
2237
2237
|
className
|
|
2238
2238
|
)}
|
|
@@ -2248,7 +2248,7 @@ const TableCaption = React.forwardRef<
|
|
|
2248
2248
|
>(({ className, ...props }, ref) => (
|
|
2249
2249
|
<caption
|
|
2250
2250
|
ref={ref}
|
|
2251
|
-
className={cn("mt-4 text-sm text-[#
|
|
2251
|
+
className={cn("mt-4 text-sm text-[#717680]", className)}
|
|
2252
2252
|
{...props}
|
|
2253
2253
|
/>
|
|
2254
2254
|
))
|
|
@@ -2270,7 +2270,7 @@ const TableSkeleton = ({ rows = 5, columns = 5 }: TableSkeletonProps) => (
|
|
|
2270
2270
|
<TableRow key={rowIndex}>
|
|
2271
2271
|
{Array.from({ length: columns }).map((_, colIndex) => (
|
|
2272
2272
|
<TableCell key={colIndex}>
|
|
2273
|
-
<div className="h-4 bg-[#
|
|
2273
|
+
<div className="h-4 bg-[#E9EAEB] rounded animate-pulse"
|
|
2274
2274
|
style={{ width: colIndex === 1 ? '80%' : colIndex === 2 ? '30%' : '60%' }} />
|
|
2275
2275
|
</TableCell>
|
|
2276
2276
|
))}
|
|
@@ -2292,7 +2292,7 @@ export interface TableEmptyProps {
|
|
|
2292
2292
|
|
|
2293
2293
|
const TableEmpty = ({ colSpan, children }: TableEmptyProps) => (
|
|
2294
2294
|
<TableRow>
|
|
2295
|
-
<TableCell colSpan={colSpan} className="text-center py-8 text-[#
|
|
2295
|
+
<TableCell colSpan={colSpan} className="text-center py-8 text-[#717680]">
|
|
2296
2296
|
{children || "No data available"}
|
|
2297
2297
|
</TableCell>
|
|
2298
2298
|
</TableRow>
|
|
@@ -2392,7 +2392,7 @@ const DropdownMenuSubTrigger = React.forwardRef<
|
|
|
2392
2392
|
<DropdownMenuPrimitive.SubTrigger
|
|
2393
2393
|
ref={ref}
|
|
2394
2394
|
className={cn(
|
|
2395
|
-
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-[#
|
|
2395
|
+
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-[#F5F5F5] data-[state=open]:bg-[#F5F5F5]",
|
|
2396
2396
|
inset && "pl-8",
|
|
2397
2397
|
className
|
|
2398
2398
|
)}
|
|
@@ -2412,7 +2412,7 @@ const DropdownMenuSubContent = React.forwardRef<
|
|
|
2412
2412
|
<DropdownMenuPrimitive.SubContent
|
|
2413
2413
|
ref={ref}
|
|
2414
2414
|
className={cn(
|
|
2415
|
-
"z-50 min-w-[8rem] overflow-hidden rounded-md border border-[#
|
|
2415
|
+
"z-50 min-w-[8rem] overflow-hidden rounded-md border border-[#E9EAEB] bg-white p-1 text-[#181D27] shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
2416
2416
|
className
|
|
2417
2417
|
)}
|
|
2418
2418
|
{...props}
|
|
@@ -2430,7 +2430,7 @@ const DropdownMenuContent = React.forwardRef<
|
|
|
2430
2430
|
ref={ref}
|
|
2431
2431
|
sideOffset={sideOffset}
|
|
2432
2432
|
className={cn(
|
|
2433
|
-
"z-50 min-w-[8rem] overflow-hidden rounded-md border border-[#
|
|
2433
|
+
"z-50 min-w-[8rem] overflow-hidden rounded-md border border-[#E9EAEB] bg-white p-1 text-[#181D27] shadow-md",
|
|
2434
2434
|
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
2435
2435
|
className
|
|
2436
2436
|
)}
|
|
@@ -2449,7 +2449,7 @@ const DropdownMenuItem = React.forwardRef<
|
|
|
2449
2449
|
<DropdownMenuPrimitive.Item
|
|
2450
2450
|
ref={ref}
|
|
2451
2451
|
className={cn(
|
|
2452
|
-
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-[#
|
|
2452
|
+
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-[#F5F5F5] focus:text-[#181D27] data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
2453
2453
|
inset && "pl-8",
|
|
2454
2454
|
className
|
|
2455
2455
|
)}
|
|
@@ -2465,7 +2465,7 @@ const DropdownMenuCheckboxItem = React.forwardRef<
|
|
|
2465
2465
|
<DropdownMenuPrimitive.CheckboxItem
|
|
2466
2466
|
ref={ref}
|
|
2467
2467
|
className={cn(
|
|
2468
|
-
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-[#
|
|
2468
|
+
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-[#F5F5F5] focus:text-[#181D27] data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
2469
2469
|
className
|
|
2470
2470
|
)}
|
|
2471
2471
|
checked={checked}
|
|
@@ -2489,7 +2489,7 @@ const DropdownMenuRadioItem = React.forwardRef<
|
|
|
2489
2489
|
<DropdownMenuPrimitive.RadioItem
|
|
2490
2490
|
ref={ref}
|
|
2491
2491
|
className={cn(
|
|
2492
|
-
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-[#
|
|
2492
|
+
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-[#F5F5F5] focus:text-[#181D27] data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
2493
2493
|
className
|
|
2494
2494
|
)}
|
|
2495
2495
|
{...props}
|
|
@@ -2528,7 +2528,7 @@ const DropdownMenuSeparator = React.forwardRef<
|
|
|
2528
2528
|
>(({ className, ...props }, ref) => (
|
|
2529
2529
|
<DropdownMenuPrimitive.Separator
|
|
2530
2530
|
ref={ref}
|
|
2531
|
-
className={cn("-mx-1 my-1 h-px bg-[#
|
|
2531
|
+
className={cn("-mx-1 my-1 h-px bg-[#E9EAEB]", className)}
|
|
2532
2532
|
{...props}
|
|
2533
2533
|
/>
|
|
2534
2534
|
))
|
|
@@ -2656,14 +2656,14 @@ const tagVariants = cva(
|
|
|
2656
2656
|
{
|
|
2657
2657
|
variants: {
|
|
2658
2658
|
variant: {
|
|
2659
|
-
default: "bg-[#
|
|
2660
|
-
primary: "bg-[#
|
|
2661
|
-
accent: "bg-[#
|
|
2662
|
-
secondary: "bg-[#
|
|
2663
|
-
success: "bg-[#
|
|
2664
|
-
warning: "bg-[#
|
|
2665
|
-
error: "bg-[#
|
|
2666
|
-
destructive: "bg-[#
|
|
2659
|
+
default: "bg-[#F5F5F5] text-[#181D27]",
|
|
2660
|
+
primary: "bg-[#F5F5F5] text-[#181D27]",
|
|
2661
|
+
accent: "bg-[#EBECEE] text-[#343E55]",
|
|
2662
|
+
secondary: "bg-[#E9EAEB] text-[#414651]",
|
|
2663
|
+
success: "bg-[#ECFDF3] text-[#17B26A]",
|
|
2664
|
+
warning: "bg-[#FFFAEB] text-[#F79009]",
|
|
2665
|
+
error: "bg-[#FEF3F2] text-[#F04438]",
|
|
2666
|
+
destructive: "bg-[#FEF3F2] text-[#F04438]",
|
|
2667
2667
|
},
|
|
2668
2668
|
size: {
|
|
2669
2669
|
default: "px-2 py-1",
|
|
@@ -2809,7 +2809,7 @@ const accordionVariants = cva("w-full", {
|
|
|
2809
2809
|
variants: {
|
|
2810
2810
|
variant: {
|
|
2811
2811
|
default: "",
|
|
2812
|
-
bordered: "border border-[#
|
|
2812
|
+
bordered: "border border-[#E9EAEB] rounded-lg divide-y divide-[#E9EAEB]",
|
|
2813
2813
|
},
|
|
2814
2814
|
},
|
|
2815
2815
|
defaultVariants: {
|
|
@@ -2841,7 +2841,7 @@ const accordionTriggerVariants = cva(
|
|
|
2841
2841
|
variants: {
|
|
2842
2842
|
variant: {
|
|
2843
2843
|
default: "py-3",
|
|
2844
|
-
bordered: "p-4 hover:bg-[#
|
|
2844
|
+
bordered: "p-4 hover:bg-[#FAFAFA]",
|
|
2845
2845
|
},
|
|
2846
2846
|
},
|
|
2847
2847
|
defaultVariants: {
|
|
@@ -3063,7 +3063,7 @@ const AccordionTrigger = React.forwardRef<HTMLButtonElement, AccordionTriggerPro
|
|
|
3063
3063
|
{showChevron && (
|
|
3064
3064
|
<ChevronDown
|
|
3065
3065
|
className={cn(
|
|
3066
|
-
"h-4 w-4 shrink-0 text-[#
|
|
3066
|
+
"h-4 w-4 shrink-0 text-[#717680] transition-transform duration-300",
|
|
3067
3067
|
isOpen && "rotate-180"
|
|
3068
3068
|
)}
|
|
3069
3069
|
/>
|
|
@@ -3140,15 +3140,16 @@ export {
|
|
|
3140
3140
|
name: "page-header.tsx",
|
|
3141
3141
|
content: prefixTailwindClasses(`import * as React from "react"
|
|
3142
3142
|
import { cva, type VariantProps } from "class-variance-authority"
|
|
3143
|
-
import { ArrowLeft } from "lucide-react"
|
|
3143
|
+
import { ArrowLeft, MoreHorizontal, X } from "lucide-react"
|
|
3144
3144
|
|
|
3145
3145
|
import { cn } from "../../lib/utils"
|
|
3146
|
+
import { Button } from "./button"
|
|
3146
3147
|
|
|
3147
3148
|
/**
|
|
3148
3149
|
* PageHeader variants for layout styles.
|
|
3149
3150
|
*/
|
|
3150
3151
|
const pageHeaderVariants = cva(
|
|
3151
|
-
"flex items-center w-full bg-white",
|
|
3152
|
+
"flex flex-col sm:flex-row sm:items-center w-full bg-white",
|
|
3152
3153
|
{
|
|
3153
3154
|
variants: {},
|
|
3154
3155
|
defaultVariants: {},
|
|
@@ -3204,6 +3205,10 @@ export interface PageHeaderProps
|
|
|
3204
3205
|
actions?: React.ReactNode
|
|
3205
3206
|
/** Show bottom border (default: true) */
|
|
3206
3207
|
showBorder?: boolean
|
|
3208
|
+
/** Layout mode: 'horizontal' (single row), 'vertical' (stacked), 'responsive' (auto based on screen size, default) */
|
|
3209
|
+
layout?: 'horizontal' | 'vertical' | 'responsive'
|
|
3210
|
+
/** Max actions to show on mobile before overflow (default: 2) */
|
|
3211
|
+
mobileOverflowLimit?: number
|
|
3207
3212
|
}
|
|
3208
3213
|
|
|
3209
3214
|
const PageHeader = React.forwardRef<HTMLDivElement, PageHeaderProps>(
|
|
@@ -3217,8 +3222,13 @@ const PageHeader = React.forwardRef<HTMLDivElement, PageHeaderProps>(
|
|
|
3217
3222
|
infoIcon,
|
|
3218
3223
|
actions,
|
|
3219
3224
|
showBorder = true,
|
|
3225
|
+
layout = 'responsive',
|
|
3226
|
+
mobileOverflowLimit = 2,
|
|
3220
3227
|
...props
|
|
3221
3228
|
}, ref) => {
|
|
3229
|
+
// State for overflow expansion (moved to top level)
|
|
3230
|
+
const [isOverflowExpanded, setIsOverflowExpanded] = React.useState(false)
|
|
3231
|
+
|
|
3222
3232
|
// Determine what to show on the left: back button, icon, or nothing
|
|
3223
3233
|
const renderLeftElement = () => {
|
|
3224
3234
|
if (showBackButton) {
|
|
@@ -3226,7 +3236,7 @@ const PageHeader = React.forwardRef<HTMLDivElement, PageHeaderProps>(
|
|
|
3226
3236
|
<button
|
|
3227
3237
|
type="button"
|
|
3228
3238
|
onClick={onBackClick}
|
|
3229
|
-
className="flex items-center justify-center w-10 h-10 rounded hover:bg-[#
|
|
3239
|
+
className="flex items-center justify-center w-10 h-10 rounded hover:bg-[#F5F5F5] transition-colors text-[#181D27]"
|
|
3230
3240
|
aria-label="Go back"
|
|
3231
3241
|
>
|
|
3232
3242
|
<ArrowLeft className="w-5 h-5" />
|
|
@@ -3235,7 +3245,7 @@ const PageHeader = React.forwardRef<HTMLDivElement, PageHeaderProps>(
|
|
|
3235
3245
|
}
|
|
3236
3246
|
if (icon) {
|
|
3237
3247
|
return (
|
|
3238
|
-
<div className="flex items-center justify-center w-10 h-10 [&_svg]:w-6 [&_svg]:h-6 text-[#
|
|
3248
|
+
<div className="flex items-center justify-center w-10 h-10 [&_svg]:w-6 [&_svg]:h-6 text-[#717680]">
|
|
3239
3249
|
{icon}
|
|
3240
3250
|
</div>
|
|
3241
3251
|
)
|
|
@@ -3245,49 +3255,162 @@ const PageHeader = React.forwardRef<HTMLDivElement, PageHeaderProps>(
|
|
|
3245
3255
|
|
|
3246
3256
|
const leftElement = renderLeftElement()
|
|
3247
3257
|
|
|
3258
|
+
// Flatten children recursively to handle fragments
|
|
3259
|
+
const flattenChildren = (children: React.ReactNode): React.ReactNode[] => {
|
|
3260
|
+
const result: React.ReactNode[] = []
|
|
3261
|
+
React.Children.forEach(children, (child) => {
|
|
3262
|
+
if (React.isValidElement(child) && child.type === React.Fragment) {
|
|
3263
|
+
result.push(...flattenChildren(child.props.children))
|
|
3264
|
+
} else if (child !== null && child !== undefined) {
|
|
3265
|
+
result.push(child)
|
|
3266
|
+
}
|
|
3267
|
+
})
|
|
3268
|
+
return result
|
|
3269
|
+
}
|
|
3270
|
+
|
|
3271
|
+
// Convert actions to array for overflow handling
|
|
3272
|
+
const actionsArray = flattenChildren(actions)
|
|
3273
|
+
const hasOverflow = actionsArray.length > mobileOverflowLimit
|
|
3274
|
+
const visibleActions = hasOverflow ? actionsArray.slice(0, mobileOverflowLimit) : actionsArray
|
|
3275
|
+
const overflowActions = hasOverflow ? actionsArray.slice(mobileOverflowLimit) : []
|
|
3276
|
+
|
|
3277
|
+
// Layout classes based on prop
|
|
3278
|
+
const layoutClasses = {
|
|
3279
|
+
horizontal: 'flex-row items-center',
|
|
3280
|
+
vertical: 'flex-col',
|
|
3281
|
+
responsive: 'flex-col sm:flex-row sm:items-center',
|
|
3282
|
+
}
|
|
3283
|
+
|
|
3284
|
+
const heightClasses = {
|
|
3285
|
+
horizontal: 'h-[76px]',
|
|
3286
|
+
vertical: 'min-h-[76px] py-4',
|
|
3287
|
+
responsive: 'min-h-[76px] py-4 sm:py-0 sm:h-[76px]',
|
|
3288
|
+
}
|
|
3289
|
+
|
|
3290
|
+
// Render actions for desktop (all inline)
|
|
3291
|
+
const renderDesktopActions = () => (
|
|
3292
|
+
<div className="hidden sm:flex items-center gap-2">
|
|
3293
|
+
{actionsArray}
|
|
3294
|
+
</div>
|
|
3295
|
+
)
|
|
3296
|
+
|
|
3297
|
+
// Render expandable actions (for mobile and vertical layout)
|
|
3298
|
+
const renderExpandableActions = (additionalClasses?: string) => {
|
|
3299
|
+
// Calculate grid columns: equal width for visible actions, smaller for overflow button
|
|
3300
|
+
const hasOverflowBtn = overflowActions.length > 0
|
|
3301
|
+
const gridCols = hasOverflowBtn
|
|
3302
|
+
? \`repeat(\${visibleActions.length}, 1fr) auto\`
|
|
3303
|
+
: \`repeat(\${visibleActions.length}, 1fr)\`
|
|
3304
|
+
|
|
3305
|
+
return (
|
|
3306
|
+
<div className={cn("flex flex-col gap-2 w-full", additionalClasses)}>
|
|
3307
|
+
{/* Visible actions row - full width grid */}
|
|
3308
|
+
<div className="grid gap-2" style={{ gridTemplateColumns: gridCols }}>
|
|
3309
|
+
{visibleActions.map((action, index) => (
|
|
3310
|
+
<div key={index} className="[&>*]:w-full [&>*]:h-9">
|
|
3311
|
+
{action}
|
|
3312
|
+
</div>
|
|
3313
|
+
))}
|
|
3314
|
+
{hasOverflowBtn && (
|
|
3315
|
+
<Button
|
|
3316
|
+
variant="outline"
|
|
3317
|
+
size="icon"
|
|
3318
|
+
className="h-9 w-9"
|
|
3319
|
+
onClick={() => setIsOverflowExpanded(!isOverflowExpanded)}
|
|
3320
|
+
aria-label={isOverflowExpanded ? "Show less" : "More actions"}
|
|
3321
|
+
aria-expanded={isOverflowExpanded}
|
|
3322
|
+
>
|
|
3323
|
+
{isOverflowExpanded ? <X className="w-4 h-4" /> : <MoreHorizontal className="w-4 h-4" />}
|
|
3324
|
+
</Button>
|
|
3325
|
+
)}
|
|
3326
|
+
</div>
|
|
3327
|
+
|
|
3328
|
+
{/* Expanded overflow actions - stacked full width */}
|
|
3329
|
+
{isOverflowExpanded && overflowActions.length > 0 && (
|
|
3330
|
+
<div className="flex flex-col gap-2">
|
|
3331
|
+
{overflowActions.map((action, index) => (
|
|
3332
|
+
<div key={index} className="[&>*]:w-full [&>*]:h-9">
|
|
3333
|
+
{action}
|
|
3334
|
+
</div>
|
|
3335
|
+
))}
|
|
3336
|
+
</div>
|
|
3337
|
+
)}
|
|
3338
|
+
</div>
|
|
3339
|
+
)
|
|
3340
|
+
}
|
|
3341
|
+
|
|
3342
|
+
// For horizontal layout, always show all actions inline
|
|
3343
|
+
const renderHorizontalActions = () => (
|
|
3344
|
+
<div className="flex items-center gap-2 ml-4">
|
|
3345
|
+
{actionsArray}
|
|
3346
|
+
</div>
|
|
3347
|
+
)
|
|
3348
|
+
|
|
3349
|
+
const renderActions = () => {
|
|
3350
|
+
if (!actions) return null
|
|
3351
|
+
|
|
3352
|
+
if (layout === 'horizontal') {
|
|
3353
|
+
return renderHorizontalActions()
|
|
3354
|
+
}
|
|
3355
|
+
|
|
3356
|
+
if (layout === 'vertical') {
|
|
3357
|
+
return renderExpandableActions("mt-3")
|
|
3358
|
+
}
|
|
3359
|
+
|
|
3360
|
+
// Responsive: render both, CSS handles visibility
|
|
3361
|
+
return (
|
|
3362
|
+
<>
|
|
3363
|
+
{renderDesktopActions()}
|
|
3364
|
+
<div className="sm:hidden mt-3 w-full">
|
|
3365
|
+
{renderExpandableActions()}
|
|
3366
|
+
</div>
|
|
3367
|
+
</>
|
|
3368
|
+
)
|
|
3369
|
+
}
|
|
3370
|
+
|
|
3248
3371
|
return (
|
|
3249
3372
|
<div
|
|
3250
3373
|
ref={ref}
|
|
3251
3374
|
className={cn(
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3375
|
+
"flex w-full bg-white px-4",
|
|
3376
|
+
layoutClasses[layout],
|
|
3377
|
+
heightClasses[layout],
|
|
3378
|
+
showBorder && "border-b border-[#E9EAEB]",
|
|
3255
3379
|
className
|
|
3256
3380
|
)}
|
|
3257
3381
|
{...props}
|
|
3258
3382
|
>
|
|
3259
|
-
{/*
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3383
|
+
{/* Top Row: Icon/Back + Title + Description */}
|
|
3384
|
+
<div className="flex items-center flex-1 min-w-0">
|
|
3385
|
+
{/* Left Section: Icon or Back Button */}
|
|
3386
|
+
{leftElement && (
|
|
3387
|
+
<div className="flex-shrink-0 mr-4">
|
|
3388
|
+
{leftElement}
|
|
3389
|
+
</div>
|
|
3390
|
+
)}
|
|
3265
3391
|
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3392
|
+
{/* Content Section: Title + Description */}
|
|
3393
|
+
<div className="flex-1 min-w-0">
|
|
3394
|
+
<div className="flex items-center gap-2">
|
|
3395
|
+
<h1 className="text-base font-semibold text-[#181D27] truncate">
|
|
3396
|
+
{title}
|
|
3397
|
+
</h1>
|
|
3398
|
+
{infoIcon && (
|
|
3399
|
+
<span className="flex-shrink-0 [&_svg]:w-4 [&_svg]:h-4 text-[#717680]">
|
|
3400
|
+
{infoIcon}
|
|
3401
|
+
</span>
|
|
3402
|
+
)}
|
|
3403
|
+
</div>
|
|
3404
|
+
{description && (
|
|
3405
|
+
<p className="text-sm text-[#181D27] font-normal mt-1 truncate">
|
|
3406
|
+
{description}
|
|
3407
|
+
</p>
|
|
3276
3408
|
)}
|
|
3277
3409
|
</div>
|
|
3278
|
-
{description && (
|
|
3279
|
-
<p className="text-sm text-[#333333] font-normal mt-1 truncate">
|
|
3280
|
-
{description}
|
|
3281
|
-
</p>
|
|
3282
|
-
)}
|
|
3283
3410
|
</div>
|
|
3284
3411
|
|
|
3285
3412
|
{/* Actions Section */}
|
|
3286
|
-
{
|
|
3287
|
-
<div className="flex-shrink-0 flex items-center gap-2 ml-4">
|
|
3288
|
-
{actions}
|
|
3289
|
-
</div>
|
|
3290
|
-
)}
|
|
3413
|
+
{renderActions()}
|
|
3291
3414
|
</div>
|
|
3292
3415
|
)
|
|
3293
3416
|
}
|