@yamada-ui/react
Version:
React UI components of the Yamada, by the Yamada, for the Yamada built with React and Emotion
1 lines • 7.9 kB
Source Map (JSON)
{"version":3,"file":"flip.cjs","names":["flipVariants: Variants","createSlotComponent","flipStyle","useControllableState","from","to","motion"],"sources":["../../../../src/components/flip/flip.tsx"],"sourcesContent":["\"use client\"\n\nimport type { Variants } from \"motion/react\"\nimport type { ReactNode } from \"react\"\nimport type { KeyframeIdent, Orientation, ThemeProps } from \"../../core\"\nimport type { HTMLMotionProps } from \"../motion\"\nimport type { FlipStyle } from \"./flip.style\"\nimport { useMemo, useRef, useState } from \"react\"\nimport { createSlotComponent } from \"../../core\"\nimport { useControllableState } from \"../../hooks/use-controllable-state\"\nimport { dataAttr, handlerAll, useSafeLayoutEffect } from \"../../utils\"\nimport { motion } from \"../motion\"\nimport { flipStyle } from \"./flip.style\"\n\nconst flipVariants: Variants = {\n enter: ({ ident, orientation, visible }) => ({\n [orientation === \"horizontal\" ? \"rotateY\" : \"rotateX\"]:\n ident === \"from\" ? (visible ? 180 : 0) : visible ? 0 : 180,\n }),\n exit: ({ ident, orientation }) => ({\n [orientation === \"horizontal\" ? \"rotateY\" : \"rotateX\"]:\n ident === \"from\" ? 0 : 180,\n }),\n}\n\ninterface Rect {\n height?: number\n width?: number\n}\n\nexport interface FlipProps\n extends Omit<HTMLMotionProps<\"button\">, \"onChange\">,\n ThemeProps<FlipStyle> {\n /**\n * Passing React elements to \"from\" is required.\n */\n from: ReactNode\n /**\n * Passing React elements to \"to\" is required.\n */\n to: ReactNode\n /**\n * You can set the initial state.\n *\n * @default 'from'\n */\n defaultValue?: KeyframeIdent\n /**\n * The animation delay.\n *\n * @default 0\n */\n delay?: number\n /**\n * If `true`, the component is disabled.\n *\n * @default false\n */\n disabled?: boolean\n /**\n * The animation duration.\n *\n * @default 0.4\n */\n duration?: number\n /**\n * The orientation of the flip effect. Determines whether the flip occurs horizontally or vertically.\n *\n * @default 'horizontal'\n */\n orientation?: Orientation\n /**\n * If `true`, the component is readonly.\n *\n * @default false\n */\n readOnly?: boolean\n /**\n * Use this when you want to control the animation from outside the component.\n */\n value?: KeyframeIdent\n /**\n * This is a callback function that is called when the animation state changes.\n */\n onChange?: (value: KeyframeIdent) => void\n}\n\nconst {\n PropsContext: FlipPropsContext,\n usePropsContext: useFlipPropsContext,\n withContext,\n withProvider,\n} = createSlotComponent<FlipProps, FlipStyle>(\"flip\", flipStyle)\n\nexport { FlipPropsContext, useFlipPropsContext }\n\n/**\n * `Flip` is an animation component that alternates between flipping two elements.\n *\n * @see https://yamada-ui.com/docs/components/flip\n */\nexport const Flip = withProvider(\n ({\n defaultValue = \"from\",\n delay = 0,\n disabled,\n duration = 0.4,\n from,\n orientation = \"horizontal\",\n readOnly,\n to,\n transition = {},\n value: valueProp,\n onChange,\n onClick: onClickProp,\n ...rest\n }) => {\n const [{ height, width }, setRect] = useState<Rect>({})\n const fromRef = useRef<HTMLDivElement | null>(null)\n const toRef = useRef<HTMLDivElement | null>(null)\n const [value, setValue] = useControllableState({\n defaultValue,\n value: valueProp,\n onChange,\n })\n const visible = value === \"to\"\n\n const style = useMemo(\n () => ({\n height: height ? `${height}px` : \"auto\",\n width: width ? `${width}px` : \"auto\",\n }),\n [width, height],\n )\n\n const onClick = () => {\n if (readOnly) return\n\n setValue((prev) => (prev === \"from\" ? \"to\" : \"from\"))\n }\n\n useSafeLayoutEffect(() => {\n const from = fromRef.current\n const to = toRef.current\n\n if (!from || !to) return\n\n if (\n from.offsetWidth !== to.offsetWidth ||\n from.offsetHeight !== to.offsetHeight\n ) {\n console.warn(\n `Flip: \"from\" element (width: ${from.offsetWidth}px, height: ${from.offsetHeight}px) does not match \"to\" element (width: ${to.offsetWidth}px, height: ${to.offsetHeight}px). Please ensure both elements have the same dimensions.`,\n )\n }\n\n setRect({ height: from.offsetHeight, width: from.offsetWidth })\n }, [fromRef, toRef])\n\n return (\n <motion.button\n type=\"button\"\n style={style}\n data-disabled={dataAttr(disabled)}\n data-orientation={orientation}\n data-readonly={dataAttr(readOnly)}\n data-value={value}\n disabled={disabled}\n onClick={handlerAll(onClickProp, onClick)}\n {...rest}\n >\n <FlipFrom\n ref={fromRef}\n custom={{ orientation, visible }}\n transition={{ delay, duration, ...transition }}\n >\n {from}\n </FlipFrom>\n\n <FlipTo\n ref={toRef}\n custom={{ orientation, visible }}\n transition={{ delay, duration, ...transition }}\n >\n {to}\n </FlipTo>\n </motion.button>\n )\n },\n \"root\",\n)()\n\ninterface FlipFromProps extends HTMLMotionProps<\"span\"> {}\n\nconst FlipFrom = withContext<\"span\", FlipFromProps>(\n ({ custom, ...rest }) => {\n return (\n <motion.span\n animate=\"enter\"\n custom={{ ident: \"from\", ...custom }}\n initial=\"exit\"\n variants={flipVariants}\n {...rest}\n />\n )\n },\n [\"item\", \"from\"],\n)()\n\ninterface FlipToProps extends HTMLMotionProps<\"span\"> {}\n\nconst FlipTo = withContext<\"span\", FlipToProps>(\n ({ custom, ...rest }) => {\n return (\n <motion.span\n animate=\"enter\"\n custom={{ ident: \"to\", ...custom }}\n initial=\"exit\"\n variants={flipVariants}\n {...rest}\n />\n )\n },\n [\"item\", \"to\"],\n)()\n"],"mappings":";;;;;;;;;;;;;;;;AAcA,MAAMA,eAAyB;CAC7B,QAAQ,EAAE,OAAO,aAAa,eAAe,GAC1C,gBAAgB,eAAe,YAAY,YAC1C,UAAU,SAAU,UAAU,MAAM,IAAK,UAAU,IAAI,KAC1D;CACD,OAAO,EAAE,OAAO,mBAAmB,GAChC,gBAAgB,eAAe,YAAY,YAC1C,UAAU,SAAS,IAAI,KAC1B;CACF;AAgED,MAAM,EACJ,cAAc,kBACd,iBAAiB,qBACjB,aACA,iBACEC,6CAA0C,QAAQC,6BAAU;;;;;;AAShE,MAAa,OAAO,cACjB,EACC,eAAe,QACf,QAAQ,GACR,UACA,WAAW,IACX,MACA,cAAc,cACd,UACA,IACA,aAAa,EAAE,EACf,OAAO,WACP,UACA,SAAS,YACT,GAAG,WACC;CACJ,MAAM,CAAC,EAAE,QAAQ,SAAS,+BAA0B,EAAE,CAAC;CACvD,MAAM,4BAAwC,KAAK;CACnD,MAAM,0BAAsC,KAAK;CACjD,MAAM,CAAC,OAAO,YAAYC,gEAAqB;EAC7C;EACA,OAAO;EACP;EACD,CAAC;CACF,MAAM,UAAU,UAAU;CAE1B,MAAM,kCACG;EACL,QAAQ,SAAS,GAAG,OAAO,MAAM;EACjC,OAAO,QAAQ,GAAG,MAAM,MAAM;EAC/B,GACD,CAAC,OAAO,OAAO,CAChB;CAED,MAAM,gBAAgB;AACpB,MAAI,SAAU;AAEd,YAAU,SAAU,SAAS,SAAS,OAAO,OAAQ;;AAGvD,0CAA0B;EACxB,MAAMC,SAAO,QAAQ;EACrB,MAAMC,OAAK,MAAM;AAEjB,MAAI,CAACD,UAAQ,CAACC,KAAI;AAElB,MACED,OAAK,gBAAgBC,KAAG,eACxBD,OAAK,iBAAiBC,KAAG,aAEzB,SAAQ,KACN,gCAAgCD,OAAK,YAAY,cAAcA,OAAK,aAAa,0CAA0CC,KAAG,YAAY,cAAcA,KAAG,aAAa,4DACzK;AAGH,UAAQ;GAAE,QAAQD,OAAK;GAAc,OAAOA,OAAK;GAAa,CAAC;IAC9D,CAAC,SAAS,MAAM,CAAC;AAEpB,QACE,4CAACE,uBAAO;EACN,MAAK;EACE;EACP,iEAAwB,SAAS;EACjC,oBAAkB;EAClB,iEAAwB,SAAS;EACjC,cAAY;EACF;EACV,2DAAoB,aAAa,QAAQ;EACzC,GAAI;aAEJ,2CAAC;GACC,KAAK;GACL,QAAQ;IAAE;IAAa;IAAS;GAChC,YAAY;IAAE;IAAO;IAAU,GAAG;IAAY;aAE7C;IACQ,EAEX,2CAAC;GACC,KAAK;GACL,QAAQ;IAAE;IAAa;IAAS;GAChC,YAAY;IAAE;IAAO;IAAU,GAAG;IAAY;aAE7C;IACM;GACK;GAGpB,OACD,EAAE;AAIH,MAAM,WAAW,aACd,EAAE,OAAQ,GAAG,WAAW;AACvB,QACE,2CAACA,uBAAO;EACN,SAAQ;EACR,QAAQ;GAAE,OAAO;GAAQ,GAAG;GAAQ;EACpC,SAAQ;EACR,UAAU;EACV,GAAI;GACJ;GAGN,CAAC,QAAQ,OAAO,CACjB,EAAE;AAIH,MAAM,SAAS,aACZ,EAAE,OAAQ,GAAG,WAAW;AACvB,QACE,2CAACA,uBAAO;EACN,SAAQ;EACR,QAAQ;GAAE,OAAO;GAAM,GAAG;GAAQ;EAClC,SAAQ;EACR,UAAU;EACV,GAAI;GACJ;GAGN,CAAC,QAAQ,KAAK,CACf,EAAE"}