@equinor/eds-core-react
Version:
The React implementation of the Equinor Design System
84 lines (81 loc) • 3.01 kB
JavaScript
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 };