UNPKG

@onesy/ui-react

Version:
406 lines (405 loc) 24.3 kB
"use strict"; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = __importDefault(require("react")); const utils_1 = require("@onesy/utils"); const style_react_1 = require("@onesy/style-react"); const IconMaterialDraftW100_1 = __importDefault(require("@onesy/icons-material-rounded-react/IconMaterialDraftW100")); const Link_1 = __importDefault(require("../Link")); const Type_1 = __importDefault(require("../Type")); const Interaction_1 = __importDefault(require("../Interaction")); const Line_1 = __importDefault(require("../Line/Line")); const AudioPlayer_1 = __importDefault(require("../AudioPlayer")); const VideoPlayer_1 = __importDefault(require("../VideoPlayer")); const Portal_1 = __importDefault(require("../Portal")); const ImageGallery_1 = __importDefault(require("../ImageGallery")); const utils_2 = require("../utils"); const useStyle = (0, style_react_1.style)(theme => ({ root: {}, items: { maxWidth: '100%', padding: theme.methods.space.value(0.5, 'px'), overflow: 'auto hidden' }, item: {}, wrapper: { position: 'relative', flex: '0 0 auto' }, wrapper_image: { transition: theme.methods.transitions.make('transform'), '&:active': { transform: 'scale(0.94)' } }, wrapper_other: { transition: theme.methods.transitions.make('transform'), '&:active': { transform: 'scale(0.94)' } }, name: { wordBreak: 'break-word' }, image: { position: 'relative', backgroundSize: 'cover', backgroundPosition: 'center', backgroundRepeat: 'no-repeat', aspectRatio: '16 / 9' }, imageWrapper_size_small: { width: '174px' }, imageWrapper_size_regular: { width: '214px' }, imageWrapper_size_large: { width: '254px' }, image_size_small: { borderRadius: theme.methods.shape.radius.value(1) }, image_size_regular: { borderRadius: theme.methods.shape.radius.value(2) }, image_size_large: { borderRadius: theme.methods.shape.radius.value(3) }, audioWrapper_size_small: { width: '324px' }, audioWrapper_size_regular: { width: '340px' }, audioWrapper_size_large: { width: '440px' }, videoWrapper_size_small: { width: '324px' }, videoWrapper_size_regular: { width: '340px' }, videoWrapper_size_large: { width: '440px' }, other: { position: 'relative', aspectRatio: '3 / 4', cursor: 'pointer', userSelect: 'none', background: theme.palette.background.secondary.tertiary, boxShadow: theme.shadows.values.default[1] }, otherWrapper_size_small: { width: '74px' }, otherWrapper_size_regular: { width: '94px' }, otherWrapper_size_large: { width: '114px' }, other_size_small: { borderRadius: theme.methods.shape.radius.value(1) }, other_size_regular: { borderRadius: theme.methods.shape.radius.value(2) }, other_size_large: { borderRadius: theme.methods.shape.radius.value(3) }, externalLinks: { overflow: 'auto hidden' }, aspectRatioYoutube: { aspectRatio: '16 / 9', width: '100%', maxWidth: '750px' }, aspectRatioVimeo: { aspectRatio: '16 / 9', width: '440px' }, aspectRatioInstagram: { aspectRatio: '3 / 5.6', width: '340px' }, aspectRatioTiktok: { aspectRatio: '3 / 6.84', width: '324px' }, customEmbed: { maxWidth: '750px' } }), { name: 'onesy-Medias' }); const Medias = react_1.default.forwardRef((props_, ref) => { var _a, _b, _c; const theme = (0, style_react_1.useOnesyTheme)(); const l = theme.l; const props = react_1.default.useMemo(() => { var _a, _b, _c, _d, _e, _f, _g, _h; return (Object.assign(Object.assign(Object.assign({}, (_d = (_c = (_b = (_a = theme === null || theme === void 0 ? void 0 : theme.ui) === null || _a === void 0 ? void 0 : _a.elements) === null || _b === void 0 ? void 0 : _b.all) === null || _c === void 0 ? void 0 : _c.props) === null || _d === void 0 ? void 0 : _d.default), (_h = (_g = (_f = (_e = theme === null || theme === void 0 ? void 0 : theme.ui) === null || _e === void 0 ? void 0 : _e.elements) === null || _f === void 0 ? void 0 : _f.onesyMedias) === null || _g === void 0 ? void 0 : _g.props) === null || _h === void 0 ? void 0 : _h.default), props_)); }, [props_]); const Line = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Line) || Line_1.default; }, [theme]); const Link = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Link) || Link_1.default; }, [theme]); const Type = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Type) || Type_1.default; }, [theme]); const Interaction = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Interaction) || Interaction_1.default; }, [theme]); const AudioPlayer = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.AudioPlayer) || AudioPlayer_1.default; }, [theme]); const VideoPlayer = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.VideoPlayer) || VideoPlayer_1.default; }, [theme]); const Portal = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Portal) || Portal_1.default; }, [theme]); const ImageGallery = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.ImageGallery) || ImageGallery_1.default; }, [theme]); const { size = 'regular', values: values_ = [], imageGallery = true, show = ['embed', 'image', 'video', 'audio', 'other'], noName = true, IconDocument = IconMaterialDraftW100_1.default, NameProps, WrapperProps, EmbedProps, ImageProps, AudioProps, VideoProps, OtherProps, ItemsProps, EmbedItemsProps = { fullWidth: true }, ImageItemsProps, AudioItemsProps, VideoItemsProps, OtherItemsProps, className, children } = props, other = __rest(props, ["size", "values", "imageGallery", "show", "noName", "IconDocument", "NameProps", "WrapperProps", "EmbedProps", "ImageProps", "AudioProps", "VideoProps", "OtherProps", "ItemsProps", "EmbedItemsProps", "ImageItemsProps", "AudioItemsProps", "VideoItemsProps", "OtherItemsProps", "className", "children"]); const { classes } = useStyle(); const [open, setOpen] = react_1.default.useState(); const refs = { root: react_1.default.useRef(undefined) }; const values = (0, utils_1.is)('array', values_) ? values_ : [values_]; const onOpen = react_1.default.useCallback((index) => { setOpen({ index }); }, []); const onClose = react_1.default.useCallback(() => { setOpen(null); }, []); const onOpenMedia = react_1.default.useCallback((media) => { window.open(media.url || media.urlSmall, 'blank_'); }, []); const items = react_1.default.useMemo(() => { const items_ = { image: [], audio: [], video: [], other: [], embed: [] }; values.filter(item => (item === null || item === void 0 ? void 0 : item.value) && !!Object.keys(item.value).length).forEach(item => { var _a, _b, _c; const media = item.value; if (media) { if (media.urlEmbed !== undefined) items_.embed.push(item); else if ((_a = media.mime) === null || _a === void 0 ? void 0 : _a.startsWith('image')) items_.image.push(item); else if ((_b = media.mime) === null || _b === void 0 ? void 0 : _b.startsWith('audio')) items_.audio.push(item); else if ((_c = media.mime) === null || _c === void 0 ? void 0 : _c.startsWith('video')) items_.video.push(item); else items_.other.push(item); } }); return items_; }, [values]); const getLink = react_1.default.useCallback((item, index) => { var _a; const urlEmbed = item === null || item === void 0 ? void 0 : item.urlEmbed; if (!urlEmbed) return null; const otherProps = Object.assign({ key: index }, EmbedProps); const urlEmbedStart = urlEmbed.replace('http://', '').replace('https://', ''); const isPlatform = (urlEmbedStart.startsWith('youtu') || urlEmbedStart.startsWith('www.youtu') || urlEmbedStart.startsWith('instagram') || urlEmbedStart.startsWith('www.instagram') || urlEmbedStart.startsWith('tiktok') || urlEmbedStart.startsWith('www.tiktok') || urlEmbedStart.startsWith('vimeo') || urlEmbedStart.startsWith('www.vimeo')); // predefined if (isPlatform) { let url; try { url = new URL(item.urlEmbed); } catch (error) { console.log('Invalid embed URL', item); return null; } const id = (_a = url.pathname) === null || _a === void 0 ? void 0 : _a.split('/').filter(Boolean).slice(-1)[0]; if (!(url === null || url === void 0 ? void 0 : url.hostname) || !id) return null; if (item.urlEmbed.includes('youtu.be')) { return ((0, jsx_runtime_1.jsx)("iframe", Object.assign({}, otherProps, { title: item.name || '', src: `https://www.youtube.com/embed/${id}`, allow: 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share', allowFullScreen: true, className: (0, style_react_1.classNames)([ otherProps === null || otherProps === void 0 ? void 0 : otherProps.className, classes.aspectRatioYoutube ]) }))); } if (item.urlEmbed.includes('instagram.com')) { return ((0, jsx_runtime_1.jsx)("iframe", Object.assign({}, otherProps, { title: item.name || '', src: `https://www.instagram.com/reel/${id}/embed`, allowFullScreen: true, className: (0, style_react_1.classNames)([ otherProps === null || otherProps === void 0 ? void 0 : otherProps.className, classes.aspectRatioInstagram ]) }))); } if (item.urlEmbed.includes('tiktok.com')) { return ((0, jsx_runtime_1.jsx)("iframe", Object.assign({}, otherProps, { title: item.name || '', src: `https://www.tiktok.com/embed/v2/${id}`, allowFullScreen: true, className: (0, style_react_1.classNames)([ otherProps === null || otherProps === void 0 ? void 0 : otherProps.className, classes.aspectRatioTiktok ]) }))); } if (item.urlEmbed.includes('vimeo.com')) { return ((0, jsx_runtime_1.jsx)("iframe", Object.assign({}, otherProps, { title: item.name || '', src: `https://player.vimeo.com/video/${id}`, allowFullScreen: true, className: (0, style_react_1.classNames)([ otherProps === null || otherProps === void 0 ? void 0 : otherProps.className, classes.aspectRatioVimeo ]) }))); } return ((0, jsx_runtime_1.jsx)(Link, Object.assign({}, otherProps, { href: item === null || item === void 0 ? void 0 : item.urlEmbed, target: 'blank' }, { children: item.name || item.urlEmbed }))); } // custom embed code return ((0, jsx_runtime_1.jsx)(Line, Object.assign({}, otherProps, { className: (0, style_react_1.classNames)([ otherProps === null || otherProps === void 0 ? void 0 : otherProps.className, classes.customEmbed ]), fullWidth: true, dangerouslySetInnerHTML: { __html: urlEmbed } }))); }, [EmbedProps]); const getItem = (version, item, index) => { var _a, _b, _c, _d, _e, _f; const media = item.value; const name = (((_a = item === null || item === void 0 ? void 0 : item.props) === null || _a === void 0 ? void 0 : _a.name) || !noName) && ((0, jsx_runtime_1.jsx)(Type, Object.assign({ version: size === 'large' ? 'l2' : size === 'regular' ? 'l3' : 'l3' }, NameProps, { className: (0, style_react_1.classNames)([ (0, utils_2.staticClassName)('Medias', theme) && [ 'onesy-Medias-name' ], NameProps === null || NameProps === void 0 ? void 0 : NameProps.className, classes.name ]) }, { children: (media === null || media === void 0 ? void 0 : media.name) || l('No name') }))); if (version === 'embed') { return getLink(media, index); } if (version === 'image') { return ((0, jsx_runtime_1.jsxs)(Line, Object.assign({ gap: 1 }, WrapperProps, { onClick: () => imageGallery && onOpen(index), className: (0, style_react_1.classNames)([ (0, utils_2.staticClassName)('Medias', theme) && [ 'onesy-Medias-wrapper', 'onesy-Medias-wrapper-image' ], WrapperProps === null || WrapperProps === void 0 ? void 0 : WrapperProps.className, classes.wrapper, classes.wrapper_image, classes[`imageWrapper_size_${size}`] ]) }, { children: [(0, jsx_runtime_1.jsx)(Line, Object.assign({}, ImageProps, item === null || item === void 0 ? void 0 : item.props, { fullWidth: true, className: (0, style_react_1.classNames)([ (0, utils_2.staticClassName)('Medias', theme) && [ 'onesy-Medias-item', 'onesy-Medias-item-image' ], ImageProps === null || ImageProps === void 0 ? void 0 : ImageProps.className, (_b = item === null || item === void 0 ? void 0 : item.props) === null || _b === void 0 ? void 0 : _b.className, classes.item, classes.image, classes[`image_size_${size}`] ]), style: Object.assign({ backgroundImage: `url(${media.urlSmall || media.url})` }, (_c = item === null || item === void 0 ? void 0 : item.props) === null || _c === void 0 ? void 0 : _c.style) }, { children: (0, jsx_runtime_1.jsx)(Interaction, {}) }), index), name] }), index)); } if (version === 'audio') { return ((0, jsx_runtime_1.jsxs)(Line, Object.assign({ gap: 1 }, WrapperProps, { className: (0, style_react_1.classNames)([ (0, utils_2.staticClassName)('Medias', theme) && [ 'onesy-Medias-wrapper', 'onesy-Medias-wrapper-audio' ], WrapperProps === null || WrapperProps === void 0 ? void 0 : WrapperProps.className, classes.wrapper, classes[`audioWrapper_size_${size}`] ]) }, { children: [(0, jsx_runtime_1.jsx)(AudioPlayer, Object.assign({ tonal: true, color: 'primary', src: media.url || media.urlSmall, size: size }, media, AudioProps, item === null || item === void 0 ? void 0 : item.props, { fullWidth: true, className: (0, style_react_1.classNames)([ (0, utils_2.staticClassName)('Medias', theme) && [ 'onesy-Medias-item', 'onesy-Medias-item-audio' ], VideoProps === null || VideoProps === void 0 ? void 0 : VideoProps.className, (_d = item === null || item === void 0 ? void 0 : item.props) === null || _d === void 0 ? void 0 : _d.className, classes.item, classes.audio ]) }), index), name] }), index)); } if (version === 'video') { return ((0, jsx_runtime_1.jsxs)(Line, Object.assign({ gap: 1 }, WrapperProps, { className: (0, style_react_1.classNames)([ (0, utils_2.staticClassName)('Medias', theme) && [ 'onesy-Medias-wrapper', 'onesy-Medias-wrapper-video' ], WrapperProps === null || WrapperProps === void 0 ? void 0 : WrapperProps.className, classes.wrapper, classes[`videoWrapper_size_${size}`] ]) }, { children: [(0, jsx_runtime_1.jsx)(VideoPlayer, Object.assign({ tonal: true, color: 'primary', src: media.url || media.urlSmall, size: size }, media, VideoProps, item === null || item === void 0 ? void 0 : item.props, { fullWidth: true, className: (0, style_react_1.classNames)([ (0, utils_2.staticClassName)('Medias', theme) && [ 'onesy-Medias-item', 'onesy-Medias-item-video' ], VideoProps === null || VideoProps === void 0 ? void 0 : VideoProps.className, (_e = item === null || item === void 0 ? void 0 : item.props) === null || _e === void 0 ? void 0 : _e.className, classes.item, classes.video ]) }), index), name] }), index)); } if (version === 'other') { return ((0, jsx_runtime_1.jsxs)(Line, Object.assign({ gap: 1 }, WrapperProps, { className: (0, style_react_1.classNames)([ (0, utils_2.staticClassName)('Medias', theme) && [ 'onesy-Medias-wrapper', 'onesy-Medias-wrapper-other' ], WrapperProps === null || WrapperProps === void 0 ? void 0 : WrapperProps.className, classes.wrapper, classes[`otherWrapper_size_${size}`] ]) }, { children: [(0, jsx_runtime_1.jsxs)(Line, Object.assign({}, OtherProps, item === null || item === void 0 ? void 0 : item.props, { align: 'center', justify: 'center', onClick: () => onOpenMedia(media), fullWidth: true, className: (0, style_react_1.classNames)([ (0, utils_2.staticClassName)('Medias', theme) && [ 'onesy-Medias-item', 'onesy-Medias-item-other' ], OtherProps === null || OtherProps === void 0 ? void 0 : OtherProps.className, (_f = item === null || item === void 0 ? void 0 : item.props) === null || _f === void 0 ? void 0 : _f.className, classes.item, classes.other, classes[`other_size_${size}`] ]) }, { children: [(0, jsx_runtime_1.jsx)(Interaction, {}), (0, jsx_runtime_1.jsx)(IconDocument, { size: size === 'large' ? 44 : size === 'regular' ? 34 : 24 })] }), index), name] }), index)); } return null; }; const usable = show.filter(item => { var _a; return (!!((_a = items[item]) === null || _a === void 0 ? void 0 : _a.length) && !!items[item].map((itemMedia, indexItemMedia) => getItem(item, itemMedia, indexItemMedia)).filter(Boolean).length); }); if (!(usable === null || usable === void 0 ? void 0 : usable.length)) return null; return ((0, jsx_runtime_1.jsxs)(Line, Object.assign({ ref: (item) => { if (ref) { if ((0, utils_1.is)('function', ref)) ref(item); else ref.current = item; } refs.root.current = item; }, gap: size === 'large' ? 3 : size === 'regular' ? 2 : 1.5, fullWidth: true, className: (0, style_react_1.classNames)([ (0, utils_2.staticClassName)('Medias', theme) && [ 'onesy-Medias-root', `onesy-Medias-size-${size}` ], className, classes.root ]) }, other, { children: [usable.map(item => ((0, jsx_runtime_1.jsx)(Line, Object.assign({ gap: size === 'large' ? 2 : size === 'regular' ? 1.5 : 1, direction: item === 'embed' ? 'column' : 'row', align: item === 'embed' ? 'center' : 'flex-start', justify: item === 'embed' ? 'center' : 'flex-start', fullWidth: true }, ItemsProps, (item === 'embed' && EmbedItemsProps), (item === 'image' && ImageItemsProps), (item === 'audio' && AudioItemsProps), (item === 'video' && VideoItemsProps), (item === 'other' && OtherItemsProps), { className: (0, style_react_1.classNames)([ (0, utils_2.staticClassName)('Medias', theme) && [ 'onesy-Medias-items', `onesy-Medias-items-${item}` ], ItemsProps === null || ItemsProps === void 0 ? void 0 : ItemsProps.className, item === 'embed' && (EmbedItemsProps === null || EmbedItemsProps === void 0 ? void 0 : EmbedItemsProps.className), item === 'image' && (ImageItemsProps === null || ImageItemsProps === void 0 ? void 0 : ImageItemsProps.className), item === 'audio' && (AudioItemsProps === null || AudioItemsProps === void 0 ? void 0 : AudioItemsProps.className), item === 'video' && (VideoItemsProps === null || VideoItemsProps === void 0 ? void 0 : VideoItemsProps.className), item === 'other' && (OtherItemsProps === null || OtherItemsProps === void 0 ? void 0 : OtherItemsProps.className), classes.items ]) }, { children: items[item].map((itemMedia, indexItemMedia) => getItem(item, itemMedia, indexItemMedia)) }), item))), refs.root.current && imageGallery && !!((_a = items.image) === null || _a === void 0 ? void 0 : _a.length) && ((0, jsx_runtime_1.jsx)(Portal, Object.assign({ element: (_c = (_b = refs.root.current) === null || _b === void 0 ? void 0 : _b.ownerDocument) === null || _c === void 0 ? void 0 : _c.body }, { children: (0, jsx_runtime_1.jsx)(ImageGallery, { open: !!open, onClose: onClose, value: open === null || open === void 0 ? void 0 : open.index, items: items.image.map(item => (Object.assign(Object.assign({}, item.value), { url: item.value.url || item.value.urlSmall, urlSmall: item.value.urlSmall || item.value.url }))) }) })))] }))); }); Medias.displayName = 'onesy-Medias'; exports.default = Medias;