import { ReactNode , ReactElement } from 'react' ; import PropTypes from 'prop-types' ; import { cx } from '@emotion/css' ; import { jsx , useTheme } from '@emotion/react' ; import { expandCSSBoxProp } from '../utils/expandCSSBoxProp' ; import { BleepsOnAnimator } from '../utils/BleepsOnAnimator' ; import { FRAME_SVG_POLYLINE , FRAME_SVG_POLYLINE_CUSTOM , FrameSVGProps , FrameSVG } from '../FrameSVG' ; type FRAME_BOX_ORIGIN = 'left' | 'right' | 'top' | 'bottom' | 'center' ; const FRAME_BOX_ORIGIN_VALUES = [ 'left' , 'right' , 'top' , 'bottom' , 'center' ] ; interface FrameBoxProps extends FrameSVGProps { origins ? : FRAME_BOX_ORIGIN | FRAME_BOX_ORIGIN [ ] ; linesWidths ? : number | number [ ] ; children ? : ReactNode ; } const FrameBox = ( props ) : ReactElement => { const { className , origins , linesWidths , children , ... otherProps } = props ; const theme = useTheme ( ) ; const originsList = expandCSSBoxProp ( origins , 'center' ) ; const linesWidthsList = expandCSSBoxProp ( linesWidths , 1 ) . map ( theme . outline ) ; const polylinesRaw = [ [ [ 0 , 0 ] , [ '100%' , 0 ] ] , [ [ '100%' , 0 ] , [ '100%' , '100%' ] ] , [ [ '100%' , '100%' ] , [ 0 , '100%' ] ] , [ [ 0 , '100%' ] , [ 0 , 0 ] ] ] ; type POLYLINES_FILTERED = FRAME_SVG_POLYLINE_CUSTOM | null ; const polylinesFiltered = polylinesRaw . map ( ( polyline , index ) => { const scaleAxis = index === 0 || index === 2 ? 'scaleX' : 'scaleY' ; const transformOrigin = originsList [ index ] ; const lineWidth = linesWidthsList [ index ] ; if ( ! lineWidth ) { return null ; } const polylineCustom = { polyline , lineWidth , css : { strokeLinecap : 'square' } , animated : { initialStyles : { transform : `${ scaleAxis }(0)` , transformOrigin } , entering : { [ scaleAxis ] : 1 } , exiting : { [ scaleAxis ] : 0 } } } ; return polylineCustom ; } ) ; const polylines = polylinesFiltered . filter ( Boolean ) as FRAME_SVG_POLYLINE_CUSTOM [ ] ; return ( < FrameSVG { ... otherProps } className = { cx ( 'arwes-frame-box' , className ) } shapes = { [ [ [ 0 , 0 ] , [ 0 , '100%' ] , [ '100%' , '100%' ] , [ '100%' , 0 ] ] ] } polylines = { polylines } > < BleepsOnAnimator entering = { { name : 'assemble' , loop : true } } exiting = { { name : 'assemble' , loop : true } } /> { children } < /FrameSVG>); } ; FrameBox . propTypes = { origins : PropTypes . oneOfType ( [ PropTypes . oneOf ( FRAME_BOX_ORIGIN_VALUES ) , PropTypes . arrayOf ( PropTypes . oneOf ( FRAME_BOX_ORIGIN_VALUES ) . isRequired ) ] ) , linesWidths : PropTypes . oneOfType ( [ PropTypes . number , PropTypes . arrayOf ( PropTypes . number . isRequired ) ] ) , children : PropTypes . any } ; FrameBox . defaultProps = { origins : 'center' , linesWidths : 1 } ; export { FRAME_BOX_ORIGIN , FRAME_BOX_ORIGIN_VALUES , FrameBoxProps , FrameBox } ;