/**
 * This file houses all non-addon related decorators
 */ import React from 'react' ; import { BrowserRouter , Route , MemoryRouter } from 'react-router-dom' ; import styled , { css , ThemeProvider } from 'styled-components' ; import { DecoratorFn } from '@storybook/react' ; import { configureStore } from '@reduxjs/toolkit' ; import { Provider as StoreProvider } from 'react-redux' ; import { initialize , mswDecorator } from 'msw-storybook-addon' ; import { rootReducer } from '../src/app-state' ; import { breakpoints } from '../src/styles/breakpoints' ; import { GlobalStyle } from '../src/styles/GlobalStyle' ; import { darkTheme , lightTheme } from '../src/styles/theme' ; import { AppRoutes } from '../src/Routes' ; initialize ( { onUnhandledRequest : ( { method , url } ) => { if ( url . pathname . startsWith ( '/.netlify/functions' ) ) { console . error ( `Unhandled ${ method } request to ${ url }.

        This exception has been only logged in the console, however, it's strongly recommended to resolve this error as you don't want unmocked data in Storybook stories.

        If you wish to mock an error response, please refer to this guide: https://mswjs.io/docs/recipes/mocking-error-responses
      ` ) ; } } , } ) ; const ThemeBlock = styled . div < { left ? : boolean ; fullScreen ? : boolean ; } > ( ( { left , fullScreen , theme : { color } } ) => css `
      position: absolute;
      top: 0;
      left: ${ left ? 0 : '50vw' };
      border-right: ${ left ? '1px solid #202020' : 'none' };
      right: ${ left ? '50vw' : 0 };
      width: 50vw;
      height: 100vh;
      bottom: 0;
      overflow: auto;
      padding: ${ fullScreen ? 0 : '1rem' };
      background: ${ color . screenBackground };
      ${ breakpoints . S } {
        left: ${ left ? 0 : '50vw' };
        right: ${ left ? '50vw' : 0 };
        padding: 0 !important;
      }
    ` ) ; export const withTheme = ( StoryFn , { globals : { theme = 'light' } , parameters } ) => { const fullScreen = parameters . layout === 'fullscreen' ; const appTheme = theme === 'light' ? lightTheme : darkTheme ; const secondContainerRef = React . useRef < HTMLDivElement > ( null ) ; const firstBlockRef = React . useCallback ( ( node ) => { if ( node ) { node . addEventListener ( 'scroll' , ( ) => { if ( secondContainerRef . current ) { secondContainerRef . current . scrollTop = node . scrollTop ; } } ) ; } } , [ secondContainerRef . current ] ) ; switch ( theme ) { case 'side-by-side' : { return ( < > < ThemeProvider theme = { lightTheme } > < GlobalStyle /> < ThemeBlock ref = { firstBlockRef } left fullScreen = { fullScreen } > < StoryFn /> < /ThemeBlock> < /ThemeProvider> < ThemeProvider theme = { darkTheme } > < GlobalStyle /> < ThemeBlock ref = { secondContainerRef } fullScreen = { fullScreen } > < StoryFn /> < /ThemeBlock> < /ThemeProvider> < />); } default : { return ( < ThemeProvider theme = { appTheme } > < GlobalStyle /> < StoryFn / > < /ThemeProvider>); } } } ; example export const withStore = ( StoryFn , { parameters } ) => { const store = configureStore ( { reducer : rootReducer , preloadedState : parameters . store ?. initialState , } ) ; return ( < StoreProvider store = { store } > < StoryFn /> < /StoreProvider>); } ; example export const withRouter = ( StoryFn , { parameters : { deeplink } } ) => { if ( ! deeplink ) { return ( < BrowserRouter > < StoryFn /> < /BrowserRouter>); } const { path , route } = deeplink ; return ( < MemoryRouter initialEntries = { [ encodeURI ( route ) ] } > < AppRoutes > < Route path = { path } element = { < StoryFn / > } /> < /AppRoutes> < /MemoryRouter>); } ; export const globalDecorators = [ withRouter , withTheme , withStore , mswDecorator ] ;