@optilogic/core 1.0.0-beta.1 → 1.0.0-beta.3

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 CHANGED
@@ -861,18 +861,104 @@ var AlertDialogCancel = React33.forwardRef(({ className, ...props }, ref) => /*
861
861
  }
862
862
  ));
863
863
  AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;
864
- var Card = React33.forwardRef(
865
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
866
- "div",
867
- {
868
- ref,
869
- className: cn(
870
- "rounded-xl border bg-card text-card-foreground shadow",
871
- className
872
- ),
873
- ...props
864
+ var cardVariants = cva(
865
+ "rounded-xl border bg-card text-card-foreground shadow",
866
+ {
867
+ variants: {
868
+ /**
869
+ * Card width size presets
870
+ */
871
+ size: {
872
+ auto: "",
873
+ sm: "w-64",
874
+ md: "w-80",
875
+ lg: "w-96",
876
+ xl: "w-[28rem]",
877
+ full: "w-full"
878
+ },
879
+ /**
880
+ * Hover effect styles
881
+ */
882
+ hover: {
883
+ none: "",
884
+ lift: "transition-all duration-200 hover:-translate-y-1 hover:shadow-lg",
885
+ glow: "transition-shadow duration-200 hover:shadow-lg hover:shadow-accent/20",
886
+ border: "transition-colors duration-200 hover:border-accent",
887
+ "border-success": "transition-colors duration-200 hover:border-success",
888
+ "border-warning": "transition-colors duration-200 hover:border-warning",
889
+ "border-destructive": "transition-colors duration-200 hover:border-destructive",
890
+ "border-muted": "transition-colors duration-200 hover:border-muted-foreground",
891
+ scale: "transition-transform duration-200 hover:scale-[1.02]"
892
+ },
893
+ /**
894
+ * Whether the card is interactive (clickable)
895
+ */
896
+ interactive: {
897
+ true: "cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
898
+ false: ""
899
+ },
900
+ /**
901
+ * Card padding density
902
+ */
903
+ padding: {
904
+ none: "",
905
+ sm: "[&>*:not(img)]:p-3 [&>*:not(img)]:pt-3",
906
+ md: "",
907
+ lg: "[&>*:not(img)]:p-8 [&>*:not(img)]:pt-8"
908
+ }
909
+ },
910
+ defaultVariants: {
911
+ size: "auto",
912
+ hover: "none",
913
+ interactive: false,
914
+ padding: "md"
874
915
  }
875
- )
916
+ }
917
+ );
918
+ var Card = React33.forwardRef(
919
+ ({
920
+ className,
921
+ size,
922
+ hover,
923
+ interactive,
924
+ padding,
925
+ asButton,
926
+ hoverBorderClass,
927
+ onClick,
928
+ onKeyDown,
929
+ ...props
930
+ }, ref) => {
931
+ const isInteractive = interactive || asButton || !!onClick;
932
+ const handleKeyDown = React33.useCallback(
933
+ (e) => {
934
+ if (isInteractive && (e.key === "Enter" || e.key === " ")) {
935
+ e.preventDefault();
936
+ onClick?.(e);
937
+ }
938
+ onKeyDown?.(e);
939
+ },
940
+ [isInteractive, onClick, onKeyDown]
941
+ );
942
+ return /* @__PURE__ */ jsx(
943
+ "div",
944
+ {
945
+ ref,
946
+ role: isInteractive ? "button" : void 0,
947
+ tabIndex: isInteractive ? 0 : void 0,
948
+ className: cn(
949
+ cardVariants({ size, hover, interactive: isInteractive, padding }),
950
+ "group relative",
951
+ // Custom hover border color overrides variant if provided
952
+ hoverBorderClass && "transition-colors duration-200",
953
+ hoverBorderClass,
954
+ className
955
+ ),
956
+ onClick,
957
+ onKeyDown: handleKeyDown,
958
+ ...props
959
+ }
960
+ );
961
+ }
876
962
  );
877
963
  Card.displayName = "Card";
878
964
  var CardHeader = React33.forwardRef(
@@ -923,6 +1009,300 @@ var CardFooter = React33.forwardRef(
923
1009
  )
924
1010
  );
925
1011
  CardFooter.displayName = "CardFooter";
1012
+ var cardImageVariants = cva("w-full object-cover", {
1013
+ variants: {
1014
+ /**
1015
+ * Image aspect ratio
1016
+ */
1017
+ aspectRatio: {
1018
+ auto: "",
1019
+ square: "aspect-square",
1020
+ video: "aspect-video",
1021
+ wide: "aspect-[2/1]",
1022
+ portrait: "aspect-[3/4]"
1023
+ },
1024
+ /**
1025
+ * Image position in the card
1026
+ */
1027
+ position: {
1028
+ top: "rounded-t-xl",
1029
+ bottom: "rounded-b-xl",
1030
+ fill: "rounded-xl"
1031
+ }
1032
+ },
1033
+ defaultVariants: {
1034
+ aspectRatio: "video",
1035
+ position: "top"
1036
+ }
1037
+ });
1038
+ var CardImage = React33.forwardRef(
1039
+ ({ className, aspectRatio, position, fallback, alt, src, onError, ...props }, ref) => {
1040
+ const [hasError, setHasError] = React33.useState(false);
1041
+ const handleError = React33.useCallback(
1042
+ (e) => {
1043
+ setHasError(true);
1044
+ onError?.(e);
1045
+ },
1046
+ [onError]
1047
+ );
1048
+ React33.useEffect(() => {
1049
+ setHasError(false);
1050
+ }, [src]);
1051
+ if (hasError && fallback) {
1052
+ return /* @__PURE__ */ jsx(
1053
+ "div",
1054
+ {
1055
+ className: cn(
1056
+ "flex items-center justify-center bg-muted",
1057
+ cardImageVariants({ aspectRatio, position }),
1058
+ className
1059
+ ),
1060
+ children: fallback
1061
+ }
1062
+ );
1063
+ }
1064
+ return /* @__PURE__ */ jsx(
1065
+ "img",
1066
+ {
1067
+ ref,
1068
+ src,
1069
+ alt,
1070
+ className: cn(cardImageVariants({ aspectRatio, position }), className),
1071
+ onError: handleError,
1072
+ ...props
1073
+ }
1074
+ );
1075
+ }
1076
+ );
1077
+ CardImage.displayName = "CardImage";
1078
+ var cardActionsVariants = cva(
1079
+ "absolute flex items-center gap-1 transition-opacity duration-200 z-10",
1080
+ {
1081
+ variants: {
1082
+ /**
1083
+ * When to show the actions
1084
+ */
1085
+ showOn: {
1086
+ hover: "opacity-0 group-hover:opacity-100",
1087
+ always: "opacity-100"
1088
+ },
1089
+ /**
1090
+ * Position of the actions overlay
1091
+ */
1092
+ position: {
1093
+ "top-right": "top-2 right-2",
1094
+ "top-left": "top-2 left-2",
1095
+ "bottom-right": "bottom-2 right-2",
1096
+ "bottom-left": "bottom-2 left-2"
1097
+ },
1098
+ /**
1099
+ * Visual style of the actions container
1100
+ */
1101
+ variant: {
1102
+ /** Solid background with backdrop blur */
1103
+ floating: "bg-background/90 backdrop-blur-sm rounded-md shadow-sm p-1",
1104
+ /** No background, just spacing */
1105
+ ghost: "p-1",
1106
+ /** Muted bar background */
1107
+ bar: "bg-muted/80 backdrop-blur-sm rounded-md p-1.5",
1108
+ /** No background on container, icons get background on hover */
1109
+ "icon-hover": "p-0 [&>button]:bg-transparent [&>button]:hover:bg-background/90 [&>button]:hover:shadow-sm [&>button]:transition-all"
1110
+ }
1111
+ },
1112
+ defaultVariants: {
1113
+ showOn: "hover",
1114
+ position: "top-right",
1115
+ variant: "floating"
1116
+ }
1117
+ }
1118
+ );
1119
+ var CardActions = React33.forwardRef(
1120
+ ({ className, showOn, position, variant, ...props }, ref) => /* @__PURE__ */ jsx(
1121
+ "div",
1122
+ {
1123
+ ref,
1124
+ className: cn(cardActionsVariants({ showOn, position, variant }), className),
1125
+ onClick: (e) => e.stopPropagation(),
1126
+ ...props
1127
+ }
1128
+ )
1129
+ );
1130
+ CardActions.displayName = "CardActions";
1131
+ var SelectableCard = React33.forwardRef(
1132
+ ({
1133
+ className,
1134
+ selected: controlledSelected,
1135
+ defaultSelected = false,
1136
+ onSelectedChange,
1137
+ showCheckbox = false,
1138
+ checkboxPosition = "top-right",
1139
+ disabled = false,
1140
+ children,
1141
+ onClick,
1142
+ hover = "border",
1143
+ ...props
1144
+ }, ref) => {
1145
+ const [uncontrolledSelected, setUncontrolledSelected] = React33.useState(defaultSelected);
1146
+ const isControlled = controlledSelected !== void 0;
1147
+ const isSelected = isControlled ? controlledSelected : uncontrolledSelected;
1148
+ const handleClick = React33.useCallback(
1149
+ (e) => {
1150
+ if (disabled) return;
1151
+ const newSelected = !isSelected;
1152
+ if (!isControlled) {
1153
+ setUncontrolledSelected(newSelected);
1154
+ }
1155
+ onSelectedChange?.(newSelected);
1156
+ onClick?.(e);
1157
+ },
1158
+ [disabled, isSelected, isControlled, onSelectedChange, onClick]
1159
+ );
1160
+ const handleCheckboxChange = React33.useCallback(
1161
+ (checked) => {
1162
+ if (disabled) return;
1163
+ const newSelected = checked === true;
1164
+ if (!isControlled) {
1165
+ setUncontrolledSelected(newSelected);
1166
+ }
1167
+ onSelectedChange?.(newSelected);
1168
+ },
1169
+ [disabled, isControlled, onSelectedChange]
1170
+ );
1171
+ const isInline = checkboxPosition === "inline-left";
1172
+ return /* @__PURE__ */ jsxs(
1173
+ Card,
1174
+ {
1175
+ ref,
1176
+ className: cn(
1177
+ // Selection styling
1178
+ isSelected && "ring-2 ring-accent border-accent",
1179
+ disabled && "opacity-50 cursor-not-allowed",
1180
+ className
1181
+ ),
1182
+ interactive: !disabled,
1183
+ hover: disabled ? "none" : hover,
1184
+ onClick: handleClick,
1185
+ "aria-selected": isSelected,
1186
+ "aria-disabled": disabled,
1187
+ ...props,
1188
+ children: [
1189
+ showCheckbox && isInline && /* @__PURE__ */ jsxs(
1190
+ "div",
1191
+ {
1192
+ className: "flex items-center gap-3 px-4 py-3 border-b border-border/50",
1193
+ onClick: (e) => e.stopPropagation(),
1194
+ children: [
1195
+ /* @__PURE__ */ jsx(
1196
+ Checkbox,
1197
+ {
1198
+ checked: isSelected,
1199
+ onCheckedChange: handleCheckboxChange,
1200
+ disabled
1201
+ }
1202
+ ),
1203
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: isSelected ? "Selected" : "Click to select" })
1204
+ ]
1205
+ }
1206
+ ),
1207
+ showCheckbox && !isInline && /* @__PURE__ */ jsx(
1208
+ "div",
1209
+ {
1210
+ className: cn(
1211
+ "absolute z-10 p-1 bg-background/90 backdrop-blur-sm rounded-md",
1212
+ checkboxPosition === "top-left" ? "top-2 left-2" : "top-2 right-2"
1213
+ ),
1214
+ onClick: (e) => e.stopPropagation(),
1215
+ children: /* @__PURE__ */ jsx(
1216
+ Checkbox,
1217
+ {
1218
+ checked: isSelected,
1219
+ onCheckedChange: handleCheckboxChange,
1220
+ disabled
1221
+ }
1222
+ )
1223
+ }
1224
+ ),
1225
+ children
1226
+ ]
1227
+ }
1228
+ );
1229
+ }
1230
+ );
1231
+ SelectableCard.displayName = "SelectableCard";
1232
+ var cardGridVariants = cva("grid", {
1233
+ variants: {
1234
+ /**
1235
+ * Number of columns
1236
+ */
1237
+ columns: {
1238
+ 1: "grid-cols-1",
1239
+ 2: "grid-cols-1 sm:grid-cols-2",
1240
+ 3: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3",
1241
+ 4: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4",
1242
+ auto: "grid-cols-[repeat(auto-fill,minmax(280px,1fr))]"
1243
+ },
1244
+ /**
1245
+ * Gap between cards
1246
+ */
1247
+ gap: {
1248
+ none: "gap-0",
1249
+ sm: "gap-3",
1250
+ md: "gap-4",
1251
+ lg: "gap-6",
1252
+ xl: "gap-8"
1253
+ }
1254
+ },
1255
+ defaultVariants: {
1256
+ columns: "auto",
1257
+ gap: "md"
1258
+ }
1259
+ });
1260
+ var CardGrid = React33.forwardRef(
1261
+ ({ className, columns, gap, ...props }, ref) => /* @__PURE__ */ jsx(
1262
+ "div",
1263
+ {
1264
+ ref,
1265
+ className: cn(cardGridVariants({ columns, gap }), className),
1266
+ ...props
1267
+ }
1268
+ )
1269
+ );
1270
+ CardGrid.displayName = "CardGrid";
1271
+ var cardListVariants = cva("flex flex-col", {
1272
+ variants: {
1273
+ /**
1274
+ * Gap between cards
1275
+ */
1276
+ gap: {
1277
+ none: "gap-0",
1278
+ sm: "gap-2",
1279
+ md: "gap-4",
1280
+ lg: "gap-6"
1281
+ },
1282
+ /**
1283
+ * Whether to show dividers between cards
1284
+ */
1285
+ divided: {
1286
+ true: "[&>*:not(:last-child)]:border-b [&>*:not(:last-child)]:pb-4 [&>*:not(:last-child)]:rounded-b-none",
1287
+ false: ""
1288
+ }
1289
+ },
1290
+ defaultVariants: {
1291
+ gap: "md",
1292
+ divided: false
1293
+ }
1294
+ });
1295
+ var CardList = React33.forwardRef(
1296
+ ({ className, gap, divided, ...props }, ref) => /* @__PURE__ */ jsx(
1297
+ "div",
1298
+ {
1299
+ ref,
1300
+ className: cn(cardListVariants({ gap, divided }), className),
1301
+ ...props
1302
+ }
1303
+ )
1304
+ );
1305
+ CardList.displayName = "CardList";
926
1306
  var Table = React33.forwardRef(
927
1307
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { className: "relative w-full overflow-auto", children: /* @__PURE__ */ jsx(
928
1308
  "table",
@@ -5823,6 +6203,6 @@ function useContextMenu() {
5823
6203
  };
5824
6204
  }
5825
6205
 
5826
- export { ALL_THEMES, Accordion, AccordionContent, AccordionItem, AccordionTrigger, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, Autocomplete, Badge, Button, CYBERPUNK_THEME, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CellEditor, Checkbox, Chip, ConfirmationModal, ContextMenu, CopyButton, DARK_ELEGANT_THEME, DataGrid, DatePicker, DatePickerInput, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, FOREST_THEME, FUTURISTIC_THEME, FilterPopover, GREEN_THEME, HeaderCell, IconButton, Input, Label, LoadingSpinner, MINIMALIST_LIGHT_THEME, Modal, ModalButton, NATURE_THEME, OCEAN_THEME, OPTILOGIC_LEGACY_THEME, PRESET_THEMES, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, ResizablePanel, ResizeHandle, SCIFI_THEME, SUNSET_THEME, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Skeleton, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, ThemePicker, Toaster, Tooltip, TooltipArrow, TooltipContent, TooltipPortal, TooltipProvider, TooltipRoot, TooltipTrigger, accordionContentVariants, accordionItemVariants, accordionTriggerVariants, applyFilterOperator, applyFilters, applySorting, applyTheme, areThemesEqual, badgeVariants, buttonVariants, cloneTheme, cn, exportTheme, getCellValue, getCurrentTheme, getDefaultTheme, getPresetTheme, hexToHsl, iconButtonVariants, importTheme, isPresetTheme, labelVariants, loadingSpinnerVariants, themeToHsl, useColumnResize, useColumnResizeManager, useConfirmation, useContextMenu, useDataGridState, useKeyboardNavigation, validateTheme };
6206
+ export { ALL_THEMES, Accordion, AccordionContent, AccordionItem, AccordionTrigger, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, Autocomplete, Badge, Button, CYBERPUNK_THEME, Calendar, Card, CardActions, CardContent, CardDescription, CardFooter, CardGrid, CardHeader, CardImage, CardList, CardTitle, CellEditor, Checkbox, Chip, ConfirmationModal, ContextMenu, CopyButton, DARK_ELEGANT_THEME, DataGrid, DatePicker, DatePickerInput, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, FOREST_THEME, FUTURISTIC_THEME, FilterPopover, GREEN_THEME, HeaderCell, IconButton, Input, Label, LoadingSpinner, MINIMALIST_LIGHT_THEME, Modal, ModalButton, NATURE_THEME, OCEAN_THEME, OPTILOGIC_LEGACY_THEME, PRESET_THEMES, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, ResizablePanel, ResizeHandle, SCIFI_THEME, SUNSET_THEME, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SelectableCard, Separator, Skeleton, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, ThemePicker, Toaster, Tooltip, TooltipArrow, TooltipContent, TooltipPortal, TooltipProvider, TooltipRoot, TooltipTrigger, accordionContentVariants, accordionItemVariants, accordionTriggerVariants, applyFilterOperator, applyFilters, applySorting, applyTheme, areThemesEqual, badgeVariants, buttonVariants, cardActionsVariants, cardGridVariants, cardImageVariants, cardListVariants, cardVariants, cloneTheme, cn, exportTheme, getCellValue, getCurrentTheme, getDefaultTheme, getPresetTheme, hexToHsl, iconButtonVariants, importTheme, isPresetTheme, labelVariants, loadingSpinnerVariants, themeToHsl, useColumnResize, useColumnResizeManager, useConfirmation, useContextMenu, useDataGridState, useKeyboardNavigation, validateTheme };
5827
6207
  //# sourceMappingURL=index.js.map
5828
6208
  //# sourceMappingURL=index.js.map