@minutemailer/kit 1.2.2 → 1.2.4

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.
@@ -12,6 +12,7 @@ export interface ImageSlotProps {
12
12
  alt?: string;
13
13
  width: number;
14
14
  height: number;
15
+ scale?: number;
15
16
  actions?: ImageSlotAction[];
16
17
  onAction?: (action: string) => void;
17
18
  onRemove?: () => void;
@@ -21,5 +22,5 @@ export interface ImageSlotProps {
21
22
  className?: string;
22
23
  style?: CSSProperties;
23
24
  }
24
- declare function ImageSlot({ src, s3, alt, width, height, actions, onAction, onRemove, onFile, loading, accept, className, style, }: ImageSlotProps): import("react/jsx-runtime").JSX.Element;
25
+ declare function ImageSlot({ src, s3, alt, width, height, scale, actions, onAction, onRemove, onFile, loading, accept, className, style, }: ImageSlotProps): import("react/jsx-runtime").JSX.Element;
25
26
  export { ImageSlot };
@@ -7,8 +7,7 @@ import { Spinner } from '../components/ui/spinner.js';
7
7
  import { toast } from 'sonner';
8
8
  import { ChevronDownIcon, ImageIcon, Trash2Icon } from 'lucide-react';
9
9
  import { S3Image } from '../components/s3-image.js';
10
- function ImageSlot({ src, s3, alt = '', width, height, actions = [], onAction, onRemove, onFile, loading = false, accept = ['image/gif', 'image/png', 'image/jpeg'], className, style, }) {
11
- const aspectRatio = width / height;
10
+ function ImageSlot({ src, s3, alt = '', width, height, scale = 1, actions = [], onAction, onRemove, onFile, loading = false, accept = ['image/gif', 'image/png', 'image/jpeg'], className, style, }) {
12
11
  const [dragState, setDragState] = useState('idle');
13
12
  const dragCounterRef = useRef(0);
14
13
  const fileInputRef = useRef(null);
@@ -87,21 +86,20 @@ function ImageSlot({ src, s3, alt = '', width, height, actions = [], onAction, o
87
86
  onRemove?.();
88
87
  setS3ImageData(null);
89
88
  };
90
- const containerWidth = s3ImageData ? s3ImageData.width : width;
91
- const containerHeight = s3ImageData ? s3ImageData.height : height;
89
+ const maxWidth = s3ImageData ? s3ImageData.width * scale : width * scale;
92
90
  if (src || s3) {
93
91
  return (_jsxs("div", { className: cn('relative group', className), style: {
94
- width: containerWidth,
95
- height: containerHeight,
92
+ width: '100%',
93
+ maxWidth,
94
+ aspectRatio: `${width} / ${height}`,
96
95
  ...style,
97
96
  }, children: [s3 ? (_jsx(S3Image, { ...s3, width: width, height: height, onLoaded: onS3ImageLoaded, alt: alt, className: "block w-full h-full object-cover" })) : (_jsx("img", { src: src, alt: alt, width: width, height: height, className: "block w-full h-full object-cover" })), onRemove && (_jsx("div", { className: "absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center", children: _jsx(Button, { variant: "outline", className: "rounded-full", size: "icon", onClick: handleRemove, children: _jsx(Trash2Icon, {}) }) }))] }));
98
97
  }
99
98
  // Placeholder view
100
99
  return (_jsx("div", { "data-slot": "image-slot", className: cn('bg-muted flex items-center justify-center @container transition-colors', dragState === 'over' && 'bg-green-100 dark:bg-green-950', className), style: {
101
- width: width,
102
- maxHeight: height,
103
- maxWidth: '100%',
104
- height: width / aspectRatio,
100
+ width: '100%',
101
+ maxWidth: width * scale,
102
+ aspectRatio: `${width} / ${height}`,
105
103
  ...style,
106
104
  }, onDragEnter: handleDragEnter, onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDrop: handleDrop, children: loading ? (_jsx(Spinner, { className: "size-8" })) : dragState === 'over' ? (_jsx("p", { className: "text-sm text-muted-foreground", children: "Drop image to upload" })) : (_jsxs(_Fragment, { children: [_jsx("input", { ref: fileInputRef, type: "file", accept: accept.join(','), onChange: handleFileInputChange, className: "hidden" }), _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs(Button, { variant: "outline", size: "sm", children: [_jsx(ImageIcon, { className: "@xs:hidden" }), _jsx("span", { className: "hidden @xs:inline", children: "Add image" }), _jsx(ChevronDownIcon, { className: "hidden @xs:inline" })] }) }), _jsx(DropdownMenuContent, { children: actions.map((action) => (_jsxs(DropdownMenuItem, { onClick: () => handleActionClick(action), children: [action.icon, action.name] }, action.value))) })] })] })) }));
107
105
  }
@@ -9,12 +9,12 @@ function S3Image({ imageKey, width, height = 0, fit = 'inside', retina = true, o
9
9
  const [loading, setLoading] = useState(true);
10
10
  const [error, setError] = useState(false);
11
11
  // Calculate container dimensions
12
- const containerWidth = width === 'auto'
12
+ const containerWidth = imageData?.width || width === 'auto'
13
13
  ? undefined
14
14
  : typeof width === 'string'
15
15
  ? parseInt(width, 10)
16
16
  : width;
17
- const containerHeight = height === 'auto'
17
+ const containerHeight = imageData?.height || height === 'auto'
18
18
  ? undefined
19
19
  : typeof height === 'string'
20
20
  ? parseInt(height, 10)
@@ -48,9 +48,13 @@ function S3Image({ imageKey, width, height = 0, fit = 'inside', retina = true, o
48
48
  JSON.stringify(edits),
49
49
  s3Image,
50
50
  ]);
51
+ const aspectRatio = containerWidth && containerHeight
52
+ ? `${containerWidth} / ${containerHeight}`
53
+ : undefined;
51
54
  const containerStyle = {
52
- width: imageData ? imageData.width : containerWidth || 'auto',
53
- height: imageData ? imageData.height : containerHeight || 'auto',
55
+ width: '100%',
56
+ maxWidth: imageData ? imageData.width : containerWidth || undefined,
57
+ aspectRatio: aspectRatio,
54
58
  };
55
59
  if (!imageKey) {
56
60
  return null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@minutemailer/kit",
3
- "version": "1.2.2",
3
+ "version": "1.2.4",
4
4
  "description": "Minutemailer UI Kit",
5
5
  "license": "MIT",
6
6
  "author": "Minutemailer",