perf(toast): improve toast component performance

test(toast): update spanshots

style(button): remove unused
This commit is contained in:
unix
2020-05-11 20:05:25 +08:00
parent eb596f4592
commit e3ba8aed41
6 changed files with 26 additions and 31 deletions

View File

@@ -11,7 +11,7 @@ export const getButtonChildrenWithIcon = (
icons: {
icon?: React.ReactNode
iconRight?: React.ReactNode
} = {},
},
) => {
const { icon, iconRight } = icons
const hasIcon = icon || iconRight

View File

@@ -135,13 +135,13 @@ exports[`UseToast should render different actions 1`] = `
border: 0;
border-radius: 5px;
padding: 16pt;
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.12);
position: absolute;
bottom: 0;
right: 0;
opacity: 0;
opacity: 1;
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.12);
transform: translate3d(0, 100%, 0px) scale(1);
transition: all 400ms ease;
transition: transform 400ms ease 0ms, visibility 200ms ease 0ms, opacity 200ms ease 0ms;
}
.toast.visible {
@@ -193,7 +193,7 @@ exports[`UseToast should render different actions 1`] = `
`;
exports[`UseToast should work with different types 1`] = `
"<div class=\\"toast-container \\"><div class=\\"toast \\"><div class=\\"message\\">hello</div><div class=\\"action\\"></div><style>
"<div class=\\"toast-container \\"><div class=\\"toast visible \\"><div class=\\"message\\">hello</div><div class=\\"action\\"></div><style>
.toast {
width: 420px;
max-width: 90vw;
@@ -207,13 +207,13 @@ exports[`UseToast should work with different types 1`] = `
border: 0;
border-radius: 5px;
padding: 16pt;
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.12);
position: absolute;
bottom: 0;
right: 0;
opacity: 0;
opacity: 1;
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.12);
transform: translate3d(0, 100%, 0px) scale(1);
transition: all 400ms ease;
transition: transform 400ms ease 0ms, visibility 200ms ease 0ms, opacity 200ms ease 0ms;
}
.toast.visible {

View File

@@ -61,7 +61,7 @@ describe('UseToast', () => {
expectToastIsHidden(wrapper)
triggerToast(wrapper, { type: 'success', text: 'hello' })
await updateWrapper(wrapper)
await updateWrapper(wrapper, 100)
expectToastIsShow(wrapper)
expect(wrapper.find('.toast-container').html()).toMatchSnapshot()
})

View File

@@ -21,13 +21,7 @@ const ToastContainer: React.FC<React.PropsWithChildren<{}>> = () => {
const toastElements = useMemo(
() =>
toasts.map((t, i) => (
<ToastItem
index={i}
total={toasts.length}
toast={t}
onHover={hover}
key={`toast-${t.id}-${i}`}
/>
<ToastItem index={i} total={toasts.length} toast={t} onHover={hover} key={`toast-${i}`} />
)),
[toasts, hover],
)

View File

@@ -61,21 +61,23 @@ const getColors = (palette: ZeitUIThemesPalette, type?: NormalTypes) => {
const ToastItem: React.FC<ToatItemProps> = React.memo(({ index, total, toast, onHover }) => {
const theme = useTheme()
const { color, bgColor } = getColors(theme.palette, toast.type)
const { color, bgColor } = useMemo(() => getColors(theme.palette, toast.type), [
theme.palette,
toast.type,
])
const [visible, setVisible] = useState<boolean>(false)
const [hide, setHide] = useState<boolean>(false)
const reverseIndex = useMemo(() => total - (index + 1), [total, index])
const translate = useMemo(() => {
const calc = `100% + -75px + -${20 * reverseIndex}px`
if (reverseIndex > 5) return `translate3d(0, -75px, -${reverseIndex}px) scale(.01)`
if (reverseIndex >= 4) return `translate3d(0, -75px, -${reverseIndex}px) scale(.7)`
if (onHover) {
return `translate3d(0, ${reverseIndex * -75}px, -${reverseIndex}px) scale(${
total === 1 ? 1 : 0.98205
})`
}
return `translate3d(0, calc(${calc}), -${reverseIndex}px) scale(${1 - 0.05 * reverseIndex})`
}, [onHover, index, total])
}, [onHover, index, total, reverseIndex])
useEffect(() => {
const timer = setTimeout(() => {
@@ -98,6 +100,8 @@ const ToastItem: React.FC<ToatItemProps> = React.memo(({ index, total, toast, on
clearTimeout(timer)
}
}, [reverseIndex, toast.willBeDestroy])
/* istanbul ignore next */
if (reverseIndex > 10) return null
return (
<div
@@ -119,13 +123,13 @@ const ToastItem: React.FC<ToatItemProps> = React.memo(({ index, total, toast, on
border: 0;
border-radius: ${theme.layout.radius};
padding: ${theme.layout.gap};
box-shadow: ${theme.expressiveness.shadowSmall};
position: absolute;
bottom: 0;
right: 0;
opacity: 0;
opacity: ${reverseIndex > 4 ? 0 : 1};
box-shadow: ${reverseIndex > 4 ? 'none' : theme.expressiveness.shadowSmall};
transform: translate3d(0, 100%, 0px) scale(1);
transition: all 400ms ease;
transition: transform 400ms ease 0ms, visibility 200ms ease 0ms, opacity 200ms ease 0ms;
}
.toast.visible {

View File

@@ -31,14 +31,11 @@ const useToasts = (): [Array<Toast>, (t: Toast) => void] => {
useEffect(() => setHovering(toastHovering), [toastHovering])
const destoryAll = (delay: number) => {
// Wait for all components to display before destroying
// The destory means direct remove all element, whether in animation or not.
const nextDestoryTime = delay + 500
const destoryAll = (delay: number, time: number) => {
/* istanbul ignore next */
if (nextDestoryTime < maxDestoryTime.current) return
if (time <= maxDestoryTime.current) return
clearTimeout(destoryTimer.current)
maxDestoryTime.current = nextDestoryTime
maxDestoryTime.current = time
destoryTimer.current = window.setTimeout(() => {
/* istanbul ignore next */
@@ -50,7 +47,7 @@ const useToasts = (): [Array<Toast>, (t: Toast) => void] => {
return []
})
clearTimeout(destoryTimer.current)
}, maxDestoryTime.current)
}, delay + 350)
}
const setToast = (toast: Toast): void => {
@@ -65,7 +62,7 @@ const useToasts = (): [Array<Toast>, (t: Toast) => void] => {
})
})
destoryStack.current.push(id)
destoryAll(delay)
destoryAll(delay, performance.now())
}
updateToasts((currentToasts: Array<ToastWithID>) => {