@synerise/ds-image 0.2.0 → 2.0.1
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/CHANGELOG.md +10 -0
- package/CLAUDE.md +4 -1
- package/README.md +2 -0
- package/dist/Gallery/Gallery.d.ts +1 -1
- package/dist/Gallery/Gallery.js +2 -1
- package/dist/Gallery/Gallery.types.d.ts +2 -0
- package/dist/Preview/ImagePreview.d.ts +1 -1
- package/dist/Preview/ImagePreview.js +3 -2
- package/dist/Preview/ImagePreview.types.d.ts +5 -0
- package/dist/shared/Image.shared.types.d.ts +5 -0
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,16 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [2.0.1](https://github.com/Synerise/synerise-design/compare/@synerise/ds-image@2.0.0...@synerise/ds-image@2.0.1) (2026-09-01)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
- **image:** keep the preview tooltips above a raised overlay ([9440cba](https://github.com/Synerise/synerise-design/commit/9440cba7d71bc9cf2d003aa179d69d67804e4e9b))
|
|
11
|
+
|
|
12
|
+
# [2.0.0](https://github.com/Synerise/synerise-design/compare/@synerise/ds-image@0.2.0...@synerise/ds-image@2.0.0) (2026-08-26)
|
|
13
|
+
|
|
14
|
+
**Note:** Version bump only for package @synerise/ds-image
|
|
15
|
+
|
|
6
16
|
# [0.2.0](https://github.com/Synerise/synerise-design/compare/@synerise/ds-image@0.1.5...@synerise/ds-image@0.2.0) (2026-08-25)
|
|
7
17
|
|
|
8
18
|
### Features
|
package/CLAUDE.md
CHANGED
|
@@ -124,7 +124,10 @@ tables.
|
|
|
124
124
|
top-right (`CloseWrapper`). The download control is a `ToolbarButton` rendered
|
|
125
125
|
as an anchor (`href`/`download`/`target="_blank"` forwarded to `<a>` by
|
|
126
126
|
`ds-button`) so it downloads same-origin images and opens cross-origin ones in
|
|
127
|
-
a new tab; it shows whenever a valid image is loaded (independent of zoom)
|
|
127
|
+
a new tab; it shows whenever a valid image is loaded (independent of zoom) and
|
|
128
|
+
the image is downloadable — per-image `ImageSource.downloadable` → preview
|
|
129
|
+
`downloadable` (default `true`). Hiding it leaves the rest of the zoom group
|
|
130
|
+
intact, and the whole group drops out only when nothing in it renders.
|
|
128
131
|
- **Error/Empty fallback** — broken `src` → `fallback` (per-image `ImageSource.fallback`
|
|
129
132
|
→ component `fallback` → default `ImageM` placeholder). No `src` on a Thumbnail →
|
|
130
133
|
the Empty placeholder.
|
package/README.md
CHANGED
|
@@ -87,6 +87,7 @@ enclosing `Gallery` before the default listed above.
|
|
|
87
87
|
| onDelete | Called with the index of the thumbnail whose delete fired. | (index: number) => void | --- |
|
|
88
88
|
| openZoom | Whether clicking a thumbnail opens the preview. | boolean | `true` |
|
|
89
89
|
| zoomable / zoomStep / maxZoom / initialZoom | Forwarded to the preview it owns. | see ImagePreview | see ImagePreview |
|
|
90
|
+
| downloadable | Forwarded to the preview — render the download control. | boolean | `true` |
|
|
90
91
|
| getContainer / zIndex | Forwarded to the preview it owns. | see ImagePreview | see ImagePreview |
|
|
91
92
|
| texts | Override tooltips / accessible labels for thumbnails and the preview. | Partial<ImageTexts> | DS translations |
|
|
92
93
|
| className | Class applied to the gallery container. | string | --- |
|
|
@@ -106,6 +107,7 @@ enclosing `Gallery` before the default listed above.
|
|
|
106
107
|
| initialZoom | Where zoom starts. | 'fit' / 'real-size' | `'fit'` |
|
|
107
108
|
| closable | Whether to render the close button and allow Escape to close. | boolean | `true` |
|
|
108
109
|
| maskClosable | Whether clicking the dimmed backdrop closes the viewer. | boolean | `true` |
|
|
110
|
+
| downloadable | Whether to render the download control (per-image override via `ImageSource.downloadable`). | boolean | `true` |
|
|
109
111
|
| zIndex | z-index of the overlay. Omitted, it stacks one step above the enclosing modal / drawer. Set it to opt out of the DS stack. | number | `zindex-modal` |
|
|
110
112
|
| fallback | Rendered when an image fails to load (per-image override via `ImageSource.fallback`). | React.ReactNode | broken-image box |
|
|
111
113
|
| getContainer | Portal target. | () => HTMLElement | `document.body` |
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { GalleryProps } from './Gallery.types';
|
|
2
|
-
declare const Gallery: ({ images, aspectRatio, size, height, background, objectFit, loading, fallback, deletable, onDelete, openZoom, zoomable, zoomStep, maxZoom, initialZoom, getContainer, zIndex, texts, className, }: GalleryProps) => JSX.Element;
|
|
2
|
+
declare const Gallery: ({ images, aspectRatio, size, height, background, objectFit, loading, fallback, deletable, onDelete, openZoom, zoomable, zoomStep, maxZoom, initialZoom, downloadable, getContainer, zIndex, texts, className, }: GalleryProps) => JSX.Element;
|
|
3
3
|
export default Gallery;
|
package/dist/Gallery/Gallery.js
CHANGED
|
@@ -20,6 +20,7 @@ const Gallery = ({
|
|
|
20
20
|
zoomStep,
|
|
21
21
|
maxZoom,
|
|
22
22
|
initialZoom,
|
|
23
|
+
downloadable,
|
|
23
24
|
getContainer,
|
|
24
25
|
zIndex,
|
|
25
26
|
texts,
|
|
@@ -38,7 +39,7 @@ const Gallery = ({
|
|
|
38
39
|
}), [aspectRatio, size, height, background, objectFit, loading, fallback, texts]);
|
|
39
40
|
return /* @__PURE__ */ jsxs(ImageGalleryContext.Provider, { value: contextValue, children: [
|
|
40
41
|
/* @__PURE__ */ jsx(Container, { className, "data-testid": "image-gallery", children: images.map((image, imageIndex) => /* @__PURE__ */ jsx(Thumbnail, { src: image.src, alt: image.alt, fallback: image.fallback, deletable, onDelete: onDelete ? () => onDelete(imageIndex) : void 0, openZoom, onClick: openZoom ? () => setPreviewIndex(imageIndex) : void 0 }, `${image.src}-${imageIndex}`)) }),
|
|
41
|
-
openZoom && /* @__PURE__ */ jsx(ImagePreview, { open: previewIndex !== null, images, index: previewIndex ?? 0, onIndexChange: setPreviewIndex, onClose: () => setPreviewIndex(null), zoomable, zoomStep, maxZoom, initialZoom, fallback, getContainer, zIndex, texts })
|
|
42
|
+
openZoom && /* @__PURE__ */ jsx(ImagePreview, { open: previewIndex !== null, images, index: previewIndex ?? 0, onIndexChange: setPreviewIndex, onClose: () => setPreviewIndex(null), zoomable, zoomStep, maxZoom, initialZoom, downloadable, fallback, getContainer, zIndex, texts })
|
|
42
43
|
] });
|
|
43
44
|
};
|
|
44
45
|
export {
|
|
@@ -31,6 +31,8 @@ export type GalleryProps = {
|
|
|
31
31
|
maxZoom?: number;
|
|
32
32
|
/** Preview pass-through — where zoom starts. */
|
|
33
33
|
initialZoom?: InitialZoom;
|
|
34
|
+
/** Preview pass-through — render the download control. */
|
|
35
|
+
downloadable?: boolean;
|
|
34
36
|
/** Preview pass-through — portal target. */
|
|
35
37
|
getContainer?: () => HTMLElement;
|
|
36
38
|
/** Preview pass-through — z-index of the preview overlay. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
2
|
import { ImagePreviewProps } from './ImagePreview.types';
|
|
3
|
-
declare const ImagePreview: ({ open, images, index, onIndexChange, onClose, zoomable, zoomStep, maxZoom, initialZoom, closable, maskClosable, fallback, getContainer, destroyOnClose, onZoom, texts: textsProp, zIndex, }: ImagePreviewProps) => React.ReactPortal | null;
|
|
3
|
+
declare const ImagePreview: ({ open, images, index, onIndexChange, onClose, zoomable, zoomStep, maxZoom, initialZoom, closable, maskClosable, downloadable, fallback, getContainer, destroyOnClose, onZoom, texts: textsProp, zIndex, }: ImagePreviewProps) => React.ReactPortal | null;
|
|
4
4
|
export default ImagePreview;
|
|
@@ -36,6 +36,7 @@ const ImagePreview = ({
|
|
|
36
36
|
initialZoom = "fit",
|
|
37
37
|
closable = true,
|
|
38
38
|
maskClosable = true,
|
|
39
|
+
downloadable = true,
|
|
39
40
|
fallback,
|
|
40
41
|
getContainer,
|
|
41
42
|
destroyOnClose = false,
|
|
@@ -178,10 +179,10 @@ const ImagePreview = ({
|
|
|
178
179
|
};
|
|
179
180
|
const zoomPercent = naturalScaleFactor > 0 ? Math.round(scale / naturalScaleFactor * 100) : 100;
|
|
180
181
|
const hasError = status === "error" || !currentImage;
|
|
181
|
-
const showDownload = !hasError && Boolean(currentSrc);
|
|
182
|
+
const showDownload = (currentImage?.downloadable ?? downloadable) && !hasError && Boolean(currentSrc);
|
|
182
183
|
const image = /* @__PURE__ */ jsx(Image, { ref: imgRef, src: currentSrc, alt: currentImage?.alt ?? "", onLoad: handleImageLoad, onError: handleError, onClick: stopPropagation, draggable: false, "data-testid": "image-preview-image" }, index);
|
|
183
184
|
const content = hasError ? /* @__PURE__ */ jsx(Fallback, { onClick: stopPropagation, "data-testid": "image-preview-fallback", children: currentImage?.fallback ?? fallback ?? /* @__PURE__ */ jsx(FallbackBox, { children: /* @__PURE__ */ jsx(Icon, { component: /* @__PURE__ */ jsx(ImageM, {}) }) }) }) : image;
|
|
184
|
-
return createPortal(/* @__PURE__ */ jsxs(Overlay, { ref: overlayRef, role: "dialog", "aria-modal": true, "aria-label": currentImage?.alt, tabIndex: -1, $hidden: !open, $zIndex: resolvedZIndex, onMouseDown: handleOverlayPointerDown, onClick: handleMaskClick, "data-testid": "image-preview", children: [
|
|
185
|
+
return createPortal(/* @__PURE__ */ jsxs(Overlay, { ref: overlayRef, role: "dialog", "aria-modal": true, "aria-label": currentImage?.alt, tabIndex: -1, $hidden: !open, $zIndex: resolvedZIndex, "data-popup-container": true, onMouseDown: handleOverlayPointerDown, onClick: handleMaskClick, "data-testid": "image-preview", children: [
|
|
185
186
|
/* @__PURE__ */ jsx(ImageWrapper, { ref: workingAreaRef, children: zoomable && !hasError ? /* @__PURE__ */ jsx(TransformWrapper, { ref: transformRef, minScale: FIT_SCALE, maxScale, initialScale: FIT_SCALE, centerOnInit: true, doubleClick: {
|
|
186
187
|
mode: "reset"
|
|
187
188
|
}, wheel: {
|
|
@@ -26,6 +26,11 @@ export type ImagePreviewProps = {
|
|
|
26
26
|
closable?: boolean;
|
|
27
27
|
/** Whether clicking the dimmed backdrop closes the viewer. Defaults to true. */
|
|
28
28
|
maskClosable?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Whether to render the download control. Defaults to true. Override it for a
|
|
31
|
+
* single image with `ImageSource.downloadable`.
|
|
32
|
+
*/
|
|
33
|
+
downloadable?: boolean;
|
|
29
34
|
/** Fallback rendered when an image fails to load (per-image override via `ImageSource.fallback`). */
|
|
30
35
|
fallback?: ReactNode;
|
|
31
36
|
/** Portal target. Defaults to `document.body`. */
|
|
@@ -7,6 +7,11 @@ export type ImageSource = {
|
|
|
7
7
|
alt: string;
|
|
8
8
|
/** Per-image override for the broken-image fallback. */
|
|
9
9
|
fallback?: ReactNode;
|
|
10
|
+
/**
|
|
11
|
+
* Per-image override for the preview's download control. Takes precedence
|
|
12
|
+
* over the preview-level `downloadable` prop.
|
|
13
|
+
*/
|
|
14
|
+
downloadable?: boolean;
|
|
10
15
|
};
|
|
11
16
|
/**
|
|
12
17
|
* Aspect ratio applied to a thumbnail. `source` keeps the image's intrinsic
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@synerise/ds-image",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "Image UI Component for the Synerise Design System",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"repository": "Synerise/synerise-design",
|
|
@@ -42,10 +42,10 @@
|
|
|
42
42
|
],
|
|
43
43
|
"types": "dist/index.d.ts",
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@synerise/ds-icon": "^
|
|
46
|
-
"@synerise/ds-toolbar": "^
|
|
47
|
-
"@synerise/ds-tooltip": "^
|
|
48
|
-
"@synerise/ds-utils": "^
|
|
45
|
+
"@synerise/ds-icon": "^2.0.0",
|
|
46
|
+
"@synerise/ds-toolbar": "^2.0.0",
|
|
47
|
+
"@synerise/ds-tooltip": "^2.0.0",
|
|
48
|
+
"@synerise/ds-utils": "^2.0.0",
|
|
49
49
|
"react-zoom-pan-pinch": "^3.6.1"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
@@ -55,5 +55,5 @@
|
|
|
55
55
|
"styled-components": "^5.3.3",
|
|
56
56
|
"vitest": "4"
|
|
57
57
|
},
|
|
58
|
-
"gitHead": "
|
|
58
|
+
"gitHead": "a57eb7eaf98318b364468368d1aa4fd9fa6a6dc8"
|
|
59
59
|
}
|