@trackunit/react-components 0.2.0 → 0.2.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/index.cjs.js
CHANGED
|
@@ -16,9 +16,10 @@ var isEqual = require('lodash/isEqual');
|
|
|
16
16
|
var reactUse = require('react-use');
|
|
17
17
|
var reactRouter = require('@tanstack/react-router');
|
|
18
18
|
var reactSwipeable = require('react-swipeable');
|
|
19
|
+
var ImageGallery = require('react-image-gallery');
|
|
20
|
+
var tailwindMerge = require('tailwind-merge');
|
|
19
21
|
var react = require('@floating-ui/react');
|
|
20
22
|
var omit = require('lodash/omit');
|
|
21
|
-
var tailwindMerge = require('tailwind-merge');
|
|
22
23
|
var reactHelmetAsync = require('react-helmet-async');
|
|
23
24
|
var reactTabs = require('@radix-ui/react-tabs');
|
|
24
25
|
var dateFns = require('date-fns');
|
|
@@ -3598,6 +3599,124 @@ const ExternalLink = ({ rel = "noreferrer", target = "_blank", href, className,
|
|
|
3598
3599
|
return (jsxRuntime.jsx("a", { className: cvaExternalLink({ className }), "data-testid": dataTestId, href: href, onClick: onClick, rel: rel, target: target, title: title, children: children }));
|
|
3599
3600
|
};
|
|
3600
3601
|
|
|
3602
|
+
const IMAGE_ENDPOINT = "https://images.iris.trackunit.com";
|
|
3603
|
+
/**
|
|
3604
|
+
* Generates an url for the original sized image from the image id
|
|
3605
|
+
*/
|
|
3606
|
+
const createOriginalUrl = (id) => `${IMAGE_ENDPOINT}/${btoa(JSON.stringify({
|
|
3607
|
+
key: id,
|
|
3608
|
+
}))}`;
|
|
3609
|
+
const createResizedUrl = (id, width, height) => {
|
|
3610
|
+
const request = {
|
|
3611
|
+
key: id,
|
|
3612
|
+
edits: {
|
|
3613
|
+
resize: {
|
|
3614
|
+
width,
|
|
3615
|
+
height,
|
|
3616
|
+
fit: "contain",
|
|
3617
|
+
background: "transparent",
|
|
3618
|
+
},
|
|
3619
|
+
},
|
|
3620
|
+
};
|
|
3621
|
+
return `${IMAGE_ENDPOINT}/${btoa(JSON.stringify(request))}`;
|
|
3622
|
+
};
|
|
3623
|
+
/**
|
|
3624
|
+
* Generates an url for the thumbnail size image
|
|
3625
|
+
*/
|
|
3626
|
+
const createThumbnailUrl = (id) => createResizedUrl(id, 100, 100);
|
|
3627
|
+
/**
|
|
3628
|
+
* Generates srcSet HTML attribute to avoid loading the full size image on small screens
|
|
3629
|
+
*/
|
|
3630
|
+
const createSrcSet = (id) => `${createResizedUrl(id, 480)} 480w, ${createResizedUrl(id, 800)} 800w`;
|
|
3631
|
+
|
|
3632
|
+
const cvaGallery = cssClassVarianceUtilities.cvaMerge([
|
|
3633
|
+
// These make the gallery grow to the height of the parent container,
|
|
3634
|
+
// which avoids jumping of the thumbnail row when going through images
|
|
3635
|
+
// with different ratios
|
|
3636
|
+
"grow",
|
|
3637
|
+
"[&_.image-gallery-content]:h-[100%]",
|
|
3638
|
+
"[&_.image-gallery-content]:flex",
|
|
3639
|
+
"[&_.image-gallery-content]:flex-col",
|
|
3640
|
+
"[&_.image-gallery-slide-wrapper]:grow",
|
|
3641
|
+
"[&_.image-gallery-slide-wrapper]:flex",
|
|
3642
|
+
"[&_.image-gallery-slide-wrapper]:flex-col",
|
|
3643
|
+
"[&_.image-gallery-slide-wrapper]:justify-center",
|
|
3644
|
+
"[&_.image-gallery-slide]:flex",
|
|
3645
|
+
// This centers thumbnails and makes the clickable area independent of image size
|
|
3646
|
+
"[&_.image-gallery-thumbnail]:h-[100px]",
|
|
3647
|
+
]);
|
|
3648
|
+
/**
|
|
3649
|
+
* Show and manage images
|
|
3650
|
+
*
|
|
3651
|
+
* Will show thumbnail selection on desktop.
|
|
3652
|
+
*
|
|
3653
|
+
* Reduces bandwidth usage by lazy loading thumbnails and loading smaller versions of images depending on screen size.
|
|
3654
|
+
*/
|
|
3655
|
+
const ImageCollection = (props) => {
|
|
3656
|
+
const { imageIds, actions, emptyPlaceholderText, additionalItemClassName } = props;
|
|
3657
|
+
const [openImageId, setOpenImageId] = React.useState(imageIds[0]);
|
|
3658
|
+
const [isDeleting, setIsDeleting] = React.useState(false);
|
|
3659
|
+
const { width } = useResize();
|
|
3660
|
+
const fileInputRef = React.useRef(null);
|
|
3661
|
+
const imageGalleryRef = React.useRef(null);
|
|
3662
|
+
const uploadButton = React.useMemo(() => (actions === null || actions === void 0 ? void 0 : actions.upload) ? (jsxRuntime.jsx("div", { className: "flex justify-end", children: jsxRuntime.jsx(Button, { onClick: () => { var _a; return (_a = fileInputRef.current) === null || _a === void 0 ? void 0 : _a.click(); }, children: actions.upload.label }) })) : null, [actions === null || actions === void 0 ? void 0 : actions.upload]);
|
|
3663
|
+
const items = React.useMemo(() => imageIds.map(imageId => ({
|
|
3664
|
+
id: imageId,
|
|
3665
|
+
original: createOriginalUrl(imageId),
|
|
3666
|
+
thumbnail: createThumbnailUrl(imageId),
|
|
3667
|
+
srcSet: createSrcSet(imageId),
|
|
3668
|
+
})), [imageIds]);
|
|
3669
|
+
React.useEffect(() => {
|
|
3670
|
+
if ((!openImageId || !imageIds.includes(openImageId)) && imageIds.length > 0) {
|
|
3671
|
+
setOpenImageId(imageIds[0]);
|
|
3672
|
+
}
|
|
3673
|
+
}, [imageIds, openImageId]);
|
|
3674
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [imageIds.length > 0 ? (jsxRuntime.jsxs("div", { className: "flex h-[100vh] max-h-[100vh] flex-col", children: [jsxRuntime.jsx(ImageGallery, { additionalClass: cvaGallery(), items: items, onBeforeSlide: index => { var _a; return setOpenImageId((_a = items[index]) === null || _a === void 0 ? void 0 : _a.id); }, ref: imageGalleryRef, renderItem: ({ original, srcSet,
|
|
3675
|
+
// Typing of the library is not flexible enough to add id, which is only used for the unit tests
|
|
3676
|
+
// @ts-ignore
|
|
3677
|
+
id, }) => (jsxRuntime.jsx("img", { alt: "full", className: tailwindMerge.twMerge(additionalItemClassName, "w-[100%]", "object-contain"), "data-testid": `image-${id}`, loading: "lazy", sizes: "(max-width: 480px) 480px, 800px", src: original, srcSet: srcSet })), renderThumbInner: ({ thumbnail,
|
|
3678
|
+
// Typing of the library is not flexible enough to add id, which is only used for the unit tests
|
|
3679
|
+
// @ts-ignore
|
|
3680
|
+
id, }) => jsxRuntime.jsx("img", { alt: "thumbnail", "data-testid": `thumbnail-${id}`, loading: "lazy", src: thumbnail }), showFullscreenButton: false, showPlayButton: false, showThumbnails: width > 768,
|
|
3681
|
+
// reduce sliding around during deletion
|
|
3682
|
+
slideDuration: isDeleting ? 0 : 200, ...props }), uploadButton, (actions === null || actions === void 0 ? void 0 : actions.remove) ? (jsxRuntime.jsx(Button, { className: "absolute right-2 top-2", loading: isDeleting, onClick: async () => {
|
|
3683
|
+
var _a;
|
|
3684
|
+
if (!(((_a = actions.remove) === null || _a === void 0 ? void 0 : _a.onRemove) && openImageId)) {
|
|
3685
|
+
return;
|
|
3686
|
+
}
|
|
3687
|
+
try {
|
|
3688
|
+
let nextIndex;
|
|
3689
|
+
const indexToDelete = imageIds.indexOf(openImageId);
|
|
3690
|
+
const deletingLastImage = indexToDelete === imageIds.length - 1;
|
|
3691
|
+
if (imageIds.length === 1) {
|
|
3692
|
+
nextIndex = undefined;
|
|
3693
|
+
}
|
|
3694
|
+
else if (deletingLastImage) {
|
|
3695
|
+
nextIndex = indexToDelete - 1;
|
|
3696
|
+
}
|
|
3697
|
+
else {
|
|
3698
|
+
// we set the index after the deletion, so the index will be the same
|
|
3699
|
+
nextIndex = indexToDelete;
|
|
3700
|
+
}
|
|
3701
|
+
setIsDeleting(true);
|
|
3702
|
+
await actions.remove.onRemove(openImageId);
|
|
3703
|
+
if (nextIndex !== undefined) {
|
|
3704
|
+
imageGalleryRef.current && nextIndex && imageGalleryRef.current.slideToIndex(nextIndex);
|
|
3705
|
+
}
|
|
3706
|
+
}
|
|
3707
|
+
finally {
|
|
3708
|
+
setIsDeleting(false);
|
|
3709
|
+
}
|
|
3710
|
+
}, prefix: jsxRuntime.jsx(Icon, { name: "Trash", size: "small" }), variant: "secondary-danger", children: actions.remove.label })) : null] })) : (jsxRuntime.jsx(EmptyState, { action: uploadButton, description: emptyPlaceholderText })), jsxRuntime.jsx("input", {
|
|
3711
|
+
// Users can still select other files on mobile devices
|
|
3712
|
+
accept: "image/jpeg, image/png, image/bmp, image/webp, image/gif", hidden: true, multiple: true, onChange: async (e) => {
|
|
3713
|
+
if (!(e.target.files && (actions === null || actions === void 0 ? void 0 : actions.upload))) {
|
|
3714
|
+
return;
|
|
3715
|
+
}
|
|
3716
|
+
await actions.upload.onUpload(e.target.files);
|
|
3717
|
+
}, ref: fileInputRef, type: "file" })] }));
|
|
3718
|
+
};
|
|
3719
|
+
|
|
3601
3720
|
/**
|
|
3602
3721
|
* The hook that powers the Popover component.
|
|
3603
3722
|
* It should not be used directly, but rather through the Popover component.
|
|
@@ -4985,8 +5104,10 @@ exports.EmptyState = EmptyState;
|
|
|
4985
5104
|
exports.EmptyValue = EmptyValue;
|
|
4986
5105
|
exports.ExternalLink = ExternalLink;
|
|
4987
5106
|
exports.Heading = Heading;
|
|
5107
|
+
exports.IMAGE_ENDPOINT = IMAGE_ENDPOINT;
|
|
4988
5108
|
exports.Icon = Icon;
|
|
4989
5109
|
exports.IconButton = IconButton;
|
|
5110
|
+
exports.ImageCollection = ImageCollection;
|
|
4990
5111
|
exports.Indicator = Indicator;
|
|
4991
5112
|
exports.KPICard = KPICard;
|
|
4992
5113
|
exports.MenuItem = MenuItem;
|
|
@@ -5024,6 +5145,8 @@ exports.Tooltip = Tooltip;
|
|
|
5024
5145
|
exports.ValueBar = ValueBar;
|
|
5025
5146
|
exports.VirtualizedList = VirtualizedList;
|
|
5026
5147
|
exports.WidgetBody = WidgetBody;
|
|
5148
|
+
exports.createOriginalUrl = createOriginalUrl;
|
|
5149
|
+
exports.createThumbnailUrl = createThumbnailUrl;
|
|
5027
5150
|
exports.cvaButton = cvaButton;
|
|
5028
5151
|
exports.cvaButtonPrefixSuffix = cvaButtonPrefixSuffix;
|
|
5029
5152
|
exports.cvaButtonSpinner = cvaButtonSpinner;
|
package/index.esm.js
CHANGED
|
@@ -15,9 +15,10 @@ import isEqual from 'lodash/isEqual';
|
|
|
15
15
|
import { usePrevious, useMeasure, useCopyToClipboard } from 'react-use';
|
|
16
16
|
import { Link, useBlocker } from '@tanstack/react-router';
|
|
17
17
|
import { useSwipeable } from 'react-swipeable';
|
|
18
|
+
import ImageGallery from 'react-image-gallery';
|
|
19
|
+
import { twMerge } from 'tailwind-merge';
|
|
18
20
|
import { useFloating, autoUpdate, offset, flip, shift, size, useClick, useDismiss, useHover as useHover$1, useRole, useInteractions, useMergeRefs, FloatingPortal, FloatingFocusManager, arrow, useTransitionStatus, FloatingArrow } from '@floating-ui/react';
|
|
19
21
|
import omit from 'lodash/omit';
|
|
20
|
-
import { twMerge } from 'tailwind-merge';
|
|
21
22
|
import { HelmetProvider, Helmet } from 'react-helmet-async';
|
|
22
23
|
import { Trigger, Content, List, Root } from '@radix-ui/react-tabs';
|
|
23
24
|
import { format, formatDistance } from 'date-fns';
|
|
@@ -3578,6 +3579,124 @@ const ExternalLink = ({ rel = "noreferrer", target = "_blank", href, className,
|
|
|
3578
3579
|
return (jsx("a", { className: cvaExternalLink({ className }), "data-testid": dataTestId, href: href, onClick: onClick, rel: rel, target: target, title: title, children: children }));
|
|
3579
3580
|
};
|
|
3580
3581
|
|
|
3582
|
+
const IMAGE_ENDPOINT = "https://images.iris.trackunit.com";
|
|
3583
|
+
/**
|
|
3584
|
+
* Generates an url for the original sized image from the image id
|
|
3585
|
+
*/
|
|
3586
|
+
const createOriginalUrl = (id) => `${IMAGE_ENDPOINT}/${btoa(JSON.stringify({
|
|
3587
|
+
key: id,
|
|
3588
|
+
}))}`;
|
|
3589
|
+
const createResizedUrl = (id, width, height) => {
|
|
3590
|
+
const request = {
|
|
3591
|
+
key: id,
|
|
3592
|
+
edits: {
|
|
3593
|
+
resize: {
|
|
3594
|
+
width,
|
|
3595
|
+
height,
|
|
3596
|
+
fit: "contain",
|
|
3597
|
+
background: "transparent",
|
|
3598
|
+
},
|
|
3599
|
+
},
|
|
3600
|
+
};
|
|
3601
|
+
return `${IMAGE_ENDPOINT}/${btoa(JSON.stringify(request))}`;
|
|
3602
|
+
};
|
|
3603
|
+
/**
|
|
3604
|
+
* Generates an url for the thumbnail size image
|
|
3605
|
+
*/
|
|
3606
|
+
const createThumbnailUrl = (id) => createResizedUrl(id, 100, 100);
|
|
3607
|
+
/**
|
|
3608
|
+
* Generates srcSet HTML attribute to avoid loading the full size image on small screens
|
|
3609
|
+
*/
|
|
3610
|
+
const createSrcSet = (id) => `${createResizedUrl(id, 480)} 480w, ${createResizedUrl(id, 800)} 800w`;
|
|
3611
|
+
|
|
3612
|
+
const cvaGallery = cvaMerge([
|
|
3613
|
+
// These make the gallery grow to the height of the parent container,
|
|
3614
|
+
// which avoids jumping of the thumbnail row when going through images
|
|
3615
|
+
// with different ratios
|
|
3616
|
+
"grow",
|
|
3617
|
+
"[&_.image-gallery-content]:h-[100%]",
|
|
3618
|
+
"[&_.image-gallery-content]:flex",
|
|
3619
|
+
"[&_.image-gallery-content]:flex-col",
|
|
3620
|
+
"[&_.image-gallery-slide-wrapper]:grow",
|
|
3621
|
+
"[&_.image-gallery-slide-wrapper]:flex",
|
|
3622
|
+
"[&_.image-gallery-slide-wrapper]:flex-col",
|
|
3623
|
+
"[&_.image-gallery-slide-wrapper]:justify-center",
|
|
3624
|
+
"[&_.image-gallery-slide]:flex",
|
|
3625
|
+
// This centers thumbnails and makes the clickable area independent of image size
|
|
3626
|
+
"[&_.image-gallery-thumbnail]:h-[100px]",
|
|
3627
|
+
]);
|
|
3628
|
+
/**
|
|
3629
|
+
* Show and manage images
|
|
3630
|
+
*
|
|
3631
|
+
* Will show thumbnail selection on desktop.
|
|
3632
|
+
*
|
|
3633
|
+
* Reduces bandwidth usage by lazy loading thumbnails and loading smaller versions of images depending on screen size.
|
|
3634
|
+
*/
|
|
3635
|
+
const ImageCollection = (props) => {
|
|
3636
|
+
const { imageIds, actions, emptyPlaceholderText, additionalItemClassName } = props;
|
|
3637
|
+
const [openImageId, setOpenImageId] = useState(imageIds[0]);
|
|
3638
|
+
const [isDeleting, setIsDeleting] = useState(false);
|
|
3639
|
+
const { width } = useResize();
|
|
3640
|
+
const fileInputRef = useRef(null);
|
|
3641
|
+
const imageGalleryRef = useRef(null);
|
|
3642
|
+
const uploadButton = useMemo(() => (actions === null || actions === void 0 ? void 0 : actions.upload) ? (jsx("div", { className: "flex justify-end", children: jsx(Button, { onClick: () => { var _a; return (_a = fileInputRef.current) === null || _a === void 0 ? void 0 : _a.click(); }, children: actions.upload.label }) })) : null, [actions === null || actions === void 0 ? void 0 : actions.upload]);
|
|
3643
|
+
const items = useMemo(() => imageIds.map(imageId => ({
|
|
3644
|
+
id: imageId,
|
|
3645
|
+
original: createOriginalUrl(imageId),
|
|
3646
|
+
thumbnail: createThumbnailUrl(imageId),
|
|
3647
|
+
srcSet: createSrcSet(imageId),
|
|
3648
|
+
})), [imageIds]);
|
|
3649
|
+
useEffect(() => {
|
|
3650
|
+
if ((!openImageId || !imageIds.includes(openImageId)) && imageIds.length > 0) {
|
|
3651
|
+
setOpenImageId(imageIds[0]);
|
|
3652
|
+
}
|
|
3653
|
+
}, [imageIds, openImageId]);
|
|
3654
|
+
return (jsxs(Fragment, { children: [imageIds.length > 0 ? (jsxs("div", { className: "flex h-[100vh] max-h-[100vh] flex-col", children: [jsx(ImageGallery, { additionalClass: cvaGallery(), items: items, onBeforeSlide: index => { var _a; return setOpenImageId((_a = items[index]) === null || _a === void 0 ? void 0 : _a.id); }, ref: imageGalleryRef, renderItem: ({ original, srcSet,
|
|
3655
|
+
// Typing of the library is not flexible enough to add id, which is only used for the unit tests
|
|
3656
|
+
// @ts-ignore
|
|
3657
|
+
id, }) => (jsx("img", { alt: "full", className: twMerge(additionalItemClassName, "w-[100%]", "object-contain"), "data-testid": `image-${id}`, loading: "lazy", sizes: "(max-width: 480px) 480px, 800px", src: original, srcSet: srcSet })), renderThumbInner: ({ thumbnail,
|
|
3658
|
+
// Typing of the library is not flexible enough to add id, which is only used for the unit tests
|
|
3659
|
+
// @ts-ignore
|
|
3660
|
+
id, }) => jsx("img", { alt: "thumbnail", "data-testid": `thumbnail-${id}`, loading: "lazy", src: thumbnail }), showFullscreenButton: false, showPlayButton: false, showThumbnails: width > 768,
|
|
3661
|
+
// reduce sliding around during deletion
|
|
3662
|
+
slideDuration: isDeleting ? 0 : 200, ...props }), uploadButton, (actions === null || actions === void 0 ? void 0 : actions.remove) ? (jsx(Button, { className: "absolute right-2 top-2", loading: isDeleting, onClick: async () => {
|
|
3663
|
+
var _a;
|
|
3664
|
+
if (!(((_a = actions.remove) === null || _a === void 0 ? void 0 : _a.onRemove) && openImageId)) {
|
|
3665
|
+
return;
|
|
3666
|
+
}
|
|
3667
|
+
try {
|
|
3668
|
+
let nextIndex;
|
|
3669
|
+
const indexToDelete = imageIds.indexOf(openImageId);
|
|
3670
|
+
const deletingLastImage = indexToDelete === imageIds.length - 1;
|
|
3671
|
+
if (imageIds.length === 1) {
|
|
3672
|
+
nextIndex = undefined;
|
|
3673
|
+
}
|
|
3674
|
+
else if (deletingLastImage) {
|
|
3675
|
+
nextIndex = indexToDelete - 1;
|
|
3676
|
+
}
|
|
3677
|
+
else {
|
|
3678
|
+
// we set the index after the deletion, so the index will be the same
|
|
3679
|
+
nextIndex = indexToDelete;
|
|
3680
|
+
}
|
|
3681
|
+
setIsDeleting(true);
|
|
3682
|
+
await actions.remove.onRemove(openImageId);
|
|
3683
|
+
if (nextIndex !== undefined) {
|
|
3684
|
+
imageGalleryRef.current && nextIndex && imageGalleryRef.current.slideToIndex(nextIndex);
|
|
3685
|
+
}
|
|
3686
|
+
}
|
|
3687
|
+
finally {
|
|
3688
|
+
setIsDeleting(false);
|
|
3689
|
+
}
|
|
3690
|
+
}, prefix: jsx(Icon, { name: "Trash", size: "small" }), variant: "secondary-danger", children: actions.remove.label })) : null] })) : (jsx(EmptyState, { action: uploadButton, description: emptyPlaceholderText })), jsx("input", {
|
|
3691
|
+
// Users can still select other files on mobile devices
|
|
3692
|
+
accept: "image/jpeg, image/png, image/bmp, image/webp, image/gif", hidden: true, multiple: true, onChange: async (e) => {
|
|
3693
|
+
if (!(e.target.files && (actions === null || actions === void 0 ? void 0 : actions.upload))) {
|
|
3694
|
+
return;
|
|
3695
|
+
}
|
|
3696
|
+
await actions.upload.onUpload(e.target.files);
|
|
3697
|
+
}, ref: fileInputRef, type: "file" })] }));
|
|
3698
|
+
};
|
|
3699
|
+
|
|
3581
3700
|
/**
|
|
3582
3701
|
* The hook that powers the Popover component.
|
|
3583
3702
|
* It should not be used directly, but rather through the Popover component.
|
|
@@ -4947,4 +5066,4 @@ const cvaClickable = cvaMerge([
|
|
|
4947
5066
|
},
|
|
4948
5067
|
});
|
|
4949
5068
|
|
|
4950
|
-
export { Alert, Badge, Breadcrumb, BreadcrumbContainer, BreadcrumbItem, Button, Card, CardBody, CardFooter, CardHeader, Collapse, CompletionStatusIndicator, CopyableText, Drawer, EmptyState, EmptyValue, ExternalLink, Heading, Icon, IconButton, Indicator, KPICard, MenuItem, MenuList, MoreMenu, Notice, PackageNameStoryComponent, Page, PageContent, PageHeader, Pagination, Polygon, Popover, PopoverContent, PopoverTitle, PopoverTrigger, Prompt, ROLE_CARD, SectionHeader, Sidebar, SkeletonLines, Spacer, Spinner, StarButton, Tab, TabContent, TabList, Tabs, Tag, Text, Timeline, TimelineElement, ToggleGroup, Tooltip, ValueBar, VirtualizedList, WidgetBody, cvaButton, cvaButtonPrefixSuffix, cvaButtonSpinner, cvaButtonSpinnerContainer, cvaClickable, cvaIconButton, cvaIndicator, cvaIndicatorIcon, cvaIndicatorIconBackground, cvaIndicatorLabel, cvaIndicatorPing, cvaInteractableItem, cvaMenuItem, cvaMenuItemLabel, cvaMenuItemPrefix, cvaMenuItemStyle, cvaMenuItemSuffix, docs, getDevicePixelRatio, getValueBarColorByValue, iconColorNames, iconPalette, setLocalStorage, useClickOutside, useContinuousTimeout, useDebounce, useDevicePixelRatio, useGeometry, useHover, useIsFirstRender, useIsFullscreen, useIsTextCutOff, useLocalStorage, useLocalStorageReducer, useOptionallyElevatedState, useOverflowItems, usePopoverContext, usePrompt, useResize, useSelfUpdatingRef, useTimeout, useViewportSize, useWindowActivity };
|
|
5069
|
+
export { Alert, Badge, Breadcrumb, BreadcrumbContainer, BreadcrumbItem, Button, Card, CardBody, CardFooter, CardHeader, Collapse, CompletionStatusIndicator, CopyableText, Drawer, EmptyState, EmptyValue, ExternalLink, Heading, IMAGE_ENDPOINT, Icon, IconButton, ImageCollection, Indicator, KPICard, MenuItem, MenuList, MoreMenu, Notice, PackageNameStoryComponent, Page, PageContent, PageHeader, Pagination, Polygon, Popover, PopoverContent, PopoverTitle, PopoverTrigger, Prompt, ROLE_CARD, SectionHeader, Sidebar, SkeletonLines, Spacer, Spinner, StarButton, Tab, TabContent, TabList, Tabs, Tag, Text, Timeline, TimelineElement, ToggleGroup, Tooltip, ValueBar, VirtualizedList, WidgetBody, createOriginalUrl, createThumbnailUrl, cvaButton, cvaButtonPrefixSuffix, cvaButtonSpinner, cvaButtonSpinnerContainer, cvaClickable, cvaIconButton, cvaIndicator, cvaIndicatorIcon, cvaIndicatorIconBackground, cvaIndicatorLabel, cvaIndicatorPing, cvaInteractableItem, cvaMenuItem, cvaMenuItemLabel, cvaMenuItemPrefix, cvaMenuItemStyle, cvaMenuItemSuffix, docs, getDevicePixelRatio, getValueBarColorByValue, iconColorNames, iconPalette, setLocalStorage, useClickOutside, useContinuousTimeout, useDebounce, useDevicePixelRatio, useGeometry, useHover, useIsFirstRender, useIsFullscreen, useIsTextCutOff, useLocalStorage, useLocalStorageReducer, useOptionallyElevatedState, useOverflowItems, usePopoverContext, usePrompt, useResize, useSelfUpdatingRef, useTimeout, useViewportSize, useWindowActivity };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trackunit/react-components",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"repository": "https://github.com/Trackunit/manager",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
6
|
"engines": {
|
|
@@ -27,7 +27,8 @@
|
|
|
27
27
|
"string-ts": "^2.0.0",
|
|
28
28
|
"tailwind-merge": "^2.0.0",
|
|
29
29
|
"@trackunit/react-table-pagination": "*",
|
|
30
|
-
"uuid": "^9.0.1"
|
|
30
|
+
"uuid": "^9.0.1",
|
|
31
|
+
"react-image-gallery": "1.3.0"
|
|
31
32
|
},
|
|
32
33
|
"module": "./index.esm.js",
|
|
33
34
|
"main": "./index.cjs.js",
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ComponentProps } from "react";
|
|
2
|
+
import ImageGallery from "react-image-gallery";
|
|
3
|
+
type Props = Omit<ComponentProps<typeof ImageGallery>, "items"> & {
|
|
4
|
+
imageIds: string[];
|
|
5
|
+
actions?: {
|
|
6
|
+
upload?: {
|
|
7
|
+
label: string;
|
|
8
|
+
onUpload: (pictures: FileList) => Promise<void>;
|
|
9
|
+
};
|
|
10
|
+
remove?: {
|
|
11
|
+
label: string;
|
|
12
|
+
onRemove?: (id: string) => Promise<void>;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
emptyPlaceholderText: string;
|
|
16
|
+
additionalItemClassName?: string;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Show and manage images
|
|
20
|
+
*
|
|
21
|
+
* Will show thumbnail selection on desktop.
|
|
22
|
+
*
|
|
23
|
+
* Reduces bandwidth usage by lazy loading thumbnails and loading smaller versions of images depending on screen size.
|
|
24
|
+
*/
|
|
25
|
+
export declare const ImageCollection: (props: Props) => import("react/jsx-runtime").JSX.Element;
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare const IMAGE_ENDPOINT = "https://images.iris.trackunit.com";
|
|
2
|
+
/**
|
|
3
|
+
* Generates an url for the original sized image from the image id
|
|
4
|
+
*/
|
|
5
|
+
export declare const createOriginalUrl: (id: string) => string;
|
|
6
|
+
/**
|
|
7
|
+
* Generates an url for the thumbnail size image
|
|
8
|
+
*/
|
|
9
|
+
export declare const createThumbnailUrl: (id: string) => string;
|
|
10
|
+
/**
|
|
11
|
+
* Generates srcSet HTML attribute to avoid loading the full size image on small screens
|
|
12
|
+
*/
|
|
13
|
+
export declare const createSrcSet: (id: string) => string;
|
|
@@ -12,6 +12,7 @@ export * from "./EmptyValue/EmptyValue";
|
|
|
12
12
|
export * from "./ExternalLink/ExternalLink";
|
|
13
13
|
export * from "./Heading";
|
|
14
14
|
export * from "./Icon/Icon";
|
|
15
|
+
export * from "./ImageCollection/ImageCollection";
|
|
15
16
|
export * from "./Indicator";
|
|
16
17
|
export * from "./KPICard/KPICard";
|
|
17
18
|
export * from "./Menu";
|
|
@@ -41,3 +42,7 @@ export * from "./Tooltip";
|
|
|
41
42
|
export * from "./ValueBar";
|
|
42
43
|
export * from "./VirtualizedList/VirtualizedList";
|
|
43
44
|
export * from "./Widget";
|
|
45
|
+
export * from "./buttons";
|
|
46
|
+
export { createOriginalUrl } from "./ImageCollection/helpers";
|
|
47
|
+
export { createThumbnailUrl } from "./ImageCollection/helpers";
|
|
48
|
+
export { IMAGE_ENDPOINT } from "./ImageCollection/helpers";
|