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.
Files changed (2) hide show
  1. package/dist/index.js +268 -30
  2. 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-semibold transition-colors whitespace-nowrap",
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-full text-sm font-medium transition-colors 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]:size-4 [&_svg]:shrink-0",
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-[#343E55]/10 hover:text-[#343E55]",
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: "p-2.5",
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-xs uppercase tracking-wider [&:has([role=checkbox])]:pr-0",
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 justify-center rounded text-sm transition-colors",
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, interactive, selected, label, children, ...props }, ref) => {
853
+ ({ className, variant, size, label, children, ...props }, ref) => {
851
854
  return (
852
855
  <span
853
- className={cn(tagVariants({ variant, size, interactive, selected, className }))}
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
- export { Tag, tagVariants }
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
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "myoperator-ui",
3
- "version": "0.0.50",
3
+ "version": "0.0.52",
4
4
  "description": "CLI for adding myOperator UI components to your project",
5
5
  "type": "module",
6
6
  "exports": "./dist/index.js",