UNPKG

@equinor/eds-core-react

Version:

The React implementation of the Equinor Design System

84 lines (81 loc) 3.01 kB
import { forwardRef, useState, useRef, useEffect } from 'react'; import styled, { css, ThemeProvider } from 'styled-components'; import { snackbar } from './Snackbar.tokens.js'; import { spacingsTemplate, bordersTemplate, typographyTemplate, useToken } from '@equinor/eds-utils'; import { jsx } from 'react/jsx-runtime'; import { Paper } from '../Paper/Paper.js'; import { useEds } from '../EdsProvider/eds.context.js'; const PopoverDiv = styled('div').withConfig({ shouldForwardProp: () => true //workaround to avoid warning until popover gets added to react types , displayName: "Snackbar__PopoverDiv", componentId: "sc-ac6no8-0" })(({ theme, $placement }) => { return css(["inset:unset;border:0;overflow:visible;position:fixed;padding:0;background-color:transparent;", " &::backdrop{background-color:transparent;}"], { top: $placement.includes('top') ? theme.spacings.top : $placement === 'left' || $placement === 'right' ? '50%' : undefined, bottom: $placement.includes('bottom') ? theme.spacings.bottom : undefined, right: $placement.includes('right') ? theme.spacings.right : undefined, left: $placement.includes('left') ? theme.spacings.left : $placement === 'top' || $placement === 'bottom' ? '50%' : undefined, transform: $placement === 'left' || $placement === 'right' ? 'translateY(-50%)' : $placement === 'top' || $placement === 'bottom' ? 'translateX(-50%)' : undefined }); }); const StyledSnackbar = styled(Paper).withConfig({ displayName: "Snackbar__StyledSnackbar", componentId: "sc-ac6no8-1" })(({ theme }) => { return css(["background-color:", ";", " ", " ", " min-height:", ";box-sizing:border-box;a,button{color:", ";}"], theme.background, spacingsTemplate(theme.spacings), bordersTemplate(theme.border), typographyTemplate(theme.typography), theme.minHeight, theme.entities.button.typography.color); }); const Snackbar = /*#__PURE__*/forwardRef(function Snackbar({ open = false, autoHideDuration = 7000, onClose, placement = 'bottom', children, ...rest }, ref) { const [visible, setVisible] = useState(open); const timer = useRef(); useEffect(() => { setVisible(open); if (open) { timer.current = setTimeout(() => { setVisible(false); if (onClose) { onClose(); } }, autoHideDuration); } return () => clearTimeout(timer.current); // eslint-disable-next-line react-hooks/exhaustive-deps }, [open, autoHideDuration]); const props = { ref, ...rest }; const { density } = useEds(); const token = useToken({ density }, snackbar); return /*#__PURE__*/jsx(ThemeProvider, { theme: token, children: visible && /*#__PURE__*/jsx(PopoverDiv, { popover: "manual", $placement: placement, ref: el => el?.showPopover(), children: /*#__PURE__*/jsx(StyledSnackbar, { role: "alert", elevation: "overlay", ...props, children: children }) }) }); }); export { Snackbar };