import cactusTheme, { generateTheme } from '@repay/cactus-theme' import addons, { makeDecorator } from '@storybook/addons' import * as React from 'react' import styled, { CSSObject } from 'styled-components' import { ScreenSizeProvider } from '../src/ScreenSizeProvider/ScreenSizeProvider' import { StyleProvider } from '../src/StyleProvider/StyleProvider' import { BACKGROUND_CHANGE, BORDER_BOX_CHANGE, CONTAINER_CHANGE, DECORATOR_LISTENING, NAME, PROP_NAME, THEME_CHANGE, } from './constants' type AlignmentTypes = 'center' | 'left' | 'right' | 'bottom' | 'top' interface StyledContainerBaseProps { inverse: boolean className?: string align?: AlignmentTypes overrides?: CSSObject borderBox?: boolean } if (window.WeakSet === undefined) window.WeakSet = window.Set const StyledContainerBase: React.FC = ({ className, children, }): React.ReactElement =>
{children}
const alignmentMap: { [k in AlignmentTypes]: CSSObject } = { center: { justifyContent: 'center', alignItems: 'center' }, left: { justifyContent: 'start', alignItems: 'center' }, right: { justifyContent: 'end', alignItems: 'center' }, bottom: { justifyContent: 'center', alignItems: 'end' }, top: { justifyContent: 'center', alignItems: 'start' }, } const DefaultContainer = styled(StyledContainerBase)` position: relative; width: 100%; height: 100vh; overflow-y: auto; ${(p) => (p.inverse ? p.theme.colorStyles.base : p.theme.colorStyles.standard)}; ${(p) => p.borderBox && '* { box-sizing: border-box; }'} && { ${(p) => p.overrides} } ` const FlexContainer = styled(DefaultContainer)` width: 100vw; display: flex; ${(p) => alignmentMap[p.align]}; ` FlexContainer.defaultProps = { align: 'center', } interface ProvideCactusThemeProps { channel: any } const ProvideCactusTheme: React.FC = ({ channel, ...props }): React.ReactElement => { const [theme, setTheme] = React.useState(cactusTheme) const [inverse, setInverse] = React.useState(false) const [borderBox, setBorderBox] = React.useState(false) const [flexContainer, setFlexContainer] = React.useState(false) const Container = flexContainer ? FlexContainer : DefaultContainer React.useEffect((): (() => void) => { const updateTheme = (params: any): void => { setTheme(generateTheme(params)) } const updateBackground = ({ inverse: newInverse }: any) => { setInverse(newInverse) } const updateBorderBox = ({ borderBox: newBorderBox }: any) => { setBorderBox(newBorderBox) } const updateContainerType = ({ isFlexContainer }: any) => { setFlexContainer(isFlexContainer) } channel.on(THEME_CHANGE, updateTheme) channel.on(BACKGROUND_CHANGE, updateBackground) channel.on(BORDER_BOX_CHANGE, updateBorderBox) channel.on(CONTAINER_CHANGE, updateContainerType) channel.emit(DECORATOR_LISTENING) return (): void => { channel.removeListener(THEME_CHANGE, updateTheme) channel.removeListener(BACKGROUND_CHANGE, updateBackground) channel.removeListener(BORDER_BOX_CHANGE, updateBorderBox) channel.removeListener(CONTAINER_CHANGE, updateContainerType) } }, [channel]) return ( ) } export interface CactusAddonsOptions { align?: AlignmentTypes overrides?: CSSObject } export default makeDecorator({ name: NAME, parameterName: PROP_NAME, wrapper: ( Story: any, context: any, { parameters, options }: { parameters?: CactusAddonsOptions; options?: CactusAddonsOptions } ): React.ReactElement => { const channel = addons.getChannel() parameters = { ...options, ...parameters } return ( ) }, })