@trackunit/react-compound-components 1.0.16 → 1.0.18
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/index.cjs.js +11 -14
- package/index.esm.js +11 -14
- package/package.json +5 -5
- package/src/ImageCollection/ImageCollection.stories.d.ts +34 -34
package/index.cjs.js
CHANGED
|
@@ -108,15 +108,15 @@ const ConfirmationDialogContextProvider = ({ children }) => {
|
|
|
108
108
|
...confirmationDialogProps,
|
|
109
109
|
isOpen,
|
|
110
110
|
handleDismiss: () => {
|
|
111
|
-
resolveAction
|
|
111
|
+
resolveAction?.("CLOSE");
|
|
112
112
|
closeModal();
|
|
113
113
|
},
|
|
114
114
|
handlePrimaryActionClick: () => {
|
|
115
|
-
resolveAction
|
|
115
|
+
resolveAction?.("PRIMARY");
|
|
116
116
|
closeModal();
|
|
117
117
|
},
|
|
118
118
|
handleSecondaryActionClick: () => {
|
|
119
|
-
resolveAction
|
|
119
|
+
resolveAction?.("SECONDARY");
|
|
120
120
|
closeModal();
|
|
121
121
|
},
|
|
122
122
|
}), [confirmationDialogProps, isOpen, resolveAction, closeModal]);
|
|
@@ -188,14 +188,13 @@ const titleStyle = "absolute top-3 left-1/2 transform -translate-x-1/2 text-whit
|
|
|
188
188
|
* Reduces bandwidth usage by lazy loading thumbnails and loading smaller versions of images depending on screen size.
|
|
189
189
|
*/
|
|
190
190
|
const ImageCollection = (props) => {
|
|
191
|
-
var _a, _b;
|
|
192
191
|
const { imagesData, actions, emptyPlaceholderActionLabel, additionalItemClassName, uploading } = props;
|
|
193
|
-
const [openImageId, setOpenImageId] = React.useState(
|
|
192
|
+
const [openImageId, setOpenImageId] = React.useState(imagesData[0]?.id);
|
|
194
193
|
const [isDeleting, setIsDeleting] = React.useState(false);
|
|
195
194
|
const { isLg } = reactComponents.useViewportBreakpoints();
|
|
196
195
|
const fileInputRef = React.useRef(null);
|
|
197
196
|
const imageGalleryRef = React.useRef(null);
|
|
198
|
-
const uploadButton = React.useMemo(() =>
|
|
197
|
+
const uploadButton = React.useMemo(() => actions?.upload ? (jsxRuntime.jsx("div", { className: "flex justify-end", children: jsxRuntime.jsx(reactComponents.Button, { loading: uploading, onClick: () => fileInputRef.current?.click(), children: actions.upload.label }) })) : null, [actions?.upload, uploading]);
|
|
199
198
|
const items = React.useMemo(() => imagesData.map(image => ({
|
|
200
199
|
id: image.id,
|
|
201
200
|
original: createOriginalUrl(image.id),
|
|
@@ -205,14 +204,12 @@ const ImageCollection = (props) => {
|
|
|
205
204
|
timestamp: dateAndTimeUtils.formatDateUtil(new Date(image.timestamp), { dateFormat: "medium", timeFormat: "medium" }),
|
|
206
205
|
})), [imagesData]);
|
|
207
206
|
React.useEffect(() => {
|
|
208
|
-
var _a;
|
|
209
207
|
if ((!openImageId || !imagesData.map(x => x.id).includes(openImageId)) && imagesData.length > 0) {
|
|
210
|
-
setOpenImageId(
|
|
208
|
+
setOpenImageId(imagesData[0]?.id);
|
|
211
209
|
}
|
|
212
210
|
}, [imagesData, openImageId]);
|
|
213
211
|
const onRemove = React.useCallback(async () => {
|
|
214
|
-
|
|
215
|
-
if (!(((_a = actions === null || actions === void 0 ? void 0 : actions.remove) === null || _a === void 0 ? void 0 : _a.onRemove) && openImageId)) {
|
|
212
|
+
if (!(actions?.remove?.onRemove && openImageId)) {
|
|
216
213
|
return;
|
|
217
214
|
}
|
|
218
215
|
try {
|
|
@@ -238,8 +235,8 @@ const ImageCollection = (props) => {
|
|
|
238
235
|
finally {
|
|
239
236
|
setIsDeleting(false);
|
|
240
237
|
}
|
|
241
|
-
}, [actions
|
|
242
|
-
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [imagesData.length > 0 ? (jsxRuntime.jsxs("div", { className: "flex h-[100vh] max-h-[100vh] flex-col", "data-testid": "image-collection", children: [jsxRuntime.jsx(ImageGallery, { additionalClass: cvaGallery(), items: items, onBeforeSlide: index =>
|
|
238
|
+
}, [actions?.remove, imagesData, openImageId]);
|
|
239
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [imagesData.length > 0 ? (jsxRuntime.jsxs("div", { className: "flex h-[100vh] max-h-[100vh] flex-col", "data-testid": "image-collection", children: [jsxRuntime.jsx(ImageGallery, { additionalClass: cvaGallery(), items: items, onBeforeSlide: index => setOpenImageId(items[index]?.id),
|
|
243
240
|
// Library typing is wrong, this is fired when a gallery image is clicked (library typing says div)
|
|
244
241
|
onClick: e => window.open(e.target.src, "_blank"), ref: imageGalleryRef, renderItem: ({ original, srcSet,
|
|
245
242
|
// Typing of the library is not flexible enough to add id, which is only used for the unit tests
|
|
@@ -253,10 +250,10 @@ const ImageCollection = (props) => {
|
|
|
253
250
|
// @ts-ignore
|
|
254
251
|
id, }) => jsxRuntime.jsx("img", { alt: "thumbnail", "data-testid": `thumbnail-${id}`, loading: "lazy", src: thumbnail }), showFullscreenButton: false, showPlayButton: false, showThumbnails: isLg,
|
|
255
252
|
// reduce sliding around during deletion
|
|
256
|
-
slideDuration: isDeleting ? 0 : 200, ...props }), uploadButton,
|
|
253
|
+
slideDuration: isDeleting ? 0 : 200, ...props }), uploadButton, actions?.remove ? (jsxRuntime.jsx(reactComponents.Button, { className: "absolute right-2 top-2", loading: isDeleting, onClick: onRemove, prefix: jsxRuntime.jsx(reactComponents.Icon, { name: "Trash", size: "small" }), variant: "secondary-danger", children: actions.remove.label })) : null] })) : actions?.upload?.onUpload ? (uploading ? (jsxRuntime.jsx(reactComponents.Spinner, {})) : (jsxRuntime.jsx(reactFormComponents.DropZone, { accept: ACCEPT_FOR_IMAGES, className: "h-screen", dataTestId: "site-images-dropzone", filesSelected: actions.upload.onUpload, label: emptyPlaceholderActionLabel, multiple: true }))) : null, jsxRuntime.jsx("input", {
|
|
257
254
|
// Users can still select other files on mobile devices
|
|
258
255
|
accept: ACCEPT_FOR_IMAGES, "data-testid": "site-images-input-files", hidden: true, multiple: true, onChange: async (e) => {
|
|
259
|
-
if (!(e.target.files &&
|
|
256
|
+
if (!(e.target.files && actions?.upload)) {
|
|
260
257
|
return;
|
|
261
258
|
}
|
|
262
259
|
await actions.upload.onUpload(e.target.files);
|
package/index.esm.js
CHANGED
|
@@ -88,15 +88,15 @@ const ConfirmationDialogContextProvider = ({ children }) => {
|
|
|
88
88
|
...confirmationDialogProps,
|
|
89
89
|
isOpen,
|
|
90
90
|
handleDismiss: () => {
|
|
91
|
-
resolveAction
|
|
91
|
+
resolveAction?.("CLOSE");
|
|
92
92
|
closeModal();
|
|
93
93
|
},
|
|
94
94
|
handlePrimaryActionClick: () => {
|
|
95
|
-
resolveAction
|
|
95
|
+
resolveAction?.("PRIMARY");
|
|
96
96
|
closeModal();
|
|
97
97
|
},
|
|
98
98
|
handleSecondaryActionClick: () => {
|
|
99
|
-
resolveAction
|
|
99
|
+
resolveAction?.("SECONDARY");
|
|
100
100
|
closeModal();
|
|
101
101
|
},
|
|
102
102
|
}), [confirmationDialogProps, isOpen, resolveAction, closeModal]);
|
|
@@ -168,14 +168,13 @@ const titleStyle = "absolute top-3 left-1/2 transform -translate-x-1/2 text-whit
|
|
|
168
168
|
* Reduces bandwidth usage by lazy loading thumbnails and loading smaller versions of images depending on screen size.
|
|
169
169
|
*/
|
|
170
170
|
const ImageCollection = (props) => {
|
|
171
|
-
var _a, _b;
|
|
172
171
|
const { imagesData, actions, emptyPlaceholderActionLabel, additionalItemClassName, uploading } = props;
|
|
173
|
-
const [openImageId, setOpenImageId] = useState(
|
|
172
|
+
const [openImageId, setOpenImageId] = useState(imagesData[0]?.id);
|
|
174
173
|
const [isDeleting, setIsDeleting] = useState(false);
|
|
175
174
|
const { isLg } = useViewportBreakpoints();
|
|
176
175
|
const fileInputRef = useRef(null);
|
|
177
176
|
const imageGalleryRef = useRef(null);
|
|
178
|
-
const uploadButton = useMemo(() =>
|
|
177
|
+
const uploadButton = useMemo(() => actions?.upload ? (jsx("div", { className: "flex justify-end", children: jsx(Button, { loading: uploading, onClick: () => fileInputRef.current?.click(), children: actions.upload.label }) })) : null, [actions?.upload, uploading]);
|
|
179
178
|
const items = useMemo(() => imagesData.map(image => ({
|
|
180
179
|
id: image.id,
|
|
181
180
|
original: createOriginalUrl(image.id),
|
|
@@ -185,14 +184,12 @@ const ImageCollection = (props) => {
|
|
|
185
184
|
timestamp: formatDateUtil(new Date(image.timestamp), { dateFormat: "medium", timeFormat: "medium" }),
|
|
186
185
|
})), [imagesData]);
|
|
187
186
|
useEffect(() => {
|
|
188
|
-
var _a;
|
|
189
187
|
if ((!openImageId || !imagesData.map(x => x.id).includes(openImageId)) && imagesData.length > 0) {
|
|
190
|
-
setOpenImageId(
|
|
188
|
+
setOpenImageId(imagesData[0]?.id);
|
|
191
189
|
}
|
|
192
190
|
}, [imagesData, openImageId]);
|
|
193
191
|
const onRemove = useCallback(async () => {
|
|
194
|
-
|
|
195
|
-
if (!(((_a = actions === null || actions === void 0 ? void 0 : actions.remove) === null || _a === void 0 ? void 0 : _a.onRemove) && openImageId)) {
|
|
192
|
+
if (!(actions?.remove?.onRemove && openImageId)) {
|
|
196
193
|
return;
|
|
197
194
|
}
|
|
198
195
|
try {
|
|
@@ -218,8 +215,8 @@ const ImageCollection = (props) => {
|
|
|
218
215
|
finally {
|
|
219
216
|
setIsDeleting(false);
|
|
220
217
|
}
|
|
221
|
-
}, [actions
|
|
222
|
-
return (jsxs(Fragment, { children: [imagesData.length > 0 ? (jsxs("div", { className: "flex h-[100vh] max-h-[100vh] flex-col", "data-testid": "image-collection", children: [jsx(ImageGallery, { additionalClass: cvaGallery(), items: items, onBeforeSlide: index =>
|
|
218
|
+
}, [actions?.remove, imagesData, openImageId]);
|
|
219
|
+
return (jsxs(Fragment, { children: [imagesData.length > 0 ? (jsxs("div", { className: "flex h-[100vh] max-h-[100vh] flex-col", "data-testid": "image-collection", children: [jsx(ImageGallery, { additionalClass: cvaGallery(), items: items, onBeforeSlide: index => setOpenImageId(items[index]?.id),
|
|
223
220
|
// Library typing is wrong, this is fired when a gallery image is clicked (library typing says div)
|
|
224
221
|
onClick: e => window.open(e.target.src, "_blank"), ref: imageGalleryRef, renderItem: ({ original, srcSet,
|
|
225
222
|
// Typing of the library is not flexible enough to add id, which is only used for the unit tests
|
|
@@ -233,10 +230,10 @@ const ImageCollection = (props) => {
|
|
|
233
230
|
// @ts-ignore
|
|
234
231
|
id, }) => jsx("img", { alt: "thumbnail", "data-testid": `thumbnail-${id}`, loading: "lazy", src: thumbnail }), showFullscreenButton: false, showPlayButton: false, showThumbnails: isLg,
|
|
235
232
|
// reduce sliding around during deletion
|
|
236
|
-
slideDuration: isDeleting ? 0 : 200, ...props }), uploadButton,
|
|
233
|
+
slideDuration: isDeleting ? 0 : 200, ...props }), uploadButton, actions?.remove ? (jsx(Button, { className: "absolute right-2 top-2", loading: isDeleting, onClick: onRemove, prefix: jsx(Icon, { name: "Trash", size: "small" }), variant: "secondary-danger", children: actions.remove.label })) : null] })) : actions?.upload?.onUpload ? (uploading ? (jsx(Spinner, {})) : (jsx(DropZone, { accept: ACCEPT_FOR_IMAGES, className: "h-screen", dataTestId: "site-images-dropzone", filesSelected: actions.upload.onUpload, label: emptyPlaceholderActionLabel, multiple: true }))) : null, jsx("input", {
|
|
237
234
|
// Users can still select other files on mobile devices
|
|
238
235
|
accept: ACCEPT_FOR_IMAGES, "data-testid": "site-images-input-files", hidden: true, multiple: true, onChange: async (e) => {
|
|
239
|
-
if (!(e.target.files &&
|
|
236
|
+
if (!(e.target.files && actions?.upload)) {
|
|
240
237
|
return;
|
|
241
238
|
}
|
|
242
239
|
await actions.upload.onUpload(e.target.files);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trackunit/react-compound-components",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.18",
|
|
4
4
|
"repository": "https://github.com/Trackunit/manager",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
6
|
"dependencies": {
|
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
"react-image-gallery": "1.3.0",
|
|
10
10
|
"@trackunit/react-core-contexts-api": "^1.0.5",
|
|
11
11
|
"@trackunit/react-core-hooks": "^1.0.5",
|
|
12
|
-
"@trackunit/react-components": "^1.0
|
|
13
|
-
"@trackunit/react-modal": "^1.0.
|
|
12
|
+
"@trackunit/react-components": "^1.1.0",
|
|
13
|
+
"@trackunit/react-modal": "^1.0.17",
|
|
14
14
|
"@trackunit/css-class-variance-utilities": "^1.0.1",
|
|
15
15
|
"@trackunit/date-and-time-utils": "^1.0.1",
|
|
16
|
-
"@trackunit/react-form-components": "^1.0.
|
|
17
|
-
"@trackunit/i18n-library-translation": "^1.0.
|
|
16
|
+
"@trackunit/react-form-components": "^1.0.17",
|
|
17
|
+
"@trackunit/i18n-library-translation": "^1.0.7"
|
|
18
18
|
},
|
|
19
19
|
"engines": {
|
|
20
20
|
"node": ">=20.x",
|
|
@@ -13,7 +13,7 @@ export declare const Default: {
|
|
|
13
13
|
original: string;
|
|
14
14
|
thumbnail: string;
|
|
15
15
|
}[];
|
|
16
|
-
onClick?:
|
|
16
|
+
onClick?: React.MouseEventHandler<HTMLDivElement> | undefined;
|
|
17
17
|
flickThreshold?: number | undefined;
|
|
18
18
|
showNav?: boolean | undefined;
|
|
19
19
|
autoPlay?: boolean | undefined;
|
|
@@ -43,22 +43,22 @@ export declare const Default: {
|
|
|
43
43
|
onScreenChange?: ((fullScreen: boolean) => void) | undefined;
|
|
44
44
|
onPause?: ((currentIndex: number) => void) | undefined;
|
|
45
45
|
onPlay?: ((currentIndex: number) => void) | undefined;
|
|
46
|
-
onImageLoad?:
|
|
47
|
-
onImageError?:
|
|
48
|
-
onTouchMove?:
|
|
49
|
-
onTouchEnd?:
|
|
50
|
-
onTouchStart?:
|
|
51
|
-
onMouseOver?:
|
|
52
|
-
onMouseLeave?:
|
|
53
|
-
onThumbnailError?:
|
|
54
|
-
onThumbnailClick?: ((event:
|
|
55
|
-
renderCustomControls?: (() =>
|
|
56
|
-
renderLeftNav?: ((onClick:
|
|
57
|
-
renderRightNav?: ((onClick:
|
|
58
|
-
renderPlayPauseButton?: ((onClick:
|
|
59
|
-
renderFullscreenButton?: ((onClick:
|
|
60
|
-
renderItem?: ((item: import("react-image-gallery").ReactImageGalleryItem) =>
|
|
61
|
-
renderThumbInner?: ((item: import("react-image-gallery").ReactImageGalleryItem) =>
|
|
46
|
+
onImageLoad?: React.ReactEventHandler<HTMLImageElement> | undefined;
|
|
47
|
+
onImageError?: React.ReactEventHandler<HTMLImageElement> | undefined;
|
|
48
|
+
onTouchMove?: React.TouchEventHandler<HTMLDivElement> | undefined;
|
|
49
|
+
onTouchEnd?: React.TouchEventHandler<HTMLDivElement> | undefined;
|
|
50
|
+
onTouchStart?: React.TouchEventHandler<HTMLDivElement> | undefined;
|
|
51
|
+
onMouseOver?: React.MouseEventHandler<HTMLDivElement> | undefined;
|
|
52
|
+
onMouseLeave?: React.MouseEventHandler<HTMLDivElement> | undefined;
|
|
53
|
+
onThumbnailError?: React.ReactEventHandler<HTMLImageElement> | undefined;
|
|
54
|
+
onThumbnailClick?: ((event: React.MouseEvent<HTMLAnchorElement>, index: number) => void) | undefined;
|
|
55
|
+
renderCustomControls?: (() => React.ReactNode) | undefined;
|
|
56
|
+
renderLeftNav?: ((onClick: React.MouseEventHandler<HTMLElement>, disabled: boolean) => React.ReactNode) | undefined;
|
|
57
|
+
renderRightNav?: ((onClick: React.MouseEventHandler<HTMLElement>, disabled: boolean) => React.ReactNode) | undefined;
|
|
58
|
+
renderPlayPauseButton?: ((onClick: React.MouseEventHandler<HTMLElement>, isPlaying: boolean) => React.ReactNode) | undefined;
|
|
59
|
+
renderFullscreenButton?: ((onClick: React.MouseEventHandler<HTMLElement>, isFullscreen: boolean) => React.ReactNode) | undefined;
|
|
60
|
+
renderItem?: ((item: import("react-image-gallery").ReactImageGalleryItem) => React.ReactNode) | undefined;
|
|
61
|
+
renderThumbInner?: ((item: import("react-image-gallery").ReactImageGalleryItem) => React.ReactNode) | undefined;
|
|
62
62
|
stopPropagation?: boolean | undefined;
|
|
63
63
|
additionalClass?: string | undefined;
|
|
64
64
|
useTranslate3D?: boolean | undefined;
|
|
@@ -88,7 +88,7 @@ export declare const EmptyState: {
|
|
|
88
88
|
render: (props: ComponentProps<typeof ImageCollection>) => import("react/jsx-runtime").JSX.Element;
|
|
89
89
|
args: {
|
|
90
90
|
imageIds: never[];
|
|
91
|
-
onClick?:
|
|
91
|
+
onClick?: React.MouseEventHandler<HTMLDivElement> | undefined;
|
|
92
92
|
flickThreshold?: number | undefined;
|
|
93
93
|
showNav?: boolean | undefined;
|
|
94
94
|
autoPlay?: boolean | undefined;
|
|
@@ -118,22 +118,22 @@ export declare const EmptyState: {
|
|
|
118
118
|
onScreenChange?: ((fullScreen: boolean) => void) | undefined;
|
|
119
119
|
onPause?: ((currentIndex: number) => void) | undefined;
|
|
120
120
|
onPlay?: ((currentIndex: number) => void) | undefined;
|
|
121
|
-
onImageLoad?:
|
|
122
|
-
onImageError?:
|
|
123
|
-
onTouchMove?:
|
|
124
|
-
onTouchEnd?:
|
|
125
|
-
onTouchStart?:
|
|
126
|
-
onMouseOver?:
|
|
127
|
-
onMouseLeave?:
|
|
128
|
-
onThumbnailError?:
|
|
129
|
-
onThumbnailClick?: ((event:
|
|
130
|
-
renderCustomControls?: (() =>
|
|
131
|
-
renderLeftNav?: ((onClick:
|
|
132
|
-
renderRightNav?: ((onClick:
|
|
133
|
-
renderPlayPauseButton?: ((onClick:
|
|
134
|
-
renderFullscreenButton?: ((onClick:
|
|
135
|
-
renderItem?: ((item: import("react-image-gallery").ReactImageGalleryItem) =>
|
|
136
|
-
renderThumbInner?: ((item: import("react-image-gallery").ReactImageGalleryItem) =>
|
|
121
|
+
onImageLoad?: React.ReactEventHandler<HTMLImageElement> | undefined;
|
|
122
|
+
onImageError?: React.ReactEventHandler<HTMLImageElement> | undefined;
|
|
123
|
+
onTouchMove?: React.TouchEventHandler<HTMLDivElement> | undefined;
|
|
124
|
+
onTouchEnd?: React.TouchEventHandler<HTMLDivElement> | undefined;
|
|
125
|
+
onTouchStart?: React.TouchEventHandler<HTMLDivElement> | undefined;
|
|
126
|
+
onMouseOver?: React.MouseEventHandler<HTMLDivElement> | undefined;
|
|
127
|
+
onMouseLeave?: React.MouseEventHandler<HTMLDivElement> | undefined;
|
|
128
|
+
onThumbnailError?: React.ReactEventHandler<HTMLImageElement> | undefined;
|
|
129
|
+
onThumbnailClick?: ((event: React.MouseEvent<HTMLAnchorElement>, index: number) => void) | undefined;
|
|
130
|
+
renderCustomControls?: (() => React.ReactNode) | undefined;
|
|
131
|
+
renderLeftNav?: ((onClick: React.MouseEventHandler<HTMLElement>, disabled: boolean) => React.ReactNode) | undefined;
|
|
132
|
+
renderRightNav?: ((onClick: React.MouseEventHandler<HTMLElement>, disabled: boolean) => React.ReactNode) | undefined;
|
|
133
|
+
renderPlayPauseButton?: ((onClick: React.MouseEventHandler<HTMLElement>, isPlaying: boolean) => React.ReactNode) | undefined;
|
|
134
|
+
renderFullscreenButton?: ((onClick: React.MouseEventHandler<HTMLElement>, isFullscreen: boolean) => React.ReactNode) | undefined;
|
|
135
|
+
renderItem?: ((item: import("react-image-gallery").ReactImageGalleryItem) => React.ReactNode) | undefined;
|
|
136
|
+
renderThumbInner?: ((item: import("react-image-gallery").ReactImageGalleryItem) => React.ReactNode) | undefined;
|
|
137
137
|
stopPropagation?: boolean | undefined;
|
|
138
138
|
additionalClass?: string | undefined;
|
|
139
139
|
useTranslate3D?: boolean | undefined;
|