Skip to content

Commit

Permalink
πŸ’„ Snackbar: implement [popover] (#3577)
Browse files Browse the repository at this point in the history
* πŸ’„ Snackbar: implement [popover]

* fix, use useState

* fix tests, snapshot
  • Loading branch information
oddvernes authored Aug 7, 2024
1 parent 0a01dd8 commit 1ab26d2
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 26 deletions.
21 changes: 20 additions & 1 deletion packages/eds-core-react/src/components/Dialog/Dialog.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import { useState } from 'react'
import { useArgs } from '@storybook/preview-api'
import { Dialog, DialogProps, Button, Radio, Typography, Tooltip } from '../..'
import {
Dialog,
DialogProps,
Button,
Radio,
Typography,
Tooltip,
Snackbar,
} from '../..'
import styled from 'styled-components'
import { StoryFn, Meta } from '@storybook/react'
import { Stack } from './../../../.storybook/components'
Expand Down Expand Up @@ -99,6 +107,7 @@ export const Introduction: StoryFn<DialogProps> = (args) => {

export const Dismissable: StoryFn<DialogProps> = () => {
const [isOpen, setIsOpen] = useState(false)
const [snackbar, setSnackbar] = useState(false)
const handleOpen = () => {
setIsOpen(true)
}
Expand All @@ -110,6 +119,13 @@ export const Dismissable: StoryFn<DialogProps> = () => {
<Button aria-haspopup="dialog" onClick={handleOpen}>
Trigger Dialog
</Button>
<Snackbar
open={snackbar}
onClose={() => setSnackbar(false)}
autoHideDuration={2000}
>
Snackbar in front of scrim!
</Snackbar>
<Dialog open={isOpen} isDismissable onClose={handleClose}>
<Dialog.Header>
<Dialog.Title>Dismissable dialog</Dialog.Title>
Expand All @@ -118,6 +134,9 @@ export const Dismissable: StoryFn<DialogProps> = () => {
<Typography variant="body_short">
Closes dialog on click outside and escape key.
</Typography>
<Button variant="outlined" onClick={() => setSnackbar(true)}>
Show a snackbar
</Button>
</Dialog.CustomContent>
<Dialog.Actions>
<Wrapper>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,15 @@ describe('Snackbar', () => {
{message}
</Snackbar>,
)
expect(screen.getByTestId('test-snackbar-3')).toHaveStyleRule(
// eslint-disable-next-line testing-library/no-node-access
expect(screen.getByTestId('test-snackbar-3').parentElement).toHaveStyleRule(
'top',
tokens.spacings.top,
)
expect(screen.getByTestId('test-snackbar-3')).toHaveStyleRule('left', '50%')
// eslint-disable-next-line testing-library/no-node-access
expect(screen.getByTestId('test-snackbar-3').parentElement).toHaveStyleRule(
'left',
'50%',
)
})
})
51 changes: 33 additions & 18 deletions packages/eds-core-react/src/components/Snackbar/Snackbar.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { useState, useEffect, HTMLAttributes, forwardRef, useRef } from 'react'
import * as ReactDom from 'react-dom'
import { useEffect, HTMLAttributes, forwardRef, useRef, useState } from 'react'
import styled, { css, ThemeProvider } from 'styled-components'
import { snackbar as SnackbarToken } from './Snackbar.tokens'
import {
Expand All @@ -12,6 +11,7 @@ import { Paper } from '../Paper'
import { useEds } from '../EdsProvider'

type StyledProps = {
popover: string
$placement?:
| 'left'
| 'right'
Expand All @@ -23,17 +23,16 @@ type StyledProps = {
| 'bottom-right'
}

const StyledSnackbar = styled(Paper)<StyledProps>(({ theme, $placement }) => {
const PopoverDiv = styled('div').withConfig({
shouldForwardProp: () => true, //workaround to avoid warning until popover gets added to react types
})<StyledProps>(({ theme, $placement }) => {
return css`
inset: unset;
border: 0;
overflow: visible;
position: fixed;
background-color: ${theme.background};
${spacingsTemplate(theme.spacings)}
${bordersTemplate(theme.border)}
${typographyTemplate(theme.typography)}
min-height: ${theme.minHeight};
box-sizing: border-box;
z-index: 1400;
padding: 0;
background-color: transparent;
${{
top: $placement.includes('top')
? theme.spacings.top
Expand All @@ -54,7 +53,20 @@ const StyledSnackbar = styled(Paper)<StyledProps>(({ theme, $placement }) => {
? 'translateX(-50%)'
: undefined,
}}
&::backdrop {
background-color: transparent;
}
`
})

const StyledSnackbar = styled(Paper)(({ theme }) => {
return css`
background-color: ${theme.background};
${spacingsTemplate(theme.spacings)}
${bordersTemplate(theme.border)}
${typographyTemplate(theme.typography)}
min-height: ${theme.minHeight};
box-sizing: border-box;
a,
button {
color: ${theme.entities.button.typography.color};
Expand Down Expand Up @@ -107,25 +119,28 @@ export const Snackbar = forwardRef<HTMLDivElement, SnackbarProps>(
}, autoHideDuration)
}
return () => clearTimeout(timer.current)
}, [open, autoHideDuration, setVisible, onClose])
}, [open, setVisible, autoHideDuration, onClose])

const props = {
ref,
$placement: placement,
...rest,
}
const { density } = useEds()
const token = useToken({ density }, SnackbarToken)

return (
<ThemeProvider theme={token}>
{visible &&
ReactDom.createPortal(
{visible && (
<PopoverDiv
popover="manual"
$placement={placement}
ref={(el) => el?.showPopover()}
>
<StyledSnackbar role="alert" elevation="overlay" {...props}>
{children}
</StyledSnackbar>,
document.body,
)}
</StyledSnackbar>
</PopoverDiv>
)}
</ThemeProvider>
)
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ exports[`Snackbar Matches snapshot 1`] = `
}
.c1 {
position: fixed;
background-color: var(--eds_ui_background__overlay, rgba(0, 0, 0, 0.8));
padding-left: 16px;
padding-top: 16px;
Expand All @@ -23,10 +22,6 @@ exports[`Snackbar Matches snapshot 1`] = `
text-align: left;
min-height: 48px;
box-sizing: border-box;
z-index: 1400;
bottom: 16px;
left: 50%;
transform: translateX(-50%);
}
.c1 a,
Expand Down

0 comments on commit 1ab26d2

Please sign in to comment.