UNPKG

framer-motion

Version:

An open source and production-ready motion library for React on the web

271 lines (237 loc) • 7.91 kB
import "../../../../../jest.setup" import { buildHTMLStyles } from "../build-html-styles" import { DOMVisualElementOptions, TransformOrigin } from "../../types" import { BoxDelta, Point2D, AxisBox2D } from "../../../../types/geometry" import { ResolvedValues } from "../../../types" describe("buildHTMLStyles", () => { test("Builds basic styles", () => { const latest = { width: 100 } const style = {} build(latest, { style }) expect(style).toEqual({ width: "100px" }) }) test("Builds vars", () => { const latest = { "--width": 100 } const vars = {} build(latest, { vars }) expect(vars).toEqual({ "--width": 100 }) }) test("Builds transform with default value types", () => { const latest = { x: 1, y: 2, rotateX: 90, transformPerspective: 200 } const style = {} build(latest, { style }) expect(style).toEqual({ transform: "perspective(200px) translateX(1px) translateY(2px) rotateX(90deg) translateZ(0)", }) }) test("Builds transform with defined value types", () => { const latest = { x: "1vw", y: "2%", rotateX: "90turn" } const style = {} build(latest, { style }) expect(style).toEqual({ transform: "translateX(1vw) translateY(2%) rotateX(90turn) translateZ(0)", }) }) test("Builds transform without translateZ if enableHardwareAcceleration is false", () => { const latest = { x: 1, y: 2, rotateX: 90 } const style = {} build(latest, { style, config: { enableHardwareAcceleration: false } }) expect(style).toEqual({ transform: "translateX(1px) translateY(2px) rotateX(90deg)", }) }) test("Builds transform none if all transforms are default", () => { const latest = { x: 0, y: 0, scale: 1 } const style = {} build(latest, { style }) expect(style).toEqual({ transform: "none", }) }) test("Doesn't build transform none if all transforms are default if allowTransformNone is false", () => { const latest = { x: 0, y: 0, scale: 1 } const style = {} build(latest, { style, config: { allowTransformNone: false } }) expect(style).toEqual({ transform: "translateX(0px) translateY(0px) scale(1) translateZ(0)", }) }) test("Builds transformOrigin with correct default value types", () => { const latest = { originX: 0.2, originY: "60%", originZ: 10 } const style = {} build(latest, { style }) expect(style).toEqual({ transformOrigin: "20% 60% 10px", }) }) test("Applies transformTemplate if provided", () => { const latest = { x: 1 } const style = {} build(latest, { style, config: { transformTemplate: ({ x }: any, gen: any) => `translateY(${parseFloat(x as string) * 2}) ${gen}`, }, }) expect(style).toEqual({ transform: "translateY(2) translateX(1px) translateZ(0)", }) }) test("Applies transformTemplate if provided", () => { const latest = { x: 1 } const style = {} build(latest, { style, config: { transformTemplate: ({ x }: any, gen: any) => `translateY(${parseFloat(x as string) * 2}) ${gen}`, }, }) expect(style).toEqual({ transform: "translateY(2) translateX(1px) translateZ(0)", }) }) test("Uses layout projection transform if enabled", () => { const latest = {} const style = {} const delta = { x: { translate: 1, scale: 0.5, origin: 0.8, originPoint: 0 }, y: { translate: 2, scale: 2, origin: 0.2, originPoint: 0 }, } build(latest, { style, isLayoutProjectionEnabled: true, treeScale: { x: 1, y: 1 }, delta, deltaFinal: delta, targetBox: { x: { min: 0, max: 100 }, y: { min: 0, max: 100 }, }, }) expect(style).toEqual({ transform: "translate3d(1px, 2px, 0) scale(0.5, 2)", transformOrigin: "80% 20% 0", }) }) test("Adds rotate transforms if present, but not translation, scale and skew", () => { /** * Translation and rotate are already baked into deltaFinal */ const latest = { x: 100, rotate: 90, skew: 3 } const style = {} const delta = { x: { translate: 1, scale: 0.5, origin: 0.8, originPoint: 0 }, y: { translate: 2, scale: 2, origin: 0.2, originPoint: 0 }, } build(latest, { style, isLayoutProjectionEnabled: true, treeScale: { x: 1, y: 1 }, delta, deltaFinal: delta, targetBox: { x: { min: 0, max: 100 }, y: { min: 0, max: 100 }, }, }) expect(style).toEqual({ transform: "translate3d(1px, 2px, 0) rotate(90deg) scale(0.5, 2)", transformOrigin: "80% 20% 0", }) }) test("Applies scale correction to borderRadius and boxShadow", () => { /** * Translation and rotate are already baked into deltaFinal */ const latest = { borderRadius: 1, boxShadow: "10px 20px 30px rgba(0, 0, 0, 0.5)", } const style = {} const delta = { x: { translate: 1, scale: 0.5, origin: 0.8, originPoint: 0 }, y: { translate: 2, scale: 2, origin: 0.2, originPoint: 0 }, } build(latest, { style, isLayoutProjectionEnabled: true, treeScale: { x: 0.5, y: 2 }, delta, deltaFinal: delta, targetBox: { x: { min: 0, max: 10 }, y: { min: 0, max: 20 }, }, }) expect(style).toEqual({ transform: "translate3d(2px, 1px, 0) scale(0.5, 2)", transformOrigin: "80% 20% 0", borderBottomLeftRadius: "10% 5%", borderBottomRightRadius: "10% 5%", borderTopLeftRadius: "10% 5%", borderTopRightRadius: "10% 5%", boxShadow: "40px 5px 14.11765px rgba(0, 0, 0, 0.5)", }) }) }) interface BuildProps { style: ResolvedValues vars: ResolvedValues transform: ResolvedValues transformOrigin: TransformOrigin transformKeys: string[] config: DOMVisualElementOptions & { transformTemplate?: any } isLayoutProjectionEnabled: boolean delta?: BoxDelta deltaFinal?: BoxDelta treeScale?: Point2D targetBox?: AxisBox2D } function build( latest: ResolvedValues, { style = {}, vars = {}, transform = {}, transformOrigin = {}, transformKeys = [], config = { enableHardwareAcceleration: true, allowTransformNone: true, }, isLayoutProjectionEnabled, delta, deltaFinal, treeScale, targetBox, }: Partial<BuildProps> = {} ) { buildHTMLStyles( { style, vars, transform, transformOrigin, transformKeys, }, latest, { target: targetBox, isEnabled: isLayoutProjectionEnabled, isTargetLocked: false, targetFinal: targetBox, } as any, { delta, deltaFinal, treeScale, isHydrated: true, } as any, config, config.transformTemplate ) }