@minutemailer/kit 1.2.1 → 1.2.2
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.
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ReactNode } from 'react';
|
|
1
|
+
import { type CSSProperties, type ReactNode } from 'react';
|
|
2
2
|
import { type S3ImageProps } from '../components/s3-image.js';
|
|
3
3
|
export interface ImageSlotAction {
|
|
4
4
|
name: string;
|
|
@@ -19,6 +19,7 @@ export interface ImageSlotProps {
|
|
|
19
19
|
loading?: boolean;
|
|
20
20
|
accept?: string[];
|
|
21
21
|
className?: string;
|
|
22
|
+
style?: CSSProperties;
|
|
22
23
|
}
|
|
23
|
-
declare function ImageSlot({ src, s3, alt, width, height, actions, onAction, onRemove, onFile, loading, accept, className, }: ImageSlotProps): import("react/jsx-runtime").JSX.Element;
|
|
24
|
+
declare function ImageSlot({ src, s3, alt, width, height, actions, onAction, onRemove, onFile, loading, accept, className, style, }: ImageSlotProps): import("react/jsx-runtime").JSX.Element;
|
|
24
25
|
export { ImageSlot };
|
package/components/image-slot.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { useRef, useState } from 'react';
|
|
2
|
+
import { useRef, useState, } from 'react';
|
|
3
3
|
import { cn } from '../utils/utils.js';
|
|
4
4
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from '../components/ui/dropdown-menu.js';
|
|
5
5
|
import { Button } from '../components/ui/button.js';
|
|
@@ -7,11 +7,12 @@ 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, }) {
|
|
10
|
+
function ImageSlot({ src, s3, alt = '', width, height, actions = [], onAction, onRemove, onFile, loading = false, accept = ['image/gif', 'image/png', 'image/jpeg'], className, style, }) {
|
|
11
11
|
const aspectRatio = width / height;
|
|
12
12
|
const [dragState, setDragState] = useState('idle');
|
|
13
13
|
const dragCounterRef = useRef(0);
|
|
14
14
|
const fileInputRef = useRef(null);
|
|
15
|
+
const [s3ImageData, setS3ImageData] = useState(null);
|
|
15
16
|
const handleAction = (action) => {
|
|
16
17
|
onAction?.(action);
|
|
17
18
|
};
|
|
@@ -78,8 +79,22 @@ function ImageSlot({ src, s3, alt = '', width, height, actions = [], onAction, o
|
|
|
78
79
|
});
|
|
79
80
|
}
|
|
80
81
|
};
|
|
82
|
+
const onS3ImageLoaded = (result) => {
|
|
83
|
+
s3?.onLoaded?.(result);
|
|
84
|
+
setS3ImageData(result);
|
|
85
|
+
};
|
|
86
|
+
const handleRemove = () => {
|
|
87
|
+
onRemove?.();
|
|
88
|
+
setS3ImageData(null);
|
|
89
|
+
};
|
|
90
|
+
const containerWidth = s3ImageData ? s3ImageData.width : width;
|
|
91
|
+
const containerHeight = s3ImageData ? s3ImageData.height : height;
|
|
81
92
|
if (src || s3) {
|
|
82
|
-
return (_jsxs("div", { className: cn('relative group', className), style: {
|
|
93
|
+
return (_jsxs("div", { className: cn('relative group', className), style: {
|
|
94
|
+
width: containerWidth,
|
|
95
|
+
height: containerHeight,
|
|
96
|
+
...style,
|
|
97
|
+
}, 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, {}) }) }))] }));
|
|
83
98
|
}
|
|
84
99
|
// Placeholder view
|
|
85
100
|
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: {
|
|
@@ -87,6 +102,7 @@ function ImageSlot({ src, s3, alt = '', width, height, actions = [], onAction, o
|
|
|
87
102
|
maxHeight: height,
|
|
88
103
|
maxWidth: '100%',
|
|
89
104
|
height: width / aspectRatio,
|
|
105
|
+
...style,
|
|
90
106
|
}, 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))) })] })] })) }));
|
|
91
107
|
}
|
|
92
108
|
export { ImageSlot };
|
package/components/s3-image.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ImgHTMLAttributes } from 'react';
|
|
2
|
-
import type { FitOptions, ImageEdits, OverlayOptions } from '../utils/s3Image/types.js';
|
|
2
|
+
import type { FitOptions, ImageEdits, OverlayOptions, S3ImageResult } from '../utils/s3Image/types.js';
|
|
3
3
|
export interface S3ImageProps extends ImgHTMLAttributes<HTMLImageElement> {
|
|
4
4
|
imageKey: string;
|
|
5
5
|
width: number | string | 'auto';
|
|
@@ -9,7 +9,7 @@ export interface S3ImageProps extends ImgHTMLAttributes<HTMLImageElement> {
|
|
|
9
9
|
overlayWith?: OverlayOptions;
|
|
10
10
|
edits?: ImageEdits;
|
|
11
11
|
containerClassName?: string;
|
|
12
|
-
onLoaded?: () => void;
|
|
12
|
+
onLoaded?: (result: S3ImageResult) => void;
|
|
13
13
|
onError?: () => void;
|
|
14
14
|
}
|
|
15
15
|
declare function S3Image({ imageKey, width, height, fit, retina, overlayWith, edits, containerClassName, className, alt, onLoaded, onError, ...imgProps }: S3ImageProps): import("react/jsx-runtime").JSX.Element | null;
|
package/components/s3-image.js
CHANGED