myoperator-ui 0.0.50 → 0.0.52
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 +268 -30
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -76,7 +76,7 @@ import { cn } from "../../lib/utils"
|
|
|
76
76
|
* Pill-shaped badges with different colors for different states.
|
|
77
77
|
*/
|
|
78
78
|
const badgeVariants = cva(
|
|
79
|
-
"inline-flex items-center justify-center rounded-full text-sm font-
|
|
79
|
+
"inline-flex items-center justify-center rounded-full text-sm font-medium transition-colors whitespace-nowrap",
|
|
80
80
|
{
|
|
81
81
|
variants: {
|
|
82
82
|
variant: {
|
|
@@ -161,7 +161,7 @@ import { Loader2 } from "lucide-react"
|
|
|
161
161
|
import { cn } from "../../lib/utils"
|
|
162
162
|
|
|
163
163
|
const buttonVariants = cva(
|
|
164
|
-
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded
|
|
164
|
+
"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-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
165
165
|
{
|
|
166
166
|
variants: {
|
|
167
167
|
variant: {
|
|
@@ -172,14 +172,15 @@ const buttonVariants = cva(
|
|
|
172
172
|
"border border-[#343E55] bg-transparent text-[#343E55] hover:bg-[#343E55] hover:text-white",
|
|
173
173
|
secondary:
|
|
174
174
|
"bg-[#343E55]/20 text-[#343E55] hover:bg-[#343E55]/30",
|
|
175
|
-
ghost: "hover:bg-[#
|
|
175
|
+
ghost: "text-[#6B7280] hover:bg-[#F3F4F6] hover:text-[#333333]",
|
|
176
176
|
link: "text-[#343E55] underline-offset-4 hover:underline",
|
|
177
177
|
},
|
|
178
178
|
size: {
|
|
179
|
-
default: "py-2.5 px-4",
|
|
180
|
-
sm: "py-2 px-3 text-xs",
|
|
181
|
-
lg: "py-3 px-6",
|
|
182
|
-
icon: "
|
|
179
|
+
default: "py-2.5 px-4 [&_svg]:size-4",
|
|
180
|
+
sm: "py-2 px-3 text-xs [&_svg]:size-3.5",
|
|
181
|
+
lg: "py-3 px-6 [&_svg]:size-5",
|
|
182
|
+
icon: "h-8 w-8 rounded-md",
|
|
183
|
+
"icon-sm": "h-7 w-7 rounded-md",
|
|
183
184
|
},
|
|
184
185
|
},
|
|
185
186
|
defaultVariants: {
|
|
@@ -490,6 +491,7 @@ export {
|
|
|
490
491
|
import { cva, type VariantProps } from "class-variance-authority"
|
|
491
492
|
|
|
492
493
|
import { cn } from "../../lib/utils"
|
|
494
|
+
import { Toggle, type ToggleProps } from "./toggle"
|
|
493
495
|
|
|
494
496
|
/**
|
|
495
497
|
* Table size variants for row height.
|
|
@@ -630,7 +632,7 @@ const TableHead = React.forwardRef<HTMLTableCellElement, TableHeadProps>(
|
|
|
630
632
|
<th
|
|
631
633
|
ref={ref}
|
|
632
634
|
className={cn(
|
|
633
|
-
"h-12 px-4 text-left align-middle font-medium text-[#6B7280] text-
|
|
635
|
+
"h-12 px-4 text-left align-middle font-medium text-[#6B7280] text-sm [&:has([role=checkbox])]:pr-0",
|
|
634
636
|
sticky && "sticky left-0 bg-[#F9FAFB] z-10",
|
|
635
637
|
sortDirection && "cursor-pointer select-none",
|
|
636
638
|
className
|
|
@@ -752,6 +754,21 @@ const TableAvatar = ({ initials, color = "#7C3AED" }: TableAvatarProps) => (
|
|
|
752
754
|
)
|
|
753
755
|
TableAvatar.displayName = "TableAvatar"
|
|
754
756
|
|
|
757
|
+
/**
|
|
758
|
+
* Toggle component optimized for table cells
|
|
759
|
+
*/
|
|
760
|
+
export interface TableToggleProps extends Omit<ToggleProps, 'size'> {
|
|
761
|
+
/** Size of the toggle - defaults to 'sm' for tables */
|
|
762
|
+
size?: 'sm' | 'default'
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
const TableToggle = React.forwardRef<HTMLButtonElement, TableToggleProps>(
|
|
766
|
+
({ size = 'sm', ...props }, ref) => (
|
|
767
|
+
<Toggle ref={ref} size={size} {...props} />
|
|
768
|
+
)
|
|
769
|
+
)
|
|
770
|
+
TableToggle.displayName = "TableToggle"
|
|
771
|
+
|
|
755
772
|
export {
|
|
756
773
|
Table,
|
|
757
774
|
TableHeader,
|
|
@@ -764,6 +781,7 @@ export {
|
|
|
764
781
|
TableSkeleton,
|
|
765
782
|
TableEmpty,
|
|
766
783
|
TableAvatar,
|
|
784
|
+
TableToggle,
|
|
767
785
|
tableVariants,
|
|
768
786
|
}
|
|
769
787
|
`, prefix)
|
|
@@ -791,7 +809,7 @@ import { cn } from "../../lib/utils"
|
|
|
791
809
|
* Rounded rectangle tags with optional bold labels.
|
|
792
810
|
*/
|
|
793
811
|
const tagVariants = cva(
|
|
794
|
-
"inline-flex items-center
|
|
812
|
+
"inline-flex items-center rounded text-sm",
|
|
795
813
|
{
|
|
796
814
|
variants: {
|
|
797
815
|
variant: {
|
|
@@ -807,20 +825,10 @@ const tagVariants = cva(
|
|
|
807
825
|
sm: "px-1.5 py-0.5 text-xs",
|
|
808
826
|
lg: "px-3 py-1.5",
|
|
809
827
|
},
|
|
810
|
-
interactive: {
|
|
811
|
-
true: "cursor-pointer hover:bg-[#E5E7EB] active:bg-[#D1D5DB]",
|
|
812
|
-
false: "",
|
|
813
|
-
},
|
|
814
|
-
selected: {
|
|
815
|
-
true: "ring-2 ring-[#343E55] ring-offset-1",
|
|
816
|
-
false: "",
|
|
817
|
-
},
|
|
818
828
|
},
|
|
819
829
|
defaultVariants: {
|
|
820
830
|
variant: "default",
|
|
821
831
|
size: "default",
|
|
822
|
-
interactive: false,
|
|
823
|
-
selected: false,
|
|
824
832
|
},
|
|
825
833
|
}
|
|
826
834
|
)
|
|
@@ -832,7 +840,6 @@ const tagVariants = cva(
|
|
|
832
840
|
* \`\`\`tsx
|
|
833
841
|
* <Tag>After Call Event</Tag>
|
|
834
842
|
* <Tag label="In Call Event:">Start of call, Bridge, Call ended</Tag>
|
|
835
|
-
* <Tag interactive onClick={() => console.log('clicked')}>Clickable</Tag>
|
|
836
843
|
* \`\`\`
|
|
837
844
|
*/
|
|
838
845
|
export interface TagProps
|
|
@@ -840,21 +847,14 @@ export interface TagProps
|
|
|
840
847
|
VariantProps<typeof tagVariants> {
|
|
841
848
|
/** Bold label prefix displayed before the content */
|
|
842
849
|
label?: string
|
|
843
|
-
/** Make the tag clickable with hover/active states */
|
|
844
|
-
interactive?: boolean
|
|
845
|
-
/** Show selected state with ring outline */
|
|
846
|
-
selected?: boolean
|
|
847
850
|
}
|
|
848
851
|
|
|
849
852
|
const Tag = React.forwardRef<HTMLSpanElement, TagProps>(
|
|
850
|
-
({ className, variant, size,
|
|
853
|
+
({ className, variant, size, label, children, ...props }, ref) => {
|
|
851
854
|
return (
|
|
852
855
|
<span
|
|
853
|
-
className={cn(tagVariants({ variant, size,
|
|
856
|
+
className={cn(tagVariants({ variant, size, className }))}
|
|
854
857
|
ref={ref}
|
|
855
|
-
role={interactive ? "button" : undefined}
|
|
856
|
-
tabIndex={interactive ? 0 : undefined}
|
|
857
|
-
aria-selected={selected}
|
|
858
858
|
{...props}
|
|
859
859
|
>
|
|
860
860
|
{label && (
|
|
@@ -867,7 +867,245 @@ const Tag = React.forwardRef<HTMLSpanElement, TagProps>(
|
|
|
867
867
|
)
|
|
868
868
|
Tag.displayName = "Tag"
|
|
869
869
|
|
|
870
|
-
|
|
870
|
+
/**
|
|
871
|
+
* TagGroup component for displaying multiple tags with overflow indicator.
|
|
872
|
+
*
|
|
873
|
+
* @example
|
|
874
|
+
* \`\`\`tsx
|
|
875
|
+
* <TagGroup
|
|
876
|
+
* tags={[
|
|
877
|
+
* { label: "In Call Event:", value: "Call Begin, Start Dialing" },
|
|
878
|
+
* { label: "Whatsapp Event:", value: "message.Delivered" },
|
|
879
|
+
* { value: "After Call Event" },
|
|
880
|
+
* ]}
|
|
881
|
+
* maxVisible={2}
|
|
882
|
+
* />
|
|
883
|
+
* \`\`\`
|
|
884
|
+
*/
|
|
885
|
+
export interface TagGroupProps {
|
|
886
|
+
/** Array of tags to display */
|
|
887
|
+
tags: Array<{ label?: string; value: string }>
|
|
888
|
+
/** Maximum number of tags to show before overflow (default: 2) */
|
|
889
|
+
maxVisible?: number
|
|
890
|
+
/** Tag variant */
|
|
891
|
+
variant?: TagProps['variant']
|
|
892
|
+
/** Tag size */
|
|
893
|
+
size?: TagProps['size']
|
|
894
|
+
/** Additional className for the container */
|
|
895
|
+
className?: string
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
const TagGroup = ({
|
|
899
|
+
tags,
|
|
900
|
+
maxVisible = 2,
|
|
901
|
+
variant,
|
|
902
|
+
size,
|
|
903
|
+
className,
|
|
904
|
+
}: TagGroupProps) => {
|
|
905
|
+
const visibleTags = tags.slice(0, maxVisible)
|
|
906
|
+
const overflowCount = tags.length - maxVisible
|
|
907
|
+
|
|
908
|
+
return (
|
|
909
|
+
<div className={cn("flex flex-col items-start gap-2", className)}>
|
|
910
|
+
{visibleTags.map((tag, index) => {
|
|
911
|
+
const isLastVisible = index === visibleTags.length - 1 && overflowCount > 0
|
|
912
|
+
|
|
913
|
+
if (isLastVisible) {
|
|
914
|
+
return (
|
|
915
|
+
<div key={index} className="flex items-center gap-2">
|
|
916
|
+
<Tag label={tag.label} variant={variant} size={size}>
|
|
917
|
+
{tag.value}
|
|
918
|
+
</Tag>
|
|
919
|
+
<Tag variant={variant} size={size}>
|
|
920
|
+
+{overflowCount} more
|
|
921
|
+
</Tag>
|
|
922
|
+
</div>
|
|
923
|
+
)
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
return (
|
|
927
|
+
<Tag key={index} label={tag.label} variant={variant} size={size}>
|
|
928
|
+
{tag.value}
|
|
929
|
+
</Tag>
|
|
930
|
+
)
|
|
931
|
+
})}
|
|
932
|
+
</div>
|
|
933
|
+
)
|
|
934
|
+
}
|
|
935
|
+
TagGroup.displayName = "TagGroup"
|
|
936
|
+
|
|
937
|
+
export { Tag, TagGroup, tagVariants }
|
|
938
|
+
`, prefix)
|
|
939
|
+
}
|
|
940
|
+
]
|
|
941
|
+
},
|
|
942
|
+
"toggle": {
|
|
943
|
+
name: "toggle",
|
|
944
|
+
description: "A toggle/switch component for boolean inputs with on/off states",
|
|
945
|
+
dependencies: [
|
|
946
|
+
"class-variance-authority",
|
|
947
|
+
"clsx",
|
|
948
|
+
"tailwind-merge"
|
|
949
|
+
],
|
|
950
|
+
files: [
|
|
951
|
+
{
|
|
952
|
+
name: "toggle.tsx",
|
|
953
|
+
content: prefixTailwindClasses(`import * as React from "react"
|
|
954
|
+
import { cva, type VariantProps } from "class-variance-authority"
|
|
955
|
+
|
|
956
|
+
import { cn } from "../../lib/utils"
|
|
957
|
+
|
|
958
|
+
/**
|
|
959
|
+
* Toggle track variants (the outer container)
|
|
960
|
+
*/
|
|
961
|
+
const toggleVariants = cva(
|
|
962
|
+
"relative inline-flex shrink-0 cursor-pointer rounded-full border-2 border-transparent 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",
|
|
963
|
+
{
|
|
964
|
+
variants: {
|
|
965
|
+
size: {
|
|
966
|
+
default: "h-6 w-11",
|
|
967
|
+
sm: "h-5 w-9",
|
|
968
|
+
lg: "h-7 w-14",
|
|
969
|
+
},
|
|
970
|
+
},
|
|
971
|
+
defaultVariants: {
|
|
972
|
+
size: "default",
|
|
973
|
+
},
|
|
974
|
+
}
|
|
975
|
+
)
|
|
976
|
+
|
|
977
|
+
/**
|
|
978
|
+
* Toggle thumb variants (the sliding circle)
|
|
979
|
+
*/
|
|
980
|
+
const toggleThumbVariants = cva(
|
|
981
|
+
"pointer-events-none inline-block rounded-full bg-white shadow-lg ring-0 transition-transform duration-200 ease-in-out",
|
|
982
|
+
{
|
|
983
|
+
variants: {
|
|
984
|
+
size: {
|
|
985
|
+
default: "h-5 w-5",
|
|
986
|
+
sm: "h-4 w-4",
|
|
987
|
+
lg: "h-6 w-6",
|
|
988
|
+
},
|
|
989
|
+
checked: {
|
|
990
|
+
true: "",
|
|
991
|
+
false: "translate-x-0",
|
|
992
|
+
},
|
|
993
|
+
},
|
|
994
|
+
compoundVariants: [
|
|
995
|
+
{ size: "default", checked: true, className: "translate-x-5" },
|
|
996
|
+
{ size: "sm", checked: true, className: "translate-x-4" },
|
|
997
|
+
{ size: "lg", checked: true, className: "translate-x-7" },
|
|
998
|
+
],
|
|
999
|
+
defaultVariants: {
|
|
1000
|
+
size: "default",
|
|
1001
|
+
checked: false,
|
|
1002
|
+
},
|
|
1003
|
+
}
|
|
1004
|
+
)
|
|
1005
|
+
|
|
1006
|
+
/**
|
|
1007
|
+
* A toggle/switch component for boolean inputs with on/off states
|
|
1008
|
+
*
|
|
1009
|
+
* @example
|
|
1010
|
+
* \`\`\`tsx
|
|
1011
|
+
* <Toggle checked={isEnabled} onCheckedChange={setIsEnabled} />
|
|
1012
|
+
* <Toggle size="sm" disabled />
|
|
1013
|
+
* <Toggle size="lg" checked label="Enable notifications" />
|
|
1014
|
+
* \`\`\`
|
|
1015
|
+
*/
|
|
1016
|
+
export interface ToggleProps
|
|
1017
|
+
extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "onChange">,
|
|
1018
|
+
VariantProps<typeof toggleVariants> {
|
|
1019
|
+
/** Whether the toggle is checked/on */
|
|
1020
|
+
checked?: boolean
|
|
1021
|
+
/** Default checked state for uncontrolled usage */
|
|
1022
|
+
defaultChecked?: boolean
|
|
1023
|
+
/** Callback when checked state changes */
|
|
1024
|
+
onCheckedChange?: (checked: boolean) => void
|
|
1025
|
+
/** Optional label text */
|
|
1026
|
+
label?: string
|
|
1027
|
+
/** Position of the label */
|
|
1028
|
+
labelPosition?: "left" | "right"
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
const Toggle = React.forwardRef<HTMLButtonElement, ToggleProps>(
|
|
1032
|
+
(
|
|
1033
|
+
{
|
|
1034
|
+
className,
|
|
1035
|
+
size,
|
|
1036
|
+
checked: controlledChecked,
|
|
1037
|
+
defaultChecked = false,
|
|
1038
|
+
onCheckedChange,
|
|
1039
|
+
disabled,
|
|
1040
|
+
label,
|
|
1041
|
+
labelPosition = "right",
|
|
1042
|
+
...props
|
|
1043
|
+
},
|
|
1044
|
+
ref
|
|
1045
|
+
) => {
|
|
1046
|
+
const [internalChecked, setInternalChecked] = React.useState(defaultChecked)
|
|
1047
|
+
|
|
1048
|
+
const isControlled = controlledChecked !== undefined
|
|
1049
|
+
const isChecked = isControlled ? controlledChecked : internalChecked
|
|
1050
|
+
|
|
1051
|
+
const handleClick = () => {
|
|
1052
|
+
if (disabled) return
|
|
1053
|
+
|
|
1054
|
+
const newValue = !isChecked
|
|
1055
|
+
|
|
1056
|
+
if (!isControlled) {
|
|
1057
|
+
setInternalChecked(newValue)
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
onCheckedChange?.(newValue)
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
const toggle = (
|
|
1064
|
+
<button
|
|
1065
|
+
type="button"
|
|
1066
|
+
role="switch"
|
|
1067
|
+
aria-checked={isChecked}
|
|
1068
|
+
ref={ref}
|
|
1069
|
+
disabled={disabled}
|
|
1070
|
+
onClick={handleClick}
|
|
1071
|
+
className={cn(
|
|
1072
|
+
toggleVariants({ size, className }),
|
|
1073
|
+
isChecked ? "bg-[#343E55]" : "bg-[#E5E7EB]"
|
|
1074
|
+
)}
|
|
1075
|
+
{...props}
|
|
1076
|
+
>
|
|
1077
|
+
<span
|
|
1078
|
+
className={cn(
|
|
1079
|
+
toggleThumbVariants({ size, checked: isChecked })
|
|
1080
|
+
)}
|
|
1081
|
+
/>
|
|
1082
|
+
</button>
|
|
1083
|
+
)
|
|
1084
|
+
|
|
1085
|
+
if (label) {
|
|
1086
|
+
return (
|
|
1087
|
+
<label className="inline-flex items-center gap-2 cursor-pointer">
|
|
1088
|
+
{labelPosition === "left" && (
|
|
1089
|
+
<span className={cn("text-sm text-[#333333]", disabled && "opacity-50")}>
|
|
1090
|
+
{label}
|
|
1091
|
+
</span>
|
|
1092
|
+
)}
|
|
1093
|
+
{toggle}
|
|
1094
|
+
{labelPosition === "right" && (
|
|
1095
|
+
<span className={cn("text-sm text-[#333333]", disabled && "opacity-50")}>
|
|
1096
|
+
{label}
|
|
1097
|
+
</span>
|
|
1098
|
+
)}
|
|
1099
|
+
</label>
|
|
1100
|
+
)
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
return toggle
|
|
1104
|
+
}
|
|
1105
|
+
)
|
|
1106
|
+
Toggle.displayName = "Toggle"
|
|
1107
|
+
|
|
1108
|
+
export { Toggle, toggleVariants }
|
|
871
1109
|
`, prefix)
|
|
872
1110
|
}
|
|
873
1111
|
]
|