diff --git a/addons/interactions/src/Panel.tsx b/addons/interactions/src/Panel.tsx index d22e156eae18..5f9eff1e9a2f 100644 --- a/addons/interactions/src/Panel.tsx +++ b/addons/interactions/src/Panel.tsx @@ -261,6 +261,7 @@ export const Panel: React.FC = (props) => { onPrevious={prev} onNext={next} onReplay={replay} + goToStart={start} goToEnd={stop} hasPrevious={hasPrevious} hasNext={hasNext} diff --git a/addons/interactions/src/Tool.tsx b/addons/interactions/src/Tool.tsx index afca05dc69d7..aa555dce1f65 100644 --- a/addons/interactions/src/Tool.tsx +++ b/addons/interactions/src/Tool.tsx @@ -1,13 +1,38 @@ -import React from 'react'; +import React, { useState } from 'react'; import { useChannel } from '@storybook/api'; import { Icons, IconButton } from '@storybook/components'; +import { styled } from '@storybook/theming'; +import { ButtonProps } from '@storybook/components/dist/ts3.9/Button/Button'; import { EVENTS, TOOL_ID } from './constants'; +interface AnimatedButtonProps extends ButtonProps { + animating?: boolean; +} +const StyledAnimatedIconButton = styled(IconButton)( + ({ theme, animating }) => ({ + svg: { + animation: animating && `${theme.animation.rotate360} 1000ms ease-out`, + }, + }) +); + export const Tool = () => { const emit = useChannel({}); + const [isAnimating, setIsAnimating] = useState(false); + const animateAndReplay = () => { + setIsAnimating(true); + emit(EVENTS.RELOAD); + }; + return ( - emit(EVENTS.RELOAD)}> + setIsAnimating(false)} + animating={isAnimating} + > - + ); }; diff --git a/addons/interactions/src/components/Subnav/Subnav.stories.tsx b/addons/interactions/src/components/Subnav/Subnav.stories.tsx index 371fa476fc03..66b3b5047678 100644 --- a/addons/interactions/src/components/Subnav/Subnav.stories.tsx +++ b/addons/interactions/src/components/Subnav/Subnav.stories.tsx @@ -8,6 +8,7 @@ export default { onPrevious: () => {}, onNext: () => {}, onReplay: () => {}, + goToStart: () => {}, goToEnd: () => {}, storyFileName: 'Subnav.stories.tsx', hasNext: true, diff --git a/addons/interactions/src/components/Subnav/Subnav.tsx b/addons/interactions/src/components/Subnav/Subnav.tsx index dfe3b3a9e933..cb5176f46a7f 100644 --- a/addons/interactions/src/components/Subnav/Subnav.tsx +++ b/addons/interactions/src/components/Subnav/Subnav.tsx @@ -2,7 +2,6 @@ import React, { useState } from 'react'; import { Button, Icons, Separator, P } from '@storybook/components'; import { styled } from '@storybook/theming'; import { transparentize } from 'polished'; -import { ButtonProps } from '@storybook/components/dist/ts3.9/Button/Button'; import { CallState, CallStates } from '../../types'; import { StatusBadge } from '../StatusBadge/StatusBadge'; @@ -24,6 +23,7 @@ export interface SubnavProps { onPrevious: () => void; onNext: () => void; onReplay: () => void; + goToStart: () => void; goToEnd: () => void; storyFileName?: string; hasPrevious: boolean; @@ -34,30 +34,23 @@ const StyledButton = styled(Button)(({ theme }) => ({ borderRadius: 4, padding: 6, color: theme.color.dark, - '&:hover,&:focus-visible': { - color: theme.color.secondary, + '&:not(:disabled)': { + '&:hover,&:focus-visible': { + color: theme.color.secondary, + }, }, })); -const StyledIconButton = styled(StyledButton)(({ theme }) => ({ +export const StyledIconButton = styled(StyledButton)(({ theme }) => ({ color: theme.color.mediumdark, margin: '0 3px', - '&:hover,&:focus-visible': { - background: transparentize(0.9, theme.color.secondary), + '&:not(:disabled)': { + '&:hover,&:focus-visible': { + background: transparentize(0.9, theme.color.secondary), + }, }, })); -interface AnimatedButtonProps extends ButtonProps { - animating?: boolean; -} -const StyledAnimatedIconButton = styled(StyledIconButton)( - ({ theme, animating }) => ({ - svg: { - animation: animating && `${theme.animation.rotate360} 1000ms ease-out`, - }, - }) -); - const StyledSeparator = styled(Separator)({ marginTop: 0, }); @@ -75,7 +68,7 @@ const Group = styled.div({ alignItems: 'center', }); -const PlaybackButton = styled(StyledIconButton)({ +const RewindButton = styled(StyledIconButton)({ marginLeft: 9, }); @@ -88,18 +81,13 @@ export const Subnav: React.FC = ({ status, onPrevious, onNext, - onReplay, + goToStart, goToEnd, storyFileName, hasNext, hasPrevious, }) => { - const buttonText = status === CallStates.ERROR ? 'Jump to error' : 'Jump to end'; - const [isAnimating, setIsAnimating] = useState(false); - const animateAndReplay = () => { - setIsAnimating(true); - onReplay(); - }; + const buttonText = status === CallStates.ERROR ? 'Scroll to error' : 'Scroll to end'; return ( @@ -112,27 +100,23 @@ export const Subnav: React.FC = ({ - + + + - + - setIsAnimating(false)} - animating={isAnimating} - data-test-id="button--replay" - > - - + + + {storyFileName && ( diff --git a/lib/components/src/icon/icons.tsx b/lib/components/src/icon/icons.tsx index 7ff3a0279e79..ceddb109cdf6 100644 --- a/lib/components/src/icon/icons.tsx +++ b/lib/components/src/icon/icons.tsx @@ -221,6 +221,10 @@ export const icons = { 'M1024 512A512 512 0 100 512a512 512 0 001024 0zM215 809a418 418 0 010-594 418 418 0 01594 0 418 418 0 010 594 418 418 0 01-594 0zm471-78H338c-25 0-45-20-45-45V338c0-25 20-45 45-45h348c25 0 45 20 45 45v348c0 25-20 45-45 45z', stopalt: 'M894 85H130c-25 0-45 20-45 45v764c0 25 20 45 45 45h764c25 0 45-20 45-45V130c0-25-20-45-45-45z', + rewind: + 'm631.8 642.6 345 245.4c7.7 5.4 15 8 21.4 8 15.9 0 26.8-15.5 26.8-42.3V170.3c0-26.8-11-42.3-26.8-42.3-6.4 0-13.7 2.6-21.4 8l-345 245.4v-211c0-26.9-10.9-42.4-26.8-42.4-6.4 0-13.7 2.6-21.4 8L129 459.4V192a64 64 0 0 0-128 0v640a64 64 0 0 0 128 0V564.6L583.6 888c7.7 5.4 15 8 21.4 8 15.9 0 26.8-15.5 26.8-42.3v-211Z', + fastforward: + 'M398.2 386.4 53.2 141c-7.7-5.4-15-8-21.4-8C15.9 133 5 148.5 5 175.3v683.4C5 885.5 16 901 31.8 901c6.4 0 13.7-2.6 21.4-8l345-245.4v211c0 26.9 11 42.4 26.8 42.4 6.4 0 13.7-2.6 21.4-8L901 569.6V837a64 64 0 0 0 128 0V197a64 64 0 0 0-128 0v267.4L446.4 141c-7.7-5.4-15-8-21.4-8-15.9 0-26.8 15.5-26.8 42.3v211Z', email: 'M960.032 268.004c0.748-10.040-2.246-20.364-9.226-28.684-5.984-7.132-13.938-11.62-22.394-13.394-0.13-0.026-0.268-0.066-0.396-0.092-1.082-0.22-2.172-0.376-3.272-0.5-0.25-0.032-0.492-0.080-0.742-0.102-1.028-0.096-2.052-0.136-3.090-0.156-0.292-0.002-0.582-0.042-0.876-0.042h-816.008c-21.416 0-38.848 16.844-39.898 38-0.034 0.628-0.092 1.256-0.096 1.89 0 0.034-0.006 0.074-0.006 0.114 0 0.050 0.008 0.102 0.008 0.152v495.692c0 0.054-0.008 0.106-0.008 0.156 0 22.090 17.91 40 40 40h816.004c13.808 0 25.98-6.996 33.17-17.636 0.1-0.148 0.182-0.312 0.28-0.458 0.606-0.93 1.196-1.868 1.722-2.84 0.046-0.082 0.080-0.172 0.124-0.258 2.992-5.604 4.704-12.008 4.704-18.804v0 0-493.038zM144.032 350.156l339.946 281.188c6.568 6.434 14.918 10.168 23.564 11.122 0.16 0.024 0.32 0.050 0.48 0.066 0.838 0.082 1.676 0.114 2.518 0.14 0.496 0.020 0.994 0.058 1.492 0.058s0.996-0.042 1.492-0.058c0.842-0.028 1.68-0.058 2.518-0.14 0.16-0.016 0.32-0.042 0.48-0.066 8.646-0.958 16.996-4.688 23.564-11.122l339.946-281.206v370.894h-736v-370.876zM215.066 305.030h593.91l-296.946 245.422-296.964-245.422z',