UNPKG

@hhgtech/hhg-components

Version:
833 lines (797 loc) • 37.5 kB
'use strict'; var React = require('react'); var index$2 = require('./index-3424862e.js'); var styled = require('@emotion/styled'); var miscTheme = require('./miscTheme.js'); var index = require('./index-d4ad3f79.js'); var index$1 = require('./index-9301f298.js'); var tslib_es6 = require('./tslib.es6-af09a0ba.js'); var index$6 = require('./index-ec32050c.js'); var index$5 = require('./index-0a047edc.js'); var core = require('@mantine/core'); var number = require('./number-76ce8f12.js'); var index$3 = require('./index-2b476eb9.js'); var hooks = require('@mantine/hooks'); var index$4 = require('./index-47ec78f0.js'); var index$7 = require('./index-512cb84a.js'); var constantsDomainLocales = require('./constantsDomainLocales.js'); var core$1 = require('@hhgtech/icons/core'); var Cookies = require('js-cookie'); var utils = require('./utils-5e3a8440.js'); function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; } var React__default = /*#__PURE__*/_interopDefault(React); var styled__default = /*#__PURE__*/_interopDefault(styled); var Cookies__default = /*#__PURE__*/_interopDefault(Cookies); const ALLOW_DOMAIN_URL = [ 'hellobacsi.com', 'hellosehat.com', 'hellodoktor.com', 'hellokrupet.com', 'hellodoctor.com.ph', 'hellokhunmor.com', 'hellosayarwon.com', 'helloyishi.com.tw', 'helloswasthya.com', 'hellojiankang.com', 'marrybaby.vn', 'hellohealth.questionpro.com', 'hellobacsivn.page.link', ]; const isInternalLink = (url = '') => { return ALLOW_DOMAIN_URL.some((o) => new URL(url).origin.endsWith(o)); }; const StyledLanguageChangeLink = styled__default["default"].a ` display: inline-flex; position: relative; flex-direction: row; align-items: center; padding: 7px 11px; gap: 2px; background: ${miscTheme.theme.colors.white}; border: 1px solid ${miscTheme.theme.colors.neutral100}; border-radius: 20px; color: ${miscTheme.theme.colors.gray600}; font-weight: 600; font-size: 12px; line-height: 18px; text-decoration: none; cursor: pointer; `; const StyledSelectionContainer = styled__default["default"].div ` position: relative; display: inline-block; `; const StyledSelectionLabel = styled__default["default"].div ` position: relative; `; const StyleSelectionPopup = styled__default["default"].div ` position: absolute; z-index: 21; top: 100%; right: 0; width: 327px; padding: 8px; background: white; border-radius: 4px; filter: drop-shadow(0px 8px 40px rgba(0, 0, 0, 0.1)); &[data-is-open='false'] { display: none; } &[data-show-indicator='true'] { &:before { position: absolute; right: 11px; bottom: 100%; width: 0; height: 0; border: 0.5rem solid transparent; border-top: none; border-bottom-color: #fff; content: ''; filter: drop-shadow(0 -0.0625rem 0.0625rem rgba(0, 0, 0, 0.1)); } } `; const StyledOption = styled__default["default"].div ` display: flex; height: 40px; align-items: center; justify-content: space-between; padding: 0 16px; border-radius: ${miscTheme.theme.borderRadius}; cursor: pointer; .check-icon { width: 16px; height: 16px; } &[data-selected='false'] { background-color: ${miscTheme.theme.colors.gray100}; } `; const StyledPopupBackground = styled__default["default"].div ` position: fixed; z-index: 20; top: 0; left: 0; width: 100%; height: 100%; cursor: default; `; const TooltipSelection = ({ options, label, labelRenderer, selected, onChange, showSelected = true, style = {}, showIndicator = true, }) => { const [isOpen, setIsOpen] = React.useState(false); return (React__default["default"].createElement(React__default["default"].Fragment, null, React__default["default"].createElement(StyledSelectionContainer, null, React__default["default"].createElement(StyledSelectionLabel, { onClick: () => setIsOpen((value) => !value) }, label || (labelRenderer === null || labelRenderer === void 0 ? void 0 : labelRenderer(isOpen)) || null, React__default["default"].createElement(StyleSelectionPopup, { "data-is-open": isOpen, style: style, "data-show-indicator": showIndicator }, options.map((option, index$2) => (React__default["default"].createElement(StyledOption, { key: index$2, "data-selected": showSelected && selected === option.value, onClick: (e) => { if (selected !== option.value) { onChange(option.value); setIsOpen((value) => !value); } e.stopPropagation(); } }, React__default["default"].createElement(index.Text, { size: "p3" }, option.label), showSelected && selected === option.value && (React__default["default"].createElement("img", { src: index$1.CommonGAssets.getAssetPath('check.svg'), alt: "check", className: "check-icon", loading: "lazy" })))))))), isOpen && (React__default["default"].createElement(StyledPopupBackground, { onClick: () => setIsOpen(false) })))); }; const LanguageSwitcher = ({ languageOptions, locale }) => { var _a, _b; const selectedLanguage = languageOptions === null || languageOptions === void 0 ? void 0 : languageOptions.find((option) => option.locale === locale); if (!(languageOptions === null || languageOptions === void 0 ? void 0 : languageOptions.length)) { return null; } return (React__default["default"].createElement(TooltipSelection, { options: languageOptions, selected: selectedLanguage.value, label: React__default["default"].createElement(LanguageLabel, { locale: locale, label: selectedLanguage.label || ((_b = (_a = locale.split('-')) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.toUpperCase()) }), onChange: (href) => { if (typeof window !== 'undefined') { window.location.href = href; } }, style: { width: 100 }, showSelected: true, showIndicator: false })); }; const LanguageLabel = ({ locale, label, href, }) => { var _a, _b, _c; return (React__default["default"].createElement(StyledLanguageChangeLink, { href: href }, React__default["default"].createElement(index$2.Flag, { country: (_b = (_a = locale === null || locale === void 0 ? void 0 : locale.split('-')) === null || _a === void 0 ? void 0 : _a[1]) === null || _b === void 0 ? void 0 : _b.toUpperCase(), width: 16, height: 16, rounded: true, language: (_c = locale === null || locale === void 0 ? void 0 : locale.split('-')) === null || _c === void 0 ? void 0 : _c[0] }), React__default["default"].createElement("span", null, label))); }; var useStyles$1 = core.createStyles((theme, { layout, useSquareRatioThumbnail, radius }) => { const itemRadius = radius !== null && radius !== void 0 ? radius : 4; return { root: { display: 'block', transition: 'all .3s ease', '&, & *': { borderRadius: itemRadius, }, [theme.fn.largerThan('sm')]: { '&:hover': Object.assign(Object.assign({}, (layout === 'overlay' && { '.overlay-info': { transform: 'translateY(-10px)', }, })), { '.item-overlay-wrapper': { backgroundColor: 'rgba(0,0,0,0.4)', } }), }, }, inner: Object.assign({ display: 'flex', gap: 8, '&, *': { pointerEvents: 'none !important', } }, (layout === 'horizon' ? { gap: 16, alignItems: 'center', } : { flexDirection: 'column', })), itemThumbImg: { width: '100%', height: '100%', objectFit: 'cover', }, thumbFrame: { backgroundColor: '#000', }, thumbWrapper: Object.assign({}, (layout === 'horizon' && Object.assign(Object.assign({}, (!useSquareRatioThumbnail && { width: 64, })), { flexShrink: 0 }))), overlayWrapper: { transition: 'all .3s ease' }, overlay: { position: 'absolute', left: 0, bottom: 0, right: 0, backgroundImage: 'linear-gradient(180deg, rgba(17, 17, 17, 0) 0%, #111111 100%)', minHeight: 96, padding: '16px 12px', display: 'flex', alignItems: 'flex-end', }, overlayInfo: { transition: 'all .3s ease', }, title: Object.assign({}, (layout === 'overlay' && { color: '#fff', })), subTitle: Object.assign({ span: { margin: '0 4px', position: 'relative', color: '#595959', '&:before': { content: '"."', position: 'absolute', top: -5, fontSize: '14px', }, } }, (layout === 'overlay' && { color: '#fff', })), }; }); const VIDEO_THUMBNAIL_RATIO = 16 / 9; const SHORT_THUMBNAIL_RATIO = 240 / 431; function secondsTo24HoursFormat(sec_num = 0) { const hours = Math.floor(sec_num / 3600); const minutes = Math.floor((sec_num - hours * 3600) / 60); const seconds = sec_num - hours * 3600 - minutes * 60; let hoursStr = String(hours); let minutesStr = String(minutes); let secondsStr = String(seconds); if (hours < 10) { hoursStr = '0' + hours; } if (minutes < 10) { minutesStr = '0' + minutes; } if (seconds < 10) { secondsStr = '0' + seconds; } return (hours > 0 ? hoursStr + ':' : '') + minutesStr + ':' + secondsStr; } function buildVideoSubtitle({ totalView, createTime, formatTotalView, }) { return [ typeof totalView === 'number' ? formatTotalView(totalView) : null, createTime, ] .filter(Boolean) .join('<span class="divider">&nbsp;</span>'); } const ShortsItem = (_a) => { var { data, layout, styles, loading = false, radius = 4, hideInfo = false, useSquareRatioThumbnail } = _a, boxProps = tslib_es6.__rest(_a, ["data", "layout", "styles", "loading", "radius", "hideInfo", "useSquareRatioThumbnail"]); const { title, totalView, imageMedium, createTime } = data; const { classes, cx } = useStyles$1({ layout, useSquareRatioThumbnail, radius }, { name: 'VideoItem__ShortsItem', styles, }); const thumbnailRatio = useSquareRatioThumbnail ? VIDEO_THUMBNAIL_RATIO : SHORT_THUMBNAIL_RATIO; const { t } = index$3.useTranslations(); const subTitle = React.useMemo(() => buildVideoSubtitle({ totalView, createTime, formatTotalView: (view) => t('common.totalView', { number: number.abbreviateNumber(view), }), }), [createTime, t, totalView]); const subTitleVisible = Boolean(subTitle); const shouldRenderInfo = !hideInfo && (loading || Boolean(title) || subTitleVisible); const infoElement = (React__default["default"].createElement(core.Stack, { spacing: 4, className: cx(classes.overlayInfo, 'overlay-info') }, React__default["default"].createElement(core.Box, { sx: { position: 'relative', minHeight: loading && !title ? core.rem(44) : undefined, } }, React__default["default"].createElement(index.Text, { size: "s3", className: cx(classes.title), lineClamp: 2, sx: { visibility: loading && title ? 'hidden' : 'visible', } }, title), loading && (React__default["default"].createElement(core.Box, { sx: { position: 'absolute', left: 0, right: 0, top: 0, display: 'flex', flexDirection: 'column', gap: 4, } }, React__default["default"].createElement(core.Skeleton, { height: 22, radius: "sm" }), React__default["default"].createElement(core.Skeleton, { height: 22, radius: "sm" })))), (subTitleVisible || loading) && (React__default["default"].createElement(core.Box, { sx: { position: 'relative', minHeight: loading && !subTitleVisible ? core.rem(16) : undefined, } }, subTitleVisible && (React__default["default"].createElement(index.Text, { className: classes.subTitle, size: "n1", sx: { visibility: loading ? 'hidden' : 'visible', }, dangerouslySetInnerHTML: { __html: subTitle, } })), loading && (React__default["default"].createElement(core.Box, { sx: { position: 'absolute', left: 0, top: 0, right: 0, } }, React__default["default"].createElement(core.Skeleton, { height: 16, width: "55%", radius: "sm" }))))))); return (React__default["default"].createElement(core.Box, Object.assign({}, boxProps, { className: classes.root }), React__default["default"].createElement(core.Box, { className: classes.inner }, React__default["default"].createElement("div", { className: classes.thumbWrapper }, React__default["default"].createElement(core.AspectRatio, { ratio: thumbnailRatio, className: classes.thumbFrame }, React__default["default"].createElement(core.Box, { sx: { position: 'relative', width: '100%', height: '100%' } }, React__default["default"].createElement("img", { src: imageMedium || '', className: classes.itemThumbImg, alt: title, loading: "lazy", style: { visibility: loading ? 'hidden' : 'visible', } }), loading && (React__default["default"].createElement(core.Box, { sx: { position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, borderRadius: radius, overflow: 'hidden', zIndex: 1, } }, React__default["default"].createElement(core.Skeleton, { height: "100%", radius: "sm", sx: { display: 'block', lineHeight: 1 } })))), React__default["default"].createElement(core.Box, { className: cx(classes.overlayWrapper, 'item-overlay-wrapper') }, React__default["default"].createElement(core.Box, { className: cx(classes.overlay, 'item-overlay') }, layout === 'overlay' && shouldRenderInfo && infoElement)))), layout !== 'overlay' && shouldRenderInfo && infoElement))); }; const Play = (_a) => { var { size = 24, color = miscTheme.theme.colors.neutral600 } = _a, rest = tslib_es6.__rest(_a, ["size", "color"]); return (React__default["default"].createElement("svg", Object.assign({ width: size, height: size, viewBox: "0 0 47 48", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, rest), React__default["default"].createElement("path", { d: "M23.297 43.153c10.55 0 19.103-8.64 19.103-19.298S33.847 4.557 23.297 4.557 4.193 13.197 4.193 23.855s8.553 19.298 19.104 19.298", fill: color, fillOpacity: ".75" }), React__default["default"].createElement("path", { d: "m19.477 16.136 11.462 7.719-11.462 7.72z", fill: "#fff", stroke: "#fff", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round" }))); }; var useStyles = core.createStyles((theme, { active, layout, radius }) => { const itemRadius = radius !== null && radius !== void 0 ? radius : 4; return { root: { display: 'block', borderRadius: itemRadius, [theme.fn.largerThan('sm')]: { '&:hover': { [`.${core.getStylesRef('overlay')}`]: Object.assign({}, (!active && { backgroundColor: 'rgba(0, 0, 0, .4)', })), }, }, }, inner: Object.assign(Object.assign({ display: 'flex', gap: 8, '&, *': { pointerEvents: 'none !important', } }, (layout === 'default' && { flexDirection: 'column', })), (layout === 'horizon' && { gap: 12, [theme.fn.largerThan('sm')]: { gap: 24, }, })), thumb: Object.assign({}, (layout === 'horizon' && { width: 140, flexShrink: 0, [theme.fn.largerThan('sm')]: { width: 164, }, })), thumbWrapper: {}, thumbFrame: {}, thumbImage: { width: '100%', height: '100%', objectFit: 'cover', }, title: { lineHeight: core.rem(22), }, subTitle: { span: { margin: '0 4px', position: 'relative', '&:before': { content: '"."', position: 'absolute', top: -5, fontSize: '14px', }, }, }, overlay: { ref: core.getStylesRef('overlay'), position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, backgroundColor: active ? 'rgba(0, 0, 0, .55)' : 'transparent', transition: 'all .2s ease', '.play-icon path': { '&:first-child': { fill: '#262626', }, }, }, duration: { position: 'absolute', zIndex: 0, background: '#262626', borderRadius: itemRadius, bottom: 4, right: 4, padding: `${core.rem(1)} ${core.rem(4)}`, }, durationTxt: { color: '#fff', }, }; }); const VideoItem$1 = (_a) => { var { isMobile, data, styles, className, classNames, layout, radius = 4, playIcon, hideInfo = false, loading = false } = _a, boxProps = tslib_es6.__rest(_a, ["isMobile", "data", "styles", "className", "classNames", "layout", "radius", "playIcon", "hideInfo", "loading"]); const { title, imageMedium, createTime, totalView, active, duration } = data; const { locale, t } = index$3.useTranslations(); const { cx, classes, theme } = useStyles({ active, layout, radius }, { name: 'VideoItem__VideoItem', classNames, styles }); const PlayIcon = playIcon || Play; const subTitle = React.useMemo(() => ({ visible: Boolean(totalView || createTime), formated: buildVideoSubtitle({ totalView, createTime, formatTotalView: (view) => t('common.totalView', { number: number.abbreviateNumber(view) }), }), }), [createTime, t, totalView]); const fallbackThumbSrc = index$1.CommonGAssets.getAssetPath(`videoThumbDefault/${locale}.jpg`); const thumbSrc = imageMedium || fallbackThumbSrc; const durationLabel = typeof duration === 'number' && duration > 0 ? secondsTo24HoursFormat(duration) : undefined; const shouldRenderVideoInfo = !hideInfo && (loading || Boolean(title) || subTitle.visible); return (React__default["default"].createElement(core.Box, Object.assign({}, boxProps, { className: cx(className, classes.root) }), React__default["default"].createElement(core.Box, { className: classes.inner }, React__default["default"].createElement(core.Box, { className: classes.thumbWrapper }, React__default["default"].createElement(core.Box, { className: classes.thumb, sx: () => ({ position: 'relative', 'div, img': { borderRadius: radius, }, }) }, React__default["default"].createElement(core.Box, { sx: { position: 'relative', width: '100%' } }, React__default["default"].createElement(core.AspectRatio, { ratio: VIDEO_THUMBNAIL_RATIO, className: classes.thumbFrame }, React__default["default"].createElement("img", { loading: "lazy", src: thumbSrc, alt: title, className: classes.thumbImage, style: { visibility: loading ? 'hidden' : 'visible', }, onError: (e) => { e.currentTarget.src = fallbackThumbSrc; } })), loading && (React__default["default"].createElement(core.Box, { sx: { position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, borderRadius: radius, overflow: 'hidden', zIndex: 2, } }, React__default["default"].createElement(core.Skeleton, { height: "100%", radius: "sm", sx: { display: 'block', lineHeight: 1 } })))), durationLabel && (React__default["default"].createElement(core.Box, { className: classes.duration, sx: { zIndex: loading ? 3 : undefined } }, React__default["default"].createElement(core.Box, { sx: { position: 'relative' } }, React__default["default"].createElement(index.Text, { size: "n1", className: classes.durationTxt, sx: { visibility: loading ? 'hidden' : 'visible', } }, durationLabel), loading && (React__default["default"].createElement(core.Box, { sx: { position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', } }, React__default["default"].createElement(core.Skeleton, { width: 40, height: 14, radius: "sm" })))))), React__default["default"].createElement(core.Flex, { className: classes.overlay, align: 'center', justify: 'center', sx: { visibility: loading ? 'hidden' : 'visible', } }, active ? (React__default["default"].createElement(index.Text, { size: "s3", weight: "semiBold", color: "#fff" }, t('common.playing'))) : (React__default["default"].createElement(PlayIcon, { className: "play-icon", size: isMobile ? 32 : 46 }))))), shouldRenderVideoInfo && (React__default["default"].createElement(core.Stack, { className: "video-info", sx: { [theme.fn.largerThan('sm')]: { gap: 4 }, gap: 2 } }, React__default["default"].createElement(core.Box, { sx: { position: 'relative', minHeight: loading && !title ? core.rem(44) : undefined, } }, React__default["default"].createElement(index.Text, { className: classes.title, size: "s3", color: active ? theme.fn.primaryColor() : '#262626', weight: "semiBold", lineClamp: 2, sx: { visibility: loading && title ? 'hidden' : 'visible', } }, title), loading && (React__default["default"].createElement(core.Box, { sx: { position: 'absolute', left: 0, right: 0, top: 0, display: 'flex', flexDirection: 'column', gap: 4, } }, React__default["default"].createElement(core.Skeleton, { height: 22, radius: "sm" }), React__default["default"].createElement(core.Skeleton, { height: 22, radius: "sm" })))), (subTitle.visible || loading) && (React__default["default"].createElement(core.Box, { sx: { position: 'relative', minHeight: loading && !subTitle.visible ? core.rem(16) : undefined, } }, subTitle.visible && (React__default["default"].createElement(index.Text, { className: classes.subTitle, size: "n1", color: "#595959", sx: { visibility: loading ? 'hidden' : 'visible', }, dangerouslySetInnerHTML: { __html: subTitle.formated, } })), loading && (React__default["default"].createElement(core.Box, { sx: { position: 'absolute', left: 0, top: 0, right: 0, } }, React__default["default"].createElement(core.Skeleton, { height: 16, width: "55%", radius: "sm" })))))))))); }; const VideoPlayerModal = (_a) => { var { data, isMobile } = _a, rest = tslib_es6.__rest(_a, ["data", "isMobile"]); const { type, url } = data; const os = hooks.useOs(); const isIos = os === 'ios'; return (React__default["default"].createElement(index$4.Modal, Object.assign({ size: type === index$5.VideoType.SHORTS ? (isMobile ? 360 : 375) : core.rem(1128), withCloseButton: true, styles: (theme) => ({ header: { padding: 0, paddingBottom: 8, backgroundColor: 'transparent', border: 0, [theme.fn.smallerThan('sm')]: { position: 'absolute', top: 10, right: 10, }, }, body: { padding: 0, }, content: { boxShadow: 'none', backgroundColor: 'transparent', borderRadius: 0, [theme.fn.largerThan('sm')]: { position: 'relative', }, }, heading: { [theme.fn.smallerThan('sm')]: {}, }, inner: { zIndex: index$6.ZINDEX_HEADER + 2, [theme.fn.smallerThan('sm')]: { padding: 0, }, }, close: { color: '#fff', backgroundColor: '#000', borderRadius: '50%', width: 24, height: 24, display: 'flex', justifyContent: 'center', alignItems: 'center', transition: 'all .3s ease', svg: { width: '18px !important', height: '18px !important', }, '&:hover': { backgroundColor: '#fff', color: '#000', }, }, overlay: { zIndex: index$6.ZINDEX_HEADER + 1, [theme.fn.smallerThan('sm')]: { backgroundColor: 'rgba(0, 0, 0, 0.85)', }, }, }) }, rest), React__default["default"].createElement(index$7.SocialLinkPreview, { key: url, url: url || '', autoPlay: !isIos, isShort: type === index$5.VideoType.SHORTS, autoScaleByVideoType: true }))); }; const VideoItem = React.forwardRef((_a, ref) => { var { data, layout = 'default', disableDefaultFn, redirectToLandingPage, onClick, dataEventCategory, dataEventAction, isMobile, loading, hideInfo = false } = _a, props = tslib_es6.__rest(_a, ["data", "layout", "disableDefaultFn", "redirectToLandingPage", "onClick", "dataEventCategory", "dataEventAction", "isMobile", "loading", "hideInfo"]); const { articleLink, id, videoId, title, url, type } = data; const [showModal, setShowModal] = React.useState(false); const href = articleLink || `/videos/${type}/?id=${id}`; const { locale } = index$3.useTranslations(); const dataEventLabel = React.useMemo(() => `https://${constantsDomainLocales.domainLocales[locale]}${href}`, [href, locale]); const persistVideoDetailForLanding = () => { localStorage.setItem(index$6.VIDEO_DETAIL_TEMP_STORAGE, JSON.stringify({ articleLink, id, videoId, title, url, type, })); }; const handleDefaultClick = (e) => { if (redirectToLandingPage) { persistVideoDetailForLanding(); return; } e.preventDefault(); setShowModal(true); }; React.useImperativeHandle(ref, () => ({ open: () => { if (articleLink) return; if (redirectToLandingPage) { persistVideoDetailForLanding(); return; } setShowModal(true); }, close: () => setShowModal(false), }), [articleLink, redirectToLandingPage, id, videoId, title, url, type]); const commonProps = { component: 'a', href, target: articleLink ? '_blank' : '_self', 'data-event-category': dataEventCategory, 'data-event-action': dataEventAction, 'data-event-label': dataEventLabel, onClick: disableDefaultFn ? onClick : !articleLink ? handleDefaultClick : undefined, }; return (React__default["default"].createElement(React__default["default"].Fragment, null, type === index$5.VideoType.SHORTS ? (React__default["default"].createElement(ShortsItem, Object.assign({}, props, commonProps, { data: data, layout: layout, isMobile: isMobile, loading: loading, hideInfo: hideInfo }))) : (React__default["default"].createElement(VideoItem$1, Object.assign({}, props, commonProps, { layout: layout, data: data, isMobile: isMobile, loading: loading, hideInfo: hideInfo }))), !articleLink && (React__default["default"].createElement(VideoPlayerModal, { opened: Boolean(showModal), data: data, onClose: () => setShowModal(false), isMobile: isMobile })))); }); VideoItem.displayName = 'VideoItem'; const siteWideBg = index$1.CommonGAssets.getAssetPath('sitewide/vn-public-desktop.png'); const StyledsiteWideContainer = styled__default["default"].div ` position: relative; display: flex; overflow: hidden; align-items: center; background-color: ${(props) => props.bgColor || '#284a75'}; background-position: center; background-size: cover; transition: height 0.25s; &[data-is-mobile='true'] { justify-content: flex-start; } &[data-is-mobile='false'] { justify-content: center; } &[data-is-collapse='false'] { height: 64px; } &[data-is-collapse='true'] { height: 0; } ${utils.MediaQueries.mbDown} { &[data-is-collapse='false'] { height: 48px; } } &[data-is-vn-public-day='true'] { background-color: ${miscTheme.theme.colors.red900}; ${utils.MediaQueries.mbDown} { overflow: hidden; } ${utils.MediaQueries.mbUp} { background-image: url(${siteWideBg}); background-repeat: no-repeat; background-size: cover; .vn-bg { display: none; } } } .banner-full { object-fit: cover; height: 100%; } & > a { display: flex; width: 100%; height: 100%; align-items: center; justify-content: center; text-decoration: none; } > a + .site-wide-content { width: 100%; } .content { padding-right: 48px; color: white; a { color: white; } &[data-is-mobile='true'] { font-size: 14px; } ${utils.MediaQueries.mbDown} { line-height: 18px; } } .close-icon { position: absolute; right: 0px; width: 64px; height: 64px; padding: 0 20px; cursor: pointer; } [data-event-category] { * { pointer-events: none !important; } } `; const StyledIcon = styled__default["default"].div ` max-width: 100px; margin-right: 16px; .image-wrapper { display: inline-block; overflow: hidden; max-width: 100px; padding: 8px 0 4px 16px; img { width: 64px; height: 64px; object-fit: contain; &[data-is-mobile='true'] { width: 52px; height: 52px; } } } `; const SITE_WIDE_EXPIRES = { daily: 1, weekly: 7, 'bi-weekly': 14, }; const SiteWideBanner = ({ site = 'discover', banner, isMobile, onClose, currentUrl, }) => { var _a; const { link, icon, content, type, layoutType, bannerDesktop, bannerMobile, backgroundColor, bannerDisplayFrequency, } = banner || {}; const [show, setShow] = React.useState(true); const formattedContent = content; const cookieName = React.useMemo(() => `${site}-disable-sitewide-${type}`, [type]); const handleCLoseSitewide = React.useCallback((event) => { event.preventDefault(); Cookies__default["default"].set(cookieName, 'true', { expires: SITE_WIDE_EXPIRES[bannerDisplayFrequency], }); setShow(false); onClose === null || onClose === void 0 ? void 0 : onClose(); }, [currentUrl, cookieName, bannerDisplayFrequency]); const dataVarsEventLabel = (_a = /<a[^>]*href=["']([^"']*)["']/g.exec(formattedContent)) === null || _a === void 0 ? void 0 : _a[1]; // TODO: Remove useEffect and use the value directly // --> as the useEffect cause flickering React.useEffect(() => { if (Cookies__default["default"].get(cookieName) === 'true') { setShow(false); } }, [banner === null || banner === void 0 ? void 0 : banner.type]); if (!formattedContent || !show) { return null; } return (React__default["default"].createElement(StyledsiteWideContainer, { "data-is-mobile": isMobile, "data-is-collapse": !show, // data-is-vn-public-day={isVNPublicDay} id: "sitewide-container", bgColor: backgroundColor }, React__default["default"].createElement("a", { className: `no-replace-click`, "data-event-category": "Header Banner", "data-event-action": "Link Click", "data-event-label": currentUrl, href: link || dataVarsEventLabel }, layoutType === 'icon-text' ? (React__default["default"].createElement(React__default["default"].Fragment, null, icon && (React__default["default"].createElement(StyledIcon, { className: "site-wide-content" }, React__default["default"].createElement("div", { className: "image-wrapper" }, React__default["default"].createElement("img", { src: icon, className: "icon", loading: "lazy", "data-is-mobile": isMobile, alt: "", width: 64, height: 64 })))), React__default["default"].createElement("div", { className: "site-wide-content" }, formattedContent && (React__default["default"].createElement(index.Text, { size: "s3", className: "content", "data-is-mobile": isMobile, dangerouslySetInnerHTML: { __html: formattedContent }, lineClamp: 2, styles: { root: { fontFamily: `${process.env.NEXT_PUBLIC_DEPLOY_LOCALE === 'km-KH' ? 'Battambang,' : process.env.NEXT_PUBLIC_DEPLOY_LOCALE === 'th-TH' ? 'Noto Sans Thai,' : 'Inter,'} -apple-system, BlinkMacSystemFont, 'Segoe UI', Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif;`, }, } }))))) : (React__default["default"].createElement("img", { src: isMobile ? bannerMobile : bannerDesktop, className: "banner-full", loading: "lazy", "data-is-mobile": isMobile, alt: "" }))), React__default["default"].createElement(core$1.Close, { color: "#fff", size: 24, className: "close-icon", "data-event-category": "Header Banner", "data-event-action": "Close Click", "data-vars-event-label": currentUrl, onClick: handleCLoseSitewide }))); }; exports.LanguageSwitcher = LanguageSwitcher; exports.SiteWideBanner = SiteWideBanner; exports.VideoItem = VideoItem; exports.VideoPlayerModal = VideoPlayerModal; exports.isInternalLink = isInternalLink;