Skip to content

Commit

Permalink
feat: add loading bar to toast (#1346)
Browse files Browse the repository at this point in the history
* feat: add loading bar to toast

* fix: cleanup css and simplify

* fix: change type of status card tone

* Delete package-lock.json

* fix: reduce height of lading bar, add animation fill mode
  • Loading branch information
ninaandal authored Jun 17, 2024
1 parent 4e6051b commit 06f9107
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 16 deletions.
61 changes: 61 additions & 0 deletions src/core/components/toast/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import {styled, keyframes, css} from 'styled-components'
import {ThemeColorStateToneKey, getTheme_v2} from '../../../theme'
import {POPOVER_MOTION_CONTENT_OPACITY_PROPERTY} from '../../constants'
import {Flex} from '../../primitives'
import {ThemeProps} from '../../styles'

export const TextBox = styled(Flex)`
overflow-x: auto;
`

const loadingAnimation = keyframes`
0% {
width: 0;
}
100% {
width: 100%;
}
`

const LOADING_BAR_HEIGHT = 2

export function rootStyles(
props: {$duration?: number; tone: ThemeColorStateToneKey} & ThemeProps,
): ReturnType<typeof css> {
const {color} = getTheme_v2(props.theme)

const loadingBarColor = color.button.default[props.tone].enabled.bg

if (!props.$duration)
return css`
pointer-events: all;
& > * {
opacity: var(${POPOVER_MOTION_CONTENT_OPACITY_PROPERTY}, 1);
will-change: opacity;
}
`

return css`
pointer-events: all;
width: 100%;
position: relative;
overflow: hidden;
overflow: clip;
padding-bottom: ${LOADING_BAR_HEIGHT}px;
&::before {
content: '';
position: absolute;
bottom: 0px;
height: ${LOADING_BAR_HEIGHT}px;
background: ${loadingBarColor};
animation-name: ${loadingAnimation};
animation-duration: ${props.$duration}ms;
animation-fill-mode: both;
}
& > * {
opacity: var(${POPOVER_MOTION_CONTENT_OPACITY_PROPERTY}, 1);
will-change: opacity;
}
`
}
27 changes: 11 additions & 16 deletions src/core/components/toast/toast.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import {CloseIcon} from '@sanity/icons'
import {ThemeColorToneKey} from '@sanity/ui/theme'
import {ThemeColorStateToneKey} from '@sanity/ui/theme'
import {styled} from 'styled-components'
import {POPOVER_MOTION_CONTENT_OPACITY_PROPERTY} from '../../constants'
import {Box, Button, Card, Flex, Stack, Text} from '../../primitives'
import {Box, Button, Flex, Stack, Text, Card} from '../../primitives'
import {ThemeProps} from '../../styles'
import type {ButtonTone} from '../../types'
import {rootStyles, TextBox} from './styles'

/**
* @public
Expand All @@ -15,9 +16,10 @@ export interface ToastProps {
radius?: number | number[]
title?: React.ReactNode
status?: 'error' | 'warning' | 'success' | 'info'
duration?: number
}

const STATUS_CARD_TONE: {[key: string]: ThemeColorToneKey} = {
const STATUS_CARD_TONE: {[key: string]: ThemeColorStateToneKey} = {
error: 'critical',
warning: 'caution',
success: 'positive',
Expand All @@ -38,17 +40,9 @@ const ROLES = {
info: 'alert',
} as const

const Root = styled(Card)`
pointer-events: all;
& > * {
opacity: var(${POPOVER_MOTION_CONTENT_OPACITY_PROPERTY}, 1);
will-change: opacity;
}
`

const TextBox = styled(Flex)`
overflow-x: auto;
`
const Root = styled(Card)<{$duration?: number; tone: ThemeColorStateToneKey} & ThemeProps>(
rootStyles,
)

/**
* The `Toast` component gives feedback to users when an action has taken place.
Expand All @@ -60,7 +54,7 @@ const TextBox = styled(Flex)`
export function Toast(
props: ToastProps & Omit<React.HTMLProps<HTMLDivElement>, 'as' | 'height' | 'ref' | 'title'>,
): React.ReactElement {
const {closable, description, onClose, radius = 3, title, status, ...restProps} = props
const {closable, description, duration, onClose, radius = 3, title, status, ...restProps} = props
const cardTone = status ? STATUS_CARD_TONE[status] : 'default'
const buttonTone = status ? BUTTON_TONE[status] : 'default'
const role = status ? ROLES[status] : 'status'
Expand All @@ -74,6 +68,7 @@ export function Toast(
radius={radius}
shadow={2}
tone={cardTone}
$duration={duration}
>
<Flex align="flex-start">
<TextBox flex={1} padding={3}>
Expand Down
1 change: 1 addition & 0 deletions src/core/components/toast/toastProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ export function ToastProvider(props: ToastProviderProps): React.ReactElement {
onClose={dismiss}
status={params.status}
title={params.title}
duration={params.duration}
/>
</motion.div>
))}
Expand Down

0 comments on commit 06f9107

Please sign in to comment.