@hhgtech/hhg-components
Version:
Hello Health Group common components
276 lines (249 loc) • 10.3 kB
JavaScript
import * as React from 'react';
import React__default, { useState, useEffect } from 'react';
import styled from '@emotion/styled';
import { theme } from './miscTheme.js';
import { I as ImageWrap } from './index-2558182c.js';
import { _ as __rest } from './tslib.es6-7984ef17.js';
import { clsx, Modal } from '@mantine/core';
import { D as DrawerComponent, u as useDrawerDrag } from './index-f7c27305.js';
import { Drawer } from 'vaul';
import { Z as ZINDEX_SSO } from './index-18cb16b6.js';
/* eslint-disable prettier/prettier */
const Pin2 = (props) => (React.createElement("svg", Object.assign({ width: "1em", height: "1em", viewBox: "0 0 12 12", fill: "none" }, props),
React.createElement("path", { d: "M10.185 4.744C10.185 6.643 7.70296 9.692 6.56096 10.994C6.26196 11.335 5.73596 11.335 5.43796 10.994C4.29696 9.693 1.81396 6.643 1.81396 4.744C1.81396 2.217 3.97696 0.75 5.99896 0.75C8.02096 0.75 10.184 2.217 10.184 4.744H10.185Z", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round" }),
React.createElement("path", { d: "M6 6C6.55228 6 7 5.55228 7 5C7 4.44772 6.55228 4 6 4C5.44772 4 5 4.44772 5 5C5 5.55228 5.44772 6 6 6Z", fill: "currentColor" })));
/* eslint-disable prettier/prettier */
const ShapedArrowDown = (props) => (React.createElement("svg", Object.assign({ width: "1em", height: "1em", viewBox: "0 0 16 16", fill: "none" }, props),
React.createElement("path", { d: "M13.5554 9.33398L7.99989 5.55621L2.44434 9.33398", stroke: "currentColor", strokeWidth: 1.2, strokeLinecap: "round", strokeLinejoin: "round" })));
const StyledAvatar = styled.div `
background-color: var(--background-color, transparent);
color: white;
cursor: pointer;
img {
--width: var(--width-prop, 40px);
--height: var(--height-prop, 40px);
width: var(--width);
height: var(--height);
}
&[data-has-max='true'] {
img {
max-width: var(--width);
max-height: var(--height);
}
}
&[data-avatar-type='square'] {
img {
--width: var(--width-prop, 72px);
--height: var(--height-prop, 72px);
border-radius: ${theme.borderRadius};
}
}
&[data-avatar-type='rounded'] {
img {
border-radius: 50%;
}
}
&[data-custom-size='true'] {
display: flex;
overflow: hidden;
overflow: hidden;
width: var(--size);
height: var(--size);
align-items: center;
justify-content: center;
background-size: cover;
font-size: calc(var(--size) / 2);
font-weight: bold;
&[data-avatar-type='square'] {
border-radius: ${theme.borderRadius};
}
&[data-avatar-type='rounded'] {
border-radius: 50%;
img {
--width: 100%;
--height: 100%;
}
}
img {
object-fit: cover;
}
}
`;
const pxBySize = {
xs: 28,
small: 32,
medium: 40,
large: 48,
xl: 64,
xxl: 80,
xxxl: 96,
};
/**
* @deprecated Consider to use at '@hhgtech/hhg-components/mantine'
*/
const Avatar = ({ type = 'square', size, avatarImg, avatarUrl, firstLetter, backgroundColor, onClick, style, className, width, height, alt, }) => {
const sizePx = size ? pxBySize[size] : undefined;
const [isImageLoadingError, setIsImageLoadingError] = useState(false);
useEffect(() => {
if (avatarUrl) {
const img = document.createElement('img');
img.setAttribute('src', avatarUrl);
img.addEventListener('error', () => {
setIsImageLoadingError(true);
});
}
}, [avatarUrl, setIsImageLoadingError]);
const shouldRenderLetter = ((!avatarUrl && !avatarImg) || isImageLoadingError) && firstLetter;
return (React__default.createElement(StyledAvatar, { style: Object.assign(Object.assign({}, style), { '--size': sizePx ? sizePx + 'px' : undefined, '--width-prop': width ? width + 'px' : undefined, '--height-prop': height ? height + 'px' : undefined, '--background-color': backgroundColor }), "data-has-max": !!(width && height), "data-avatar-type": type, onClick: onClick, className: className, avatarUrl: avatarUrl, "data-custom-size": !!size },
avatarImg,
avatarUrl && !isImageLoadingError && (React__default.createElement(ImageWrap, { src: avatarUrl, alt: alt || 'avatar' })),
shouldRenderLetter && firstLetter));
};
const DistanceTagStyled = styled.div `
display: inline-flex;
align-items: center;
gap: 4px;
padding: 4px 8px;
color: ${theme.colors.red700};
border-radius: 8px;
border: 1px solid ${theme.colors.neutral100};
font-size: 0.6875rem;
line-height: 1rem;
border-radius: 0.5rem;
`;
const StyledPin2 = styled(Pin2) `
width: 0.75rem;
height: 0.75rem;
color: ${theme.colors.gray400};
`;
const StyledSpan = styled.span `
color: ${theme.colors.gray600};
font-size: 11px;
line-height: 1rem;
`;
function DistanceTag({ value, className }) {
return (React__default.createElement(DistanceTagStyled, { className: className },
React__default.createElement(StyledPin2, null),
React__default.createElement(StyledSpan, null, value)));
}
const StyledIconWrapper = styled.div `
display: inline-flex;
align-items: center;
justify-content: center;
flex-grow: 0;
flex-shrink: 0;
width: calc(var(--wrapper-size, var(--icon-size)) * 1px);
height: calc(var(--wrapper-size, var(--icon-size)) * 1px);
&[data-clickable='true'] {
cursor: pointer;
}
> * {
width: calc(var(--icon-size) * 1px);
height: calc(var(--icon-size) * 1px);
}
&[data-svg-custom-stroke='true'] > svg * {
stroke: var(--icon-stroke-color);
}
&[data-svg-custom-fill='true'] > svg * {
fill: var(--icon-fill-color);
}
`;
/**
* Wrapper for icon
* You can use this component to wrap your icon with custom size and style
* With svgIcon you can set fill and stroke color as well
*/
const IconWrapper = ({ children, className, onClick, wrapperSize, iconSize = 24, wrapperStyle, iconStyle, svgIcon, wrapperProps, }) => {
return (React__default.createElement(StyledIconWrapper, Object.assign({ className: className, onClick: onClick, style: Object.assign(Object.assign(Object.assign(Object.assign({}, (wrapperSize && { '--wrapper-size': wrapperSize })), (iconSize && { '--icon-size': iconSize })), (svgIcon && Object.assign(Object.assign({}, (svgIcon.fill && { '--icon-fill-color': svgIcon.fill })), (svgIcon.stroke && { '--icon-stroke-color': svgIcon.stroke })))), wrapperStyle), "data-clickable": !!onClick, "data-svg-custom-stroke": !!(svgIcon === null || svgIcon === void 0 ? void 0 : svgIcon.stroke), "data-svg-custom-fill": !!(svgIcon === null || svgIcon === void 0 ? void 0 : svgIcon.fill) }, wrapperProps), React__default.cloneElement(children, {
style: iconStyle,
})));
};
styled(DrawerComponent) `
/* max-height: 100vh;
max-height: 100dvh; */
background-color: white;
&[data-vaul-drawer-direction='bottom'] {
top: initial !important;
border-top-left-radius: 16px !important;
border-top-right-radius: 16px !important;
padding-bottom: 32px;
padding-left: 20px;
padding-right: 20px;
}
.drawer__handle {
width: 44px;
height: 3px;
background-color: ${theme.colors.neutral500};
margin: 16px auto;
flex-shrink: 0;
}
`;
const StyledDrawerBottomContent = styled(Drawer.Content) `
position: fixed;
z-index: ${ZINDEX_SSO - 9e6 + 1};
inset: 0;
background-color: #fff;
outline: none !important;
&[data-is-linear='true'] {
background: linear-gradient(180deg, #c3e3ff 1.86%, #fff 20%) !important;
}
&::-webkit-scrollbar {
width: 6px;
height: 6px;
}
&::-webkit-scrollbar-track {
background-color: transparent;
}
&::-webkit-scrollbar-thumb {
background-color: rgba(0, 0, 0, 0.4);
border-radius: 6px;
}
&[data-vaul-drawer-direction='bottom'] {
top: initial;
border-top-left-radius: 16px;
border-top-right-radius: 16px;
/* padding-bottom: 16px; */
}
${(props) => props.isDragging &&
`
input {
caret-color: transparent;
}
`}
`;
const StyledDrawerBottomOverlay = styled(Drawer.Overlay) `
position: fixed;
inset: 0;
z-index: ${ZINDEX_SSO - 9e6};
width: 100%;
max-height: 100%;
background-color: rgb(0, 0, 0, 0.4);
`;
const StyledDrawerBottomHandler = styled(Drawer.Handle) `
&[data-vaul-handle] {
width: 44px;
height: 3px;
background-color: ${theme.colors.neutral500};
margin: 16px auto;
flex-shrink: 0;
}
`;
function DrawerBottom(_a) {
var { children, onClose, isOpen, onOpenChange, isMobile, classNames, isLinear, overlayClassName, contentClassName, handlerClassName } = _a, restProps = __rest(_a, ["children", "onClose", "isOpen", "onOpenChange", "isMobile", "classNames", "isLinear", "overlayClassName", "contentClassName", "handlerClassName"]);
const { isDragging, handleDragStart, handleDragEnd } = useDrawerDrag();
if (isMobile) {
return (React__default.createElement(Drawer.Root, Object.assign({ onDrag: handleDragStart, onRelease: handleDragEnd, open: isOpen, onOpenChange: onOpenChange, onClose: onClose }, restProps),
React__default.createElement(Drawer.Portal, null,
React__default.createElement(StyledDrawerBottomOverlay, { className: clsx(overlayClassName, 'drawer__overlay') }),
React__default.createElement(StyledDrawerBottomContent, { isDragging: isDragging, className: clsx(contentClassName, 'drawer__content'), "data-is-linear": isLinear },
React__default.createElement(Drawer.Title, { style: { display: 'none' } }),
React__default.createElement(StyledDrawerBottomHandler, { className: clsx(handlerClassName, 'drawer__handle') }),
children))));
}
return (React__default.createElement(Modal, Object.assign({ withCloseButton: true, centered: true, zIndex: 500, size: "auto", classNames: classNames, radius: "lg" }, restProps, { onClose: onClose, opened: isOpen, styles: {
root: {
maxHeight: '400px',
},
} }), children));
}
export { Avatar as A, DistanceTag as D, IconWrapper as I, Pin2 as P, ShapedArrowDown as S, DrawerBottom as a };