Developers
Back to framer.com
Documentation
Overrides
  • Motion
  • Handshake
  • Guides
  • API Documentation
Developers
  • Motion
  • Handshake
  • Guides
  • API Documentation
Back to framer.com
Guides
  • Code Components
  • Smart Components
  • Code Overrides
  • Auto Sizing
  • Sharing Code
  • Importing External Code
  • Migrating
  • HandshakeBeta
Community
  • GitHub
  • Discord

Code Overrides

A way to share data between components within Framer.

Code Overrides are higher-order components that can be used to share application state, work with real data, create advanced gestures & animations, and more.

They can be applied to almost any layer on the canvas and give you the ability to override the layer or component's props. A basic override looks like this:

import type { ComponentType } from "react";
export const withLowerOpacity = (Component): ComponentType => {
// This part of the code is only run once when creating the component
return (props) => {
// This part runs every time the component is rendered.
return <Component {...props} opacity={0.5} />;
};
};

This override takes in the Component or layer it's attached to, and overrides the opacity to 0.5.

Note: the older override syntax still works, but we decided to stay as close to standard React as we could going forward, avoiding having multiple ways to do the same thing.

#Sharing Data

Overrides in Framer also allow you to share data, information, and state across the different components you attach them to.


When using Overrides to share data across components, we suggest using a simple shared hook.

import type { ComponentType } from "react";
import { createStore } from "https://framer.com/m/framer/store.js@^0.3.0"
const useStore = createStore({ count: 0 });
export const withCount = (Component): ComponentType => {
return (props) => {
const [store, setStore] = useStore();
return <Component {...props} text={`Count ${store.count}`} />;
};
};
export const withIncrement = (Component): ComponentType => {
return (props) => {
const [store, setStore] = useStore();
const onTap = () => setStore({ count: store.count + 1 });
return <Component {...props} onTap={onTap} />;
};
};

If you were previously using the Data component to share data, we now encourage you to switch to standard hook solutions (like the one above).

If React hooks seem intimidating to you at first sight, you’re not alone. They are a standard part of React and are the default way to keep track of a component's state. Let's take a look at a simple example:

const [name, setName] = useState("Koen")


In this example, name holds the current value. By default, we set it to "Koen" at the end of the line.

You can update the name by calling setName("Hunter").

If you're having trouble understanding React, we've written an entire book just for you! Framer's Guide to React is the perfect resource to learn enough about React to become dangerous. It's written from a Designer's perspective, mapping out everything you'll want to know to start writing your own Overrides.

Additionally, you can find more tutorials on learning React here.

#Recipes

#Scroll Animations

Overrides can be used to animate elements based on interactions with other elements. In this case we add the withScroll Override to a Scroll component on the canvas. When scrolled, the Scroll component maps its scrollOffset to the global MotionValue scrollOffset which we can use to animate values in other Overrides. By using a MotionValue, all our animations are incredibly performant by default.

In withHorizontalParallax we use useTransform to map the x position of the element to 25% of the scrollOffset MotionValue, creating a parallax effect.

In withFadeByScroll we use useTransform to fade the opacity of the element when scrollOffset is between 50 and 200 (mapped to 0-1). You can change these values as you'd like to create the style of animation you're looking to create.

import type { ComponentType, ReactPropTypes } from "react"
import { useLayoutEffect, useRef } from "react"
import { motionValue, useTransform } from "framer"
const scrollOffset = motionValue(0)
export function withScroll(Component): ComponentType {
return (props) => {
const ref = useRef<HTMLDivElement>(null)
// Reset scroll offset on mount
useLayoutEffect(() => {
scrollOffset.set(0)
}, [])
const onScroll = () => {
if (!ref.current) return
scrollOffset.set(ref.current.scrollTop)
}
return <Component {...props} ref={ref} onScroll={onScroll} />
}
}
export function withHorizontalParallax(Component): ComponentType<any> {
return (props) => {
// Map x position to 25% of scroll offest
const x = useTransform(scrollOffset, (latest) => latest * 0.25)
return <Component {...props} style={{ ...props.style, x }} />
}
}
export function withFadeByScroll(Component): ComponentType<any> {
return (props) => {
// Fade in when scroll offset hits 50
// Finish fade when scroll offset is 200
const opacity = useTransform(scrollOffset, [50, 200], [0, 1])
return <Component {...props} style={{ ...props.style, opacity }} />
}
}

#Variant Cycling

By applying Overrides to smart components with Variants you can gain an extra layer of control, allowing you to use logic & events from other Overrides to animate between them.

A basic example here shows how can use an Override to cycle between Variants of a smart component, from here you can log the current variant to the console or add additional logic based on the Variant switches.

import type { ComponentType } from "react"
import { useCycle } from "framer-motion"
export function withLocalVariantState(Component): ComponentType {
return (props) => {
// Cycle between variants on Tap
const [variant, cycleVariant] = useCycle("Active", "Inactive")
console.log(`Switched to Variant ${variant}`)
return <Component {...props} variant={variant} onTap={cycleVariant} />
}
}

From there, we can set up a shared store using createStore that we use to synchronise the Variant of multiple Smart components with the Overrides applied.

import type { ComponentType } from "react"
import { useCycle } from "framer-motion"
import { createStore } from "https://framer.com/m/framer/store.js@^1.0.0"
const useStore = createStore({
variant: "Active",
})
export function withSharedVariantState(Component): ComponentType {
return (props) => {
// Uses the Variant set on the shared store
const [store] = useStore()
return <Component {...props} variant={store.variant} />
}
}
export function withToggleSharedVariantState(Component): ComponentType {
return (props) => {
const [store, setStore] = useStore()
// Cycles the variant set on the shared store
function toggleVariant() {
setStore((prevState) => ({
variant: prevState.variant === "Active" ? "Inactive" : "Active",
}))
}
return (
<Component
{...props}
variant={store.variant}
onTap={toggleVariant}
/>
)
}
}
PreviousSmart ComponentsNextAuto Sizing
On this page
  • Sharing Data
  • Recipes
  • Scroll Animations
  • Variant Cycling

Copyright © 2022 Framer B.V.

  • Security
  • Terms of Service
  • Privacy Statement