@aurora-ds/components 0.23.5 → 0.24.0
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/README.md +1 -1
- package/dist/cjs/components/forms/file-picker/FilePicker.d.ts +24 -0
- package/dist/cjs/components/forms/file-picker/FilePicker.props.d.ts +99 -0
- package/dist/cjs/components/forms/file-picker/FilePicker.styles.d.ts +18 -0
- package/dist/cjs/components/forms/file-picker/index.d.ts +2 -0
- package/dist/cjs/components/forms/image-picker/ImagePicker.d.ts +18 -0
- package/dist/cjs/components/forms/image-picker/ImagePicker.props.d.ts +76 -0
- package/dist/cjs/components/forms/image-picker/index.d.ts +2 -0
- package/dist/cjs/components/index.d.ts +2 -0
- package/dist/cjs/index.js +154 -4
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/resources/Icons.d.ts +3 -1
- package/dist/cjs/resources/icons/PlusIcon.d.ts +2 -0
- package/dist/cjs/resources/icons/TrashIcon.d.ts +2 -0
- package/dist/esm/components/forms/file-picker/FilePicker.d.ts +24 -0
- package/dist/esm/components/forms/file-picker/FilePicker.props.d.ts +99 -0
- package/dist/esm/components/forms/file-picker/FilePicker.styles.d.ts +18 -0
- package/dist/esm/components/forms/file-picker/index.d.ts +2 -0
- package/dist/esm/components/forms/image-picker/ImagePicker.d.ts +18 -0
- package/dist/esm/components/forms/image-picker/ImagePicker.props.d.ts +76 -0
- package/dist/esm/components/forms/image-picker/index.d.ts +2 -0
- package/dist/esm/components/index.d.ts +2 -0
- package/dist/esm/index.js +153 -5
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/resources/Icons.d.ts +3 -1
- package/dist/esm/resources/icons/PlusIcon.d.ts +2 -0
- package/dist/esm/resources/icons/TrashIcon.d.ts +2 -0
- package/dist/index.d.ts +216 -3
- package/package.json +1 -1
|
@@ -10,4 +10,6 @@ import { EyeIcon } from '@resources/icons/EyeIcon.tsx';
|
|
|
10
10
|
import { EyeOffIcon } from '@resources/icons/EyeOffIcon.tsx';
|
|
11
11
|
import { InfoIcon } from '@resources/icons/InfoIcon.tsx';
|
|
12
12
|
import { MoreHorizontalIcon } from '@resources/icons/MoreHorizontalIcon.tsx';
|
|
13
|
-
|
|
13
|
+
import { PlusIcon } from '@resources/icons/PlusIcon.tsx';
|
|
14
|
+
import { TrashIcon } from '@resources/icons/TrashIcon.tsx';
|
|
15
|
+
export { AlertCircleIcon, AlertTriangleIcon, CalendarIcon, CheckCircleIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, InfoIcon, MoreHorizontalIcon, EyeIcon, EyeOffIcon, CloseIcon, PlusIcon, TrashIcon };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { FilePickerProps } from '@components/forms/file-picker/FilePicker.props.ts';
|
|
3
|
+
/**
|
|
4
|
+
* Generic file picker component with drag-and-drop style interface.
|
|
5
|
+
* Supports custom preview, icons, and styling for use in external libraries.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```tsx
|
|
9
|
+
* // Basic usage with image
|
|
10
|
+
* <FilePicker
|
|
11
|
+
* label="Upload Image"
|
|
12
|
+
* accept="image/*"
|
|
13
|
+
* preview={imagePreview}
|
|
14
|
+
* placeholder="Click to upload"
|
|
15
|
+
* hint="JPEG, PNG or WebP"
|
|
16
|
+
* icon={PlusIcon}
|
|
17
|
+
* clearIcon={TrashIcon}
|
|
18
|
+
* onSelect={handleSelect}
|
|
19
|
+
* onClear={handleClear}
|
|
20
|
+
* />
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
declare const FilePicker: FC<FilePickerProps>;
|
|
24
|
+
export default FilePicker;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { ComponentType, CSSProperties, ReactNode, SVGProps } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* SVG icon component type (compatible with Aurora-DS Icon)
|
|
4
|
+
*/
|
|
5
|
+
export type SvgIconComponent = ComponentType<SVGProps<SVGSVGElement>>;
|
|
6
|
+
export type FilePickerProps = {
|
|
7
|
+
/**
|
|
8
|
+
* Label for the input
|
|
9
|
+
*/
|
|
10
|
+
label?: string;
|
|
11
|
+
/**
|
|
12
|
+
* Accepted file types (MIME types)
|
|
13
|
+
* @example 'image/jpeg,image/png,image/webp'
|
|
14
|
+
* @example 'application/pdf'
|
|
15
|
+
* @example '.jpg,.png,.pdf'
|
|
16
|
+
*/
|
|
17
|
+
accept?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Preview content to display when a file is selected
|
|
20
|
+
* Can be a URL string for images or a ReactNode for custom preview
|
|
21
|
+
*/
|
|
22
|
+
preview?: string | ReactNode | null;
|
|
23
|
+
/**
|
|
24
|
+
* Whether the preview is an image URL
|
|
25
|
+
* @default true when preview is a string
|
|
26
|
+
*/
|
|
27
|
+
previewIsImage?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Alt text for image preview
|
|
30
|
+
*/
|
|
31
|
+
previewAlt?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Error message to display
|
|
34
|
+
*/
|
|
35
|
+
error?: string | null;
|
|
36
|
+
/**
|
|
37
|
+
* Callback when a file is selected
|
|
38
|
+
*/
|
|
39
|
+
onSelect: (file: File | null) => void;
|
|
40
|
+
/**
|
|
41
|
+
* Callback when the file is cleared
|
|
42
|
+
*/
|
|
43
|
+
onClear: () => void;
|
|
44
|
+
/**
|
|
45
|
+
* Whether the input is disabled
|
|
46
|
+
*/
|
|
47
|
+
disabled?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Placeholder text shown in the dropzone
|
|
50
|
+
*/
|
|
51
|
+
placeholder?: string;
|
|
52
|
+
/**
|
|
53
|
+
* Hint text shown below the placeholder (e.g., accepted formats)
|
|
54
|
+
*/
|
|
55
|
+
hint?: string;
|
|
56
|
+
/**
|
|
57
|
+
* Icon component to display in the dropzone
|
|
58
|
+
* Should be an SVG component (e.g., from @resources/Icons)
|
|
59
|
+
*/
|
|
60
|
+
icon?: SvgIconComponent;
|
|
61
|
+
/**
|
|
62
|
+
* Icon component to display on the clear button
|
|
63
|
+
* Should be an SVG component (e.g., from @resources/Icons)
|
|
64
|
+
*/
|
|
65
|
+
clearIcon?: SvgIconComponent;
|
|
66
|
+
/**
|
|
67
|
+
* Aria label for the clear button
|
|
68
|
+
*/
|
|
69
|
+
clearAriaLabel?: string;
|
|
70
|
+
/**
|
|
71
|
+
* Width of the FilePicker container
|
|
72
|
+
* @example '400px'
|
|
73
|
+
* @example '100%'
|
|
74
|
+
*/
|
|
75
|
+
width?: CSSProperties['width'];
|
|
76
|
+
/**
|
|
77
|
+
* Height of the dropzone (when no preview)
|
|
78
|
+
* @example '200px'
|
|
79
|
+
* @default '120px'
|
|
80
|
+
*/
|
|
81
|
+
dropzoneHeight?: CSSProperties['height'];
|
|
82
|
+
/**
|
|
83
|
+
* Max height of the preview image
|
|
84
|
+
* @example '300px'
|
|
85
|
+
* @default '200px'
|
|
86
|
+
*/
|
|
87
|
+
previewMaxHeight?: CSSProperties['maxHeight'];
|
|
88
|
+
/**
|
|
89
|
+
* Max width of the preview image
|
|
90
|
+
* @example '400px'
|
|
91
|
+
* @default '100%'
|
|
92
|
+
*/
|
|
93
|
+
previewMaxWidth?: CSSProperties['maxWidth'];
|
|
94
|
+
/**
|
|
95
|
+
* Object fit for the preview image
|
|
96
|
+
* @default 'cover'
|
|
97
|
+
*/
|
|
98
|
+
previewObjectFit?: CSSProperties['objectFit'];
|
|
99
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { CSSProperties } from 'react';
|
|
2
|
+
type StyleParams = {
|
|
3
|
+
width?: CSSProperties['width'];
|
|
4
|
+
dropzoneHeight?: CSSProperties['height'];
|
|
5
|
+
previewMaxHeight?: CSSProperties['maxHeight'];
|
|
6
|
+
previewMaxWidth?: CSSProperties['maxWidth'];
|
|
7
|
+
previewObjectFit?: CSSProperties['objectFit'];
|
|
8
|
+
};
|
|
9
|
+
export declare const FILE_PICKER_STYLES: {
|
|
10
|
+
root: (params?: StyleParams | undefined) => string;
|
|
11
|
+
dropzone: (params?: StyleParams | undefined) => string;
|
|
12
|
+
dropzoneDisabled: string;
|
|
13
|
+
hiddenInput: string;
|
|
14
|
+
previewContainer: string;
|
|
15
|
+
preview: (params?: StyleParams | undefined) => string;
|
|
16
|
+
clearButton: string;
|
|
17
|
+
};
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { ImagePickerProps } from '@components/forms/image-picker/ImagePicker.props.ts';
|
|
3
|
+
/**
|
|
4
|
+
* Image picker component built on top of the generic FilePicker.
|
|
5
|
+
* Pre-configured for image uploads with JPEG, PNG, and WebP support.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```tsx
|
|
9
|
+
* <ImagePicker
|
|
10
|
+
* label="Profile Picture"
|
|
11
|
+
* preview={imageUrl}
|
|
12
|
+
* onSelect={handleImageSelect}
|
|
13
|
+
* onClear={handleImageClear}
|
|
14
|
+
* />
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
declare const ImagePicker: FC<ImagePickerProps>;
|
|
18
|
+
export default ImagePicker;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { CSSProperties } from 'react';
|
|
2
|
+
export type ImagePickerProps = {
|
|
3
|
+
/**
|
|
4
|
+
* Label for the input
|
|
5
|
+
*/
|
|
6
|
+
label?: string;
|
|
7
|
+
/**
|
|
8
|
+
* Preview URL of the selected image
|
|
9
|
+
*/
|
|
10
|
+
preview: string | null;
|
|
11
|
+
/**
|
|
12
|
+
* Error message to display
|
|
13
|
+
*/
|
|
14
|
+
error?: string | null;
|
|
15
|
+
/**
|
|
16
|
+
* Callback when a file is selected
|
|
17
|
+
*/
|
|
18
|
+
onSelect: (file: File | null) => void;
|
|
19
|
+
/**
|
|
20
|
+
* Callback when the image is cleared
|
|
21
|
+
*/
|
|
22
|
+
onClear: () => void;
|
|
23
|
+
/**
|
|
24
|
+
* Whether the input is disabled
|
|
25
|
+
*/
|
|
26
|
+
disabled?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Placeholder text shown in the dropzone
|
|
29
|
+
* @default 'Click to upload an image'
|
|
30
|
+
*/
|
|
31
|
+
placeholder?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Hint text shown below the placeholder
|
|
34
|
+
* @default 'JPEG, PNG or WebP'
|
|
35
|
+
*/
|
|
36
|
+
hint?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Alt text for image preview
|
|
39
|
+
* @default 'Image preview'
|
|
40
|
+
*/
|
|
41
|
+
previewAlt?: string;
|
|
42
|
+
/**
|
|
43
|
+
* Aria label for the clear button
|
|
44
|
+
* @default 'Remove image'
|
|
45
|
+
*/
|
|
46
|
+
clearAriaLabel?: string;
|
|
47
|
+
/**
|
|
48
|
+
* Width of the ImagePicker container
|
|
49
|
+
* @example '400px'
|
|
50
|
+
* @example '100%'
|
|
51
|
+
*/
|
|
52
|
+
width?: CSSProperties['width'];
|
|
53
|
+
/**
|
|
54
|
+
* Height of the dropzone (when no preview)
|
|
55
|
+
* @example '200px'
|
|
56
|
+
* @default '120px'
|
|
57
|
+
*/
|
|
58
|
+
dropzoneHeight?: CSSProperties['height'];
|
|
59
|
+
/**
|
|
60
|
+
* Max height of the preview image
|
|
61
|
+
* @example '300px'
|
|
62
|
+
* @default '200px'
|
|
63
|
+
*/
|
|
64
|
+
previewMaxHeight?: CSSProperties['maxHeight'];
|
|
65
|
+
/**
|
|
66
|
+
* Max width of the preview image
|
|
67
|
+
* @example '400px'
|
|
68
|
+
* @default '100%'
|
|
69
|
+
*/
|
|
70
|
+
previewMaxWidth?: CSSProperties['maxWidth'];
|
|
71
|
+
/**
|
|
72
|
+
* Object fit for the preview image
|
|
73
|
+
* @default 'cover'
|
|
74
|
+
*/
|
|
75
|
+
previewObjectFit?: CSSProperties['objectFit'];
|
|
76
|
+
};
|
|
@@ -11,6 +11,8 @@ export * from '@components/forms/input';
|
|
|
11
11
|
export * from '@components/forms/textarea';
|
|
12
12
|
export * from '@components/forms/select';
|
|
13
13
|
export * from '@components/forms/date-picker';
|
|
14
|
+
export * from '@components/forms/file-picker';
|
|
15
|
+
export * from '@components/forms/image-picker';
|
|
14
16
|
export * from '@components/layout/box';
|
|
15
17
|
export * from '@components/layout/stack';
|
|
16
18
|
export * from '@components/layout/card';
|
package/dist/esm/index.js
CHANGED
|
@@ -1128,7 +1128,7 @@ const INPUT_STYLES = createStyles((theme) => ({
|
|
|
1128
1128
|
borderColor: theme.colors.primary,
|
|
1129
1129
|
},
|
|
1130
1130
|
'::placeholder': {
|
|
1131
|
-
color: theme.colors.
|
|
1131
|
+
color: theme.colors.textSecondary,
|
|
1132
1132
|
fontSize: theme.fontSize.sm,
|
|
1133
1133
|
},
|
|
1134
1134
|
...(disabled && {
|
|
@@ -1225,6 +1225,10 @@ const MoreHorizontalIcon = () => {
|
|
|
1225
1225
|
return (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: [jsx("circle", { cx: '12', cy: '12', r: '1' }), jsx("circle", { cx: '19', cy: '12', r: '1' }), jsx("circle", { cx: '5', cy: '12', r: '1' })] }));
|
|
1226
1226
|
};
|
|
1227
1227
|
|
|
1228
|
+
const PlusIcon = () => (jsx("svg", { width: '16', height: '16', viewBox: '0 0 16 16', fill: 'none', xmlns: 'http://www.w3.org/2000/svg', children: jsx("path", { d: 'M8 3.33337V12.6667M3.33333 8H12.6667', stroke: 'currentColor', strokeWidth: '2', strokeLinecap: 'round', strokeLinejoin: 'round' }) }));
|
|
1229
|
+
|
|
1230
|
+
const TrashIcon = () => (jsxs("svg", { width: '16', height: '16', viewBox: '0 0 16 16', fill: 'none', xmlns: 'http://www.w3.org/2000/svg', children: [jsx("path", { d: 'M2 4H3.33333H14', stroke: 'currentColor', strokeWidth: '2', strokeLinecap: 'round', strokeLinejoin: 'round' }), 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' })] }));
|
|
1231
|
+
|
|
1228
1232
|
/**
|
|
1229
1233
|
* Input component
|
|
1230
1234
|
*/
|
|
@@ -1271,7 +1275,7 @@ const TEXTAREA_STYLES = createStyles((theme) => ({
|
|
|
1271
1275
|
borderColor: theme.colors.primary,
|
|
1272
1276
|
},
|
|
1273
1277
|
'::placeholder': {
|
|
1274
|
-
color: theme.colors.
|
|
1278
|
+
color: theme.colors.textSecondary,
|
|
1275
1279
|
fontSize: theme.fontSize.sm,
|
|
1276
1280
|
textOverflow: 'ellipsis',
|
|
1277
1281
|
overflow: 'hidden',
|
|
@@ -1371,7 +1375,7 @@ const SELECT_STYLES = createStyles((theme) => ({
|
|
|
1371
1375
|
placeholder: {
|
|
1372
1376
|
flex: 1,
|
|
1373
1377
|
fontSize: theme.fontSize.md,
|
|
1374
|
-
color: theme.colors.
|
|
1378
|
+
color: theme.colors.textSecondary
|
|
1375
1379
|
}
|
|
1376
1380
|
}));
|
|
1377
1381
|
|
|
@@ -2020,7 +2024,7 @@ const DATE_PICKER_STYLES = createStyles((theme) => ({
|
|
|
2020
2024
|
borderColor: theme.colors.primary,
|
|
2021
2025
|
},
|
|
2022
2026
|
'::placeholder': {
|
|
2023
|
-
color: theme.colors.
|
|
2027
|
+
color: theme.colors.textSecondary,
|
|
2024
2028
|
},
|
|
2025
2029
|
':disabled': {
|
|
2026
2030
|
color: theme.colors.disabledText,
|
|
@@ -2107,6 +2111,150 @@ const DatePicker = ({ value, onChange, label, mandatory = false, placeholder, di
|
|
|
2107
2111
|
DatePicker.displayName = 'DatePicker';
|
|
2108
2112
|
var DatePicker_default = memo(DatePicker);
|
|
2109
2113
|
|
|
2114
|
+
const FILE_PICKER_STYLES = createStyles((theme) => ({
|
|
2115
|
+
root: (params) => ({
|
|
2116
|
+
display: 'flex',
|
|
2117
|
+
flexDirection: 'column',
|
|
2118
|
+
gap: theme.spacing.xs,
|
|
2119
|
+
width: params?.width ?? '100%',
|
|
2120
|
+
}),
|
|
2121
|
+
dropzone: (params) => ({
|
|
2122
|
+
position: 'relative',
|
|
2123
|
+
display: 'flex',
|
|
2124
|
+
flexDirection: 'column',
|
|
2125
|
+
alignItems: 'center',
|
|
2126
|
+
justifyContent: 'center',
|
|
2127
|
+
gap: theme.spacing.sm,
|
|
2128
|
+
padding: theme.spacing.lg,
|
|
2129
|
+
border: `2px dashed ${theme.colors.border}`,
|
|
2130
|
+
borderRadius: theme.radius.md,
|
|
2131
|
+
backgroundColor: theme.colors.surface,
|
|
2132
|
+
cursor: 'pointer',
|
|
2133
|
+
transition: `all ${theme.transition.fast}`,
|
|
2134
|
+
minHeight: params?.dropzoneHeight ?? '120px',
|
|
2135
|
+
'&:hover': {
|
|
2136
|
+
borderColor: theme.colors.primary,
|
|
2137
|
+
backgroundColor: theme.colors.surfaceHover,
|
|
2138
|
+
},
|
|
2139
|
+
}),
|
|
2140
|
+
dropzoneDisabled: {
|
|
2141
|
+
opacity: 0.5,
|
|
2142
|
+
cursor: 'not-allowed',
|
|
2143
|
+
'&:hover': {
|
|
2144
|
+
borderColor: theme.colors.border,
|
|
2145
|
+
backgroundColor: theme.colors.surface,
|
|
2146
|
+
},
|
|
2147
|
+
},
|
|
2148
|
+
hiddenInput: {
|
|
2149
|
+
display: 'none',
|
|
2150
|
+
},
|
|
2151
|
+
previewContainer: {
|
|
2152
|
+
position: 'relative',
|
|
2153
|
+
width: '100%',
|
|
2154
|
+
borderRadius: theme.radius.md,
|
|
2155
|
+
overflow: 'hidden',
|
|
2156
|
+
},
|
|
2157
|
+
preview: (params) => ({
|
|
2158
|
+
width: '100%',
|
|
2159
|
+
maxHeight: params?.previewMaxHeight ?? '200px',
|
|
2160
|
+
maxWidth: params?.previewMaxWidth ?? '100%',
|
|
2161
|
+
objectFit: params?.previewObjectFit ?? 'cover',
|
|
2162
|
+
borderRadius: theme.radius.md,
|
|
2163
|
+
}),
|
|
2164
|
+
clearButton: {
|
|
2165
|
+
position: 'absolute',
|
|
2166
|
+
top: theme.spacing.xs,
|
|
2167
|
+
right: theme.spacing.xs,
|
|
2168
|
+
'& button': {
|
|
2169
|
+
backgroundColor: 'rgba(0, 0, 0, 0.6)',
|
|
2170
|
+
'&:hover': {
|
|
2171
|
+
backgroundColor: 'rgba(0, 0, 0, 0.8)',
|
|
2172
|
+
},
|
|
2173
|
+
},
|
|
2174
|
+
},
|
|
2175
|
+
}));
|
|
2176
|
+
|
|
2177
|
+
/**
|
|
2178
|
+
* Generic file picker component with drag-and-drop style interface.
|
|
2179
|
+
* Supports custom preview, icons, and styling for use in external libraries.
|
|
2180
|
+
*
|
|
2181
|
+
* @example
|
|
2182
|
+
* ```tsx
|
|
2183
|
+
* // Basic usage with image
|
|
2184
|
+
* <FilePicker
|
|
2185
|
+
* label="Upload Image"
|
|
2186
|
+
* accept="image/*"
|
|
2187
|
+
* preview={imagePreview}
|
|
2188
|
+
* placeholder="Click to upload"
|
|
2189
|
+
* hint="JPEG, PNG or WebP"
|
|
2190
|
+
* icon={PlusIcon}
|
|
2191
|
+
* clearIcon={TrashIcon}
|
|
2192
|
+
* onSelect={handleSelect}
|
|
2193
|
+
* onClear={handleClear}
|
|
2194
|
+
* />
|
|
2195
|
+
* ```
|
|
2196
|
+
*/
|
|
2197
|
+
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, }) => {
|
|
2198
|
+
// refs
|
|
2199
|
+
const inputRef = useRef(null);
|
|
2200
|
+
// handlers
|
|
2201
|
+
const handleClick = () => {
|
|
2202
|
+
if (!disabled && inputRef.current) {
|
|
2203
|
+
inputRef.current.click();
|
|
2204
|
+
}
|
|
2205
|
+
};
|
|
2206
|
+
const handleChange = (e) => {
|
|
2207
|
+
const file = e.target.files?.[0] || null;
|
|
2208
|
+
onSelect(file);
|
|
2209
|
+
// Reset input to allow selecting the same file again
|
|
2210
|
+
if (inputRef.current) {
|
|
2211
|
+
inputRef.current.value = '';
|
|
2212
|
+
}
|
|
2213
|
+
};
|
|
2214
|
+
const handleClear = (e) => {
|
|
2215
|
+
e.stopPropagation();
|
|
2216
|
+
onClear();
|
|
2217
|
+
};
|
|
2218
|
+
const handleKeyDown = (e) => {
|
|
2219
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
2220
|
+
e.preventDefault();
|
|
2221
|
+
handleClick();
|
|
2222
|
+
}
|
|
2223
|
+
};
|
|
2224
|
+
// Determine if preview is a string (image URL) or ReactNode
|
|
2225
|
+
const isImagePreview = typeof preview === 'string' && previewIsImage;
|
|
2226
|
+
const hasPreview = preview !== null && preview !== undefined;
|
|
2227
|
+
// Style parameters
|
|
2228
|
+
const styleParams = {
|
|
2229
|
+
width,
|
|
2230
|
+
dropzoneHeight,
|
|
2231
|
+
previewMaxHeight,
|
|
2232
|
+
previewMaxWidth,
|
|
2233
|
+
previewObjectFit,
|
|
2234
|
+
};
|
|
2235
|
+
return (jsxs("div", { className: FILE_PICKER_STYLES.root(styleParams), children: [label && (jsx(Text, { fontSize: 'sm', variant: 'label', children: label })), jsx("input", { ref: inputRef, type: 'file', accept: accept, className: FILE_PICKER_STYLES.hiddenInput, onChange: handleChange, disabled: disabled }), hasPreview ? (jsxs("div", { className: FILE_PICKER_STYLES.previewContainer, children: [isImagePreview ? (jsx("img", { src: preview, alt: previewAlt, className: FILE_PICKER_STYLES.preview(styleParams) })) : (preview), !disabled && ClearIconComponent && (jsx("div", { className: FILE_PICKER_STYLES.clearButton, children: jsx(IconButton, { icon: jsx(ClearIconComponent, {}), onClick: handleClear, ariaLabel: clearAriaLabel, variant: 'contained', size: 'small', textColor: 'surface' }) }))] })) : (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 && (jsx(Icon, { size: 'lg', color: 'text', children: jsx(IconComponent, {}) })), jsx(Text, { children: placeholder }), hint && (jsx(Text, { fontSize: 'xs', color: 'textSecondary', children: hint }))] })), error && (jsx(Text, { fontSize: 'sm', color: 'error', children: error }))] }));
|
|
2236
|
+
};
|
|
2237
|
+
FilePicker.displayName = 'FilePicker';
|
|
2238
|
+
|
|
2239
|
+
/**
|
|
2240
|
+
* Image picker component built on top of the generic FilePicker.
|
|
2241
|
+
* Pre-configured for image uploads with JPEG, PNG, and WebP support.
|
|
2242
|
+
*
|
|
2243
|
+
* @example
|
|
2244
|
+
* ```tsx
|
|
2245
|
+
* <ImagePicker
|
|
2246
|
+
* label="Profile Picture"
|
|
2247
|
+
* preview={imageUrl}
|
|
2248
|
+
* onSelect={handleImageSelect}
|
|
2249
|
+
* onClear={handleImageClear}
|
|
2250
|
+
* />
|
|
2251
|
+
* ```
|
|
2252
|
+
*/
|
|
2253
|
+
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, }) => {
|
|
2254
|
+
return (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: PlusIcon, clearIcon: TrashIcon, clearAriaLabel: clearAriaLabel, width: width, dropzoneHeight: dropzoneHeight, previewMaxHeight: previewMaxHeight, previewMaxWidth: previewMaxWidth, previewObjectFit: previewObjectFit }));
|
|
2255
|
+
};
|
|
2256
|
+
ImagePicker.displayName = 'ImagePicker';
|
|
2257
|
+
|
|
2110
2258
|
/**
|
|
2111
2259
|
* Box styles using createStyles from @aurora-ds/theme
|
|
2112
2260
|
*/
|
|
@@ -3555,5 +3703,5 @@ const defaultTheme = {
|
|
|
3555
3703
|
breakpoints: themeBreakpoints,
|
|
3556
3704
|
};
|
|
3557
3705
|
|
|
3558
|
-
export { Accordion, Alert, AlertProvider, Avatar, AvatarGroup, Box, Breadcrumb, BreadcrumbEllipsis, BreadcrumbLink, BreadcrumbPage, BreadcrumbSeparator, Button, ButtonToggle, ButtonToggleGroup, Card, DatePicker_default as DatePicker, DrawerItem, Form, Grid, Icon, IconButton, Input_default as Input, Menu, MenuGroup, MenuItem, Modal, Page, PageSection, Pagination, Select, Separator, Skeleton, Stack, Status, TabItem, Tabs, Text, TextArea_default as TextArea, defaultTheme, useAlert, useAnchorPosition, useClickOutside, useTransitionRender };
|
|
3706
|
+
export { Accordion, Alert, AlertProvider, Avatar, AvatarGroup, Box, Breadcrumb, BreadcrumbEllipsis, BreadcrumbLink, BreadcrumbPage, BreadcrumbSeparator, Button, ButtonToggle, ButtonToggleGroup, Card, DatePicker_default as DatePicker, DrawerItem, FilePicker, Form, Grid, Icon, IconButton, ImagePicker, Input_default as Input, Menu, MenuGroup, MenuItem, Modal, Page, PageSection, Pagination, Select, Separator, Skeleton, Stack, Status, TabItem, Tabs, Text, TextArea_default as TextArea, defaultTheme, useAlert, useAnchorPosition, useClickOutside, useTransitionRender };
|
|
3559
3707
|
//# sourceMappingURL=index.js.map
|