@aurora-ds/components 0.24.5 → 0.24.7
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/cjs/components/forms/file-picker/FilePicker.styles.d.ts +1 -0
- package/dist/cjs/components/overlay/menu/Menu.props.d.ts +5 -0
- package/dist/cjs/components/overlay/menu/Menu.styles.d.ts +10 -1
- package/dist/cjs/index.js +70 -14
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/resources/Icons.d.ts +2 -2
- package/dist/cjs/resources/icons/UploadIcon.d.ts +2 -0
- package/dist/esm/components/forms/file-picker/FilePicker.styles.d.ts +1 -0
- package/dist/esm/components/overlay/menu/Menu.props.d.ts +5 -0
- package/dist/esm/components/overlay/menu/Menu.styles.d.ts +10 -1
- package/dist/esm/index.js +70 -14
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/resources/Icons.d.ts +2 -2
- package/dist/esm/resources/icons/UploadIcon.d.ts +2 -0
- package/dist/index.d.ts +5 -0
- package/package.json +1 -1
|
@@ -5,6 +5,7 @@ type StyleParams = {
|
|
|
5
5
|
previewMaxHeight?: CSSProperties['maxHeight'];
|
|
6
6
|
previewMaxWidth?: CSSProperties['maxWidth'];
|
|
7
7
|
previewObjectFit?: CSSProperties['objectFit'];
|
|
8
|
+
isDragOver?: boolean;
|
|
8
9
|
};
|
|
9
10
|
export declare const FILE_PICKER_STYLES: {
|
|
10
11
|
root: (params?: StyleParams | undefined) => string;
|
|
@@ -1,4 +1,13 @@
|
|
|
1
|
+
import { CSSProperties } from 'react';
|
|
1
2
|
import { AnchorOrigin, AnchorPosition } from '@hooks/useAnchorPosition.types';
|
|
3
|
+
type MenuStyleParams = {
|
|
4
|
+
isFadingIn: boolean;
|
|
5
|
+
anchorOrigin: AnchorOrigin;
|
|
6
|
+
position: AnchorPosition;
|
|
7
|
+
width?: CSSProperties['width'];
|
|
8
|
+
disableAnimation?: boolean;
|
|
9
|
+
};
|
|
2
10
|
export declare const MENU_STYLES: {
|
|
3
|
-
root: (
|
|
11
|
+
root: (args_0: MenuStyleParams) => string;
|
|
4
12
|
};
|
|
13
|
+
export {};
|
package/dist/cjs/index.js
CHANGED
|
@@ -1211,10 +1211,10 @@ const MoreHorizontalIcon = () => {
|
|
|
1211
1211
|
return (jsxRuntime.jsxs("svg", { xmlns: 'http://www.w3.org/2000/svg', width: '24', height: '24', viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: '2', strokeLinecap: 'round', strokeLinejoin: 'round', className: 'lucide lucide-ellipsis-icon lucide-ellipsis', children: [jsxRuntime.jsx("circle", { cx: '12', cy: '12', r: '1' }), jsxRuntime.jsx("circle", { cx: '19', cy: '12', r: '1' }), jsxRuntime.jsx("circle", { cx: '5', cy: '12', r: '1' })] }));
|
|
1212
1212
|
};
|
|
1213
1213
|
|
|
1214
|
-
const PlusIcon = () => (jsxRuntime.jsx("svg", { width: '16', height: '16', viewBox: '0 0 16 16', fill: 'none', xmlns: 'http://www.w3.org/2000/svg', children: jsxRuntime.jsx("path", { d: 'M8 3.33337V12.6667M3.33333 8H12.6667', stroke: 'currentColor', strokeWidth: '2', strokeLinecap: 'round', strokeLinejoin: 'round' }) }));
|
|
1215
|
-
|
|
1216
1214
|
const TrashIcon = () => (jsxRuntime.jsxs("svg", { width: '16', height: '16', viewBox: '0 0 16 16', fill: 'none', xmlns: 'http://www.w3.org/2000/svg', children: [jsxRuntime.jsx("path", { d: 'M2 4H3.33333H14', stroke: 'currentColor', strokeWidth: '2', strokeLinecap: 'round', strokeLinejoin: 'round' }), jsxRuntime.jsx("path", { d: 'M5.33325 4.00004V2.66671C5.33325 2.31309 5.47373 1.97395 5.72378 1.7239C5.97382 1.47385 6.31296 1.33337 6.66659 1.33337H9.33325C9.68687 1.33337 10.026 1.47385 10.276 1.7239C10.5261 1.97395 10.6666 2.31309 10.6666 2.66671V4.00004M12.6666 4.00004V13.3334C12.6666 13.687 12.5261 14.0261 12.276 14.2762C12.026 14.5262 11.6868 14.6667 11.3333 14.6667H4.66659C4.31296 14.6667 3.97382 14.5262 3.72378 14.2762C3.47373 14.0261 3.33325 13.687 3.33325 13.3334V4.00004H12.6666Z', stroke: 'currentColor', strokeWidth: '2', strokeLinecap: 'round', strokeLinejoin: 'round' })] }));
|
|
1217
1215
|
|
|
1216
|
+
const UploadIcon = () => (jsxRuntime.jsxs("svg", { xmlns: 'http://www.w3.org/2000/svg', width: '24', height: '24', viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', "stroke-width": '2', "stroke-linecap": 'round', "stroke-linejoin": 'round', className: 'lucide lucide-upload-icon lucide-upload', children: [jsxRuntime.jsx("path", { d: 'M12 3v12' }), jsxRuntime.jsx("path", { d: 'm17 8-5-5-5 5' }), jsxRuntime.jsx("path", { d: 'M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4' })] }));
|
|
1217
|
+
|
|
1218
1218
|
/**
|
|
1219
1219
|
* Input component
|
|
1220
1220
|
*/
|
|
@@ -1405,7 +1405,7 @@ const SelectItem = ({ option, isSelected = false, onSelect }) => {
|
|
|
1405
1405
|
SelectItem.displayName = 'SelectItem';
|
|
1406
1406
|
|
|
1407
1407
|
const MENU_STYLES = theme.createStyles((theme) => ({
|
|
1408
|
-
root: (isFadingIn, anchorOrigin, position, width) => ({
|
|
1408
|
+
root: ({ isFadingIn, anchorOrigin, position, width, disableAnimation = false }) => ({
|
|
1409
1409
|
position: 'fixed',
|
|
1410
1410
|
zIndex: theme.zIndex.popover,
|
|
1411
1411
|
marginTop: theme.spacing.xs,
|
|
@@ -1417,10 +1417,10 @@ const MENU_STYLES = theme.createStyles((theme) => ({
|
|
|
1417
1417
|
maxHeight: MENU_ITEM_SIZE * 8,
|
|
1418
1418
|
overflowY: 'auto',
|
|
1419
1419
|
width,
|
|
1420
|
-
opacity: isFadingIn ? 1 : 0,
|
|
1421
|
-
transform: isFadingIn ? 'scale(1)' : 'scale(0.95)',
|
|
1420
|
+
opacity: disableAnimation ? 1 : (isFadingIn ? 1 : 0),
|
|
1421
|
+
transform: disableAnimation ? 'scale(1)' : (isFadingIn ? 'scale(1)' : 'scale(0.95)'),
|
|
1422
1422
|
transformOrigin: anchorOrigin === 'right' ? 'top right' : 'top left',
|
|
1423
|
-
transition: `opacity ${DEFAULT_TRANSITION_DURATION_MS}ms ease-out, transform ${DEFAULT_TRANSITION_DURATION_MS}ms ease-out`,
|
|
1423
|
+
transition: disableAnimation ? 'none' : `opacity ${DEFAULT_TRANSITION_DURATION_MS}ms ease-out, transform ${DEFAULT_TRANSITION_DURATION_MS}ms ease-out`,
|
|
1424
1424
|
top: position?.top ?? 0,
|
|
1425
1425
|
left: position?.left ?? 0,
|
|
1426
1426
|
visibility: position ? 'visible' : 'hidden',
|
|
@@ -1554,7 +1554,7 @@ const useTransitionRender = (isOpen, duration = DEFAULT_TRANSITION_DURATION_MS)
|
|
|
1554
1554
|
};
|
|
1555
1555
|
};
|
|
1556
1556
|
|
|
1557
|
-
const Menu = ({ anchor, onClose, children, anchorOrigin = 'right', width }) => {
|
|
1557
|
+
const Menu = ({ anchor, onClose, children, anchorOrigin = 'right', width, disableAnimation = false }) => {
|
|
1558
1558
|
// refs
|
|
1559
1559
|
const menuRef = React.useRef(null);
|
|
1560
1560
|
const anchorRef = React.useRef(null);
|
|
@@ -1579,7 +1579,7 @@ const Menu = ({ anchor, onClose, children, anchorOrigin = 'right', width }) => {
|
|
|
1579
1579
|
if (!isVisible) {
|
|
1580
1580
|
return null;
|
|
1581
1581
|
}
|
|
1582
|
-
return reactDom.createPortal(jsxRuntime.jsx("div", { ref: menuRef, className: MENU_STYLES.root(isFadingIn, anchorOrigin, position, width), children: children }), document.body);
|
|
1582
|
+
return reactDom.createPortal(jsxRuntime.jsx("div", { ref: menuRef, className: MENU_STYLES.root({ isFadingIn, anchorOrigin, position, width, disableAnimation }), children: children }), document.body);
|
|
1583
1583
|
};
|
|
1584
1584
|
Menu.displayName = 'Menu';
|
|
1585
1585
|
|
|
@@ -2111,17 +2111,20 @@ const FILE_PICKER_STYLES = theme.createStyles((theme) => ({
|
|
|
2111
2111
|
alignItems: 'center',
|
|
2112
2112
|
justifyContent: 'center',
|
|
2113
2113
|
gap: theme.spacing.sm,
|
|
2114
|
-
padding: theme.spacing.
|
|
2115
|
-
border: `2px dashed ${theme.colors.border}`,
|
|
2114
|
+
padding: theme.spacing.md,
|
|
2115
|
+
border: `2px dashed ${params?.isDragOver ? theme.colors.primary : theme.colors.border}`,
|
|
2116
2116
|
borderRadius: theme.radius.md,
|
|
2117
|
-
backgroundColor: theme.colors.surface,
|
|
2117
|
+
backgroundColor: params?.isDragOver ? theme.colors.surfaceHover : theme.colors.surface,
|
|
2118
2118
|
cursor: 'pointer',
|
|
2119
2119
|
transition: `all ${theme.transition.fast}`,
|
|
2120
|
-
minHeight: params?.dropzoneHeight ??
|
|
2120
|
+
minHeight: params?.dropzoneHeight ?? undefined,
|
|
2121
2121
|
'&:hover': {
|
|
2122
2122
|
borderColor: theme.colors.primary,
|
|
2123
2123
|
backgroundColor: theme.colors.surfaceHover,
|
|
2124
2124
|
},
|
|
2125
|
+
'& > *': {
|
|
2126
|
+
pointerEvents: 'none',
|
|
2127
|
+
},
|
|
2125
2128
|
}),
|
|
2126
2129
|
dropzoneDisabled: {
|
|
2127
2130
|
opacity: 0.5,
|
|
@@ -2183,6 +2186,8 @@ const FILE_PICKER_STYLES = theme.createStyles((theme) => ({
|
|
|
2183
2186
|
const FilePicker = ({ label, accept, preview, previewIsImage = true, previewAlt = 'Preview', error, onSelect, onClear, disabled = false, placeholder = 'Click to upload a file', hint, icon: IconComponent, clearIcon: ClearIconComponent, clearAriaLabel = 'Remove file', width, dropzoneHeight, previewMaxHeight, previewMaxWidth, previewObjectFit, }) => {
|
|
2184
2187
|
// refs
|
|
2185
2188
|
const inputRef = React.useRef(null);
|
|
2189
|
+
// state
|
|
2190
|
+
const [isDragOver, setIsDragOver] = React.useState(false);
|
|
2186
2191
|
// handlers
|
|
2187
2192
|
const handleClick = () => {
|
|
2188
2193
|
if (!disabled && inputRef.current) {
|
|
@@ -2207,6 +2212,56 @@ const FilePicker = ({ label, accept, preview, previewIsImage = true, previewAlt
|
|
|
2207
2212
|
handleClick();
|
|
2208
2213
|
}
|
|
2209
2214
|
};
|
|
2215
|
+
const handleDragEnter = (e) => {
|
|
2216
|
+
e.preventDefault();
|
|
2217
|
+
e.stopPropagation();
|
|
2218
|
+
if (!disabled) {
|
|
2219
|
+
setIsDragOver(true);
|
|
2220
|
+
}
|
|
2221
|
+
};
|
|
2222
|
+
const handleDragOver = (e) => {
|
|
2223
|
+
e.preventDefault();
|
|
2224
|
+
e.stopPropagation();
|
|
2225
|
+
};
|
|
2226
|
+
const handleDragLeave = (e) => {
|
|
2227
|
+
e.preventDefault();
|
|
2228
|
+
e.stopPropagation();
|
|
2229
|
+
// Only set isDragOver to false if we're actually leaving the dropzone
|
|
2230
|
+
// (not just entering a child element)
|
|
2231
|
+
if (e.currentTarget === e.target || !e.currentTarget.contains(e.relatedTarget)) {
|
|
2232
|
+
setIsDragOver(false);
|
|
2233
|
+
}
|
|
2234
|
+
};
|
|
2235
|
+
const handleDrop = (e) => {
|
|
2236
|
+
e.preventDefault();
|
|
2237
|
+
e.stopPropagation();
|
|
2238
|
+
setIsDragOver(false);
|
|
2239
|
+
if (!disabled) {
|
|
2240
|
+
const file = e.dataTransfer.files?.[0] || null;
|
|
2241
|
+
if (file) {
|
|
2242
|
+
// Validate file type if accept is specified
|
|
2243
|
+
if (accept) {
|
|
2244
|
+
const acceptedTypes = accept.split(',').map(type => type.trim());
|
|
2245
|
+
const isAccepted = acceptedTypes.some(type => {
|
|
2246
|
+
if (type.startsWith('.')) {
|
|
2247
|
+
// Extension check
|
|
2248
|
+
return file.name.toLowerCase().endsWith(type.toLowerCase());
|
|
2249
|
+
}
|
|
2250
|
+
else {
|
|
2251
|
+
// MIME type check
|
|
2252
|
+
return file.type === type || file.type.match(new RegExp(type.replace('*', '.*')));
|
|
2253
|
+
}
|
|
2254
|
+
});
|
|
2255
|
+
if (isAccepted) {
|
|
2256
|
+
onSelect(file);
|
|
2257
|
+
}
|
|
2258
|
+
}
|
|
2259
|
+
else {
|
|
2260
|
+
onSelect(file);
|
|
2261
|
+
}
|
|
2262
|
+
}
|
|
2263
|
+
}
|
|
2264
|
+
};
|
|
2210
2265
|
// Determine if preview is a string (image URL) or ReactNode
|
|
2211
2266
|
const isImagePreview = typeof preview === 'string' && previewIsImage;
|
|
2212
2267
|
const hasPreview = preview !== null && preview !== undefined;
|
|
@@ -2217,8 +2272,9 @@ const FilePicker = ({ label, accept, preview, previewIsImage = true, previewAlt
|
|
|
2217
2272
|
previewMaxHeight,
|
|
2218
2273
|
previewMaxWidth,
|
|
2219
2274
|
previewObjectFit,
|
|
2275
|
+
isDragOver,
|
|
2220
2276
|
};
|
|
2221
|
-
return (jsxRuntime.jsxs("div", { className: FILE_PICKER_STYLES.root(styleParams), children: [label && (jsxRuntime.jsx(Text, { fontSize: 'sm', variant: 'label', children: label })), jsxRuntime.jsx("input", { ref: inputRef, type: 'file', accept: accept, className: FILE_PICKER_STYLES.hiddenInput, onChange: handleChange, disabled: disabled }), hasPreview ? (jsxRuntime.jsxs("div", { className: FILE_PICKER_STYLES.previewContainer, children: [isImagePreview ? (jsxRuntime.jsx("img", { src: preview, alt: previewAlt, className: FILE_PICKER_STYLES.preview(styleParams) })) : (preview), !disabled && ClearIconComponent && (jsxRuntime.jsx("div", { className: FILE_PICKER_STYLES.clearButton, children: jsxRuntime.jsx(IconButton, { icon: jsxRuntime.jsx(ClearIconComponent, {}), onClick: handleClear, ariaLabel: clearAriaLabel, variant: 'contained', size: 'small', textColor: 'surface' }) }))] })) : (jsxRuntime.jsxs("div", { className: `${FILE_PICKER_STYLES.dropzone(styleParams)} ${disabled ? FILE_PICKER_STYLES.dropzoneDisabled : ''}`, onClick: handleClick, role: 'button', tabIndex: disabled ? -1 : 0, onKeyDown: handleKeyDown, children: [IconComponent && (jsxRuntime.jsx(Icon, { size: '
|
|
2277
|
+
return (jsxRuntime.jsxs("div", { className: FILE_PICKER_STYLES.root(styleParams), children: [label && (jsxRuntime.jsx(Text, { fontSize: 'sm', variant: 'label', children: label })), jsxRuntime.jsx("input", { ref: inputRef, type: 'file', accept: accept, className: FILE_PICKER_STYLES.hiddenInput, onChange: handleChange, disabled: disabled }), hasPreview ? (jsxRuntime.jsxs("div", { className: FILE_PICKER_STYLES.previewContainer, children: [isImagePreview ? (jsxRuntime.jsx("img", { src: preview, alt: previewAlt, className: FILE_PICKER_STYLES.preview(styleParams) })) : (preview), !disabled && ClearIconComponent && (jsxRuntime.jsx("div", { className: FILE_PICKER_STYLES.clearButton, children: jsxRuntime.jsx(IconButton, { icon: jsxRuntime.jsx(ClearIconComponent, {}), onClick: handleClear, ariaLabel: clearAriaLabel, variant: 'contained', size: 'small', textColor: 'surface' }) }))] })) : (jsxRuntime.jsxs("div", { className: `${FILE_PICKER_STYLES.dropzone(styleParams)} ${disabled ? FILE_PICKER_STYLES.dropzoneDisabled : ''}`, onClick: handleClick, role: 'button', tabIndex: disabled ? -1 : 0, onKeyDown: handleKeyDown, onDragEnter: handleDragEnter, onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDrop: handleDrop, children: [jsxRuntime.jsxs(Stack, { children: [IconComponent && (jsxRuntime.jsx(Icon, { size: 'md', color: 'text', children: jsxRuntime.jsx(IconComponent, {}) })), jsxRuntime.jsx(Text, { children: placeholder })] }), hint && (jsxRuntime.jsx(Text, { fontSize: 'xs', color: 'textSecondary', children: hint }))] })), error && (jsxRuntime.jsx(Text, { fontSize: 'sm', color: 'error', children: error }))] }));
|
|
2222
2278
|
};
|
|
2223
2279
|
FilePicker.displayName = 'FilePicker';
|
|
2224
2280
|
|
|
@@ -2237,7 +2293,7 @@ FilePicker.displayName = 'FilePicker';
|
|
|
2237
2293
|
* ```
|
|
2238
2294
|
*/
|
|
2239
2295
|
const ImagePicker = ({ label, preview, error, onSelect, onClear, disabled = false, placeholder = 'Click to upload an image', hint = 'JPEG, PNG or WebP', previewAlt = 'Image preview', clearAriaLabel = 'Remove image', width, dropzoneHeight, previewMaxHeight, previewMaxWidth, previewObjectFit, }) => {
|
|
2240
|
-
return (jsxRuntime.jsx(FilePicker, { label: label, accept: 'image/jpeg,image/png,image/webp', preview: preview, previewIsImage: true, previewAlt: previewAlt, error: error, onSelect: onSelect, onClear: onClear, disabled: disabled, placeholder: placeholder, hint: hint, icon:
|
|
2296
|
+
return (jsxRuntime.jsx(FilePicker, { label: label, accept: 'image/jpeg,image/png,image/webp', preview: preview, previewIsImage: true, previewAlt: previewAlt, error: error, onSelect: onSelect, onClear: onClear, disabled: disabled, placeholder: placeholder, hint: hint, icon: UploadIcon, clearIcon: TrashIcon, clearAriaLabel: clearAriaLabel, width: width, dropzoneHeight: dropzoneHeight, previewMaxHeight: previewMaxHeight, previewMaxWidth: previewMaxWidth, previewObjectFit: previewObjectFit }));
|
|
2241
2297
|
};
|
|
2242
2298
|
ImagePicker.displayName = 'ImagePicker';
|
|
2243
2299
|
|