Apple Keyboard Interaction

Apple Keyboard Interaction

Apple Keyboard Interaction

Apple Keyboard Interaction

Interaction

Interaction

Interaction

Interaction

Apple Keyboard Interaction

Apple Keyboard Interaction

Apple Keyboard Interaction

Apple Keyboard Interaction

This is an Apple keyboard interaction in Framer. The fascinating part is that the keyboard is not an image. Yes, everything you see is created by drawing rectangles and applying gradients, creating the appearance of a mini Apple keyboard.

To make this project more interactive, I have designed the keys to be not only clickable but also responsive to keyboard key presses. For instance, if you press down the "F" key on your keyboard, the "F" key on the website will also switch to the pressed state.

This is an Apple keyboard interaction in Framer. The fascinating part is that the keyboard is not an image. Yes, everything you see is created by drawing rectangles and applying gradients, creating the appearance of a mini Apple keyboard.

To make this project more interactive, I have designed the keys to be not only clickable but also responsive to keyboard key presses. For instance, if you press down the "F" key on your keyboard, the "F" key on the website will also switch to the pressed state.

This is an Apple keyboard interaction in Framer. The fascinating part is that the keyboard is not an image. Yes, everything you see is created by drawing rectangles and applying gradients, creating the appearance of a mini Apple keyboard.

To make this project more interactive, I have designed the keys to be not only clickable but also responsive to keyboard key presses. For instance, if you press down the "F" key on your keyboard, the "F" key on the website will also switch to the pressed state.

This is an Apple keyboard interaction in Framer. The fascinating part is that the keyboard is not an image. Yes, everything you see is created by drawing rectangles and applying gradients, creating the appearance of a mini Apple keyboard.

To make this project more interactive, I have designed the keys to be not only clickable but also responsive to keyboard key presses. For instance, if you press down the "F" key on your keyboard, the "F" key on the website will also switch to the pressed state.

Apple Keyboard in Framer
Apple Keyboard in Framer
Apple Keyboard in Framer
Apple Keyboard in Framer

Features

For this interaction, I used:

  • A bunch of frames and gradients to achieve the look of the Apple keyboard in Framer.

  • Noise component from framer.supply to give the keyboard some texture.

  • A code override that I applied to each key so they are not only clickable but also trigger on specific key press.

Step 01 outline

Step / 01

Remix the project.

Step 2 outline

Step / 02

Take a look at how it's built.

Step 3 outline

Step / 03

Try recreating it for practice or copy and paste it to your project.

Code override

You can copy this override code and apply it to any component. By selecting a trigger key and applying it to any component, you can configure the component to switch from "Variant 1" to "Variant 2" when that key is pressed. It's crucial to remember the variants must be named in this specific way.

// © Framer University. All rights reserved.


import { ComponentType, useEffect, useState } from "react"
import { addPropertyControls, ControlType } from "framer"

function withKey(Component, key): ComponentType {
    return (props) => {
        // Initial variant, scale
        const [variant, setVariant] = useState("Variant 1")
        const [scale, setScale] = useState(1)

        // Set variant and decrease scale
        const handleKeyDown = (event) => {
            if (event.key == key) {
                setVariant("Variant 2")
            }
        }

        // Set variant back and increase scale
        const handleKeyUp = (event) => {
            if (event.key === key) {
                setVariant("Variant 1")
            }
        }

        useEffect(() => {
            document.addEventListener("keydown", handleKeyDown)
            document.addEventListener("keyup", handleKeyUp)

            return () => {
                document.removeEventListener("keydown", handleKeyDown)
                document.removeEventListener("keyup", handleKeyUp)
            }
        }, [])

        // Animation fine-tuned via the transition property
        return (
            <Component
                {...props}
                variant={variant}
                style={{
                    transform: `scale(${scale})`,
                    transition: "transform 100ms ease-out",
                }}
            />
        )
    }
}

export function withShift(Component): ComponentType {
    return (props) => {
        const [variant, setVariant] = useState("Variant 1")
        const [scale, setScale] = useState(1)
        const [shiftPressed, setShiftPressed] = useState(false)

        const handleKeyPress = (event) => {
            if (event.key === "Shift") {
                setVariant("Variant 2")
                setScale(0.8)
                setShiftPressed(true)
            }
        }

        const handleKeyRelease = (event) => {
            if (event.key === "Shift") {
                setScale(1)
                setShiftPressed(false)
                setTimeout(() => {
                    setVariant("Variant 1")
                }, 100)
            }
        }

        useEffect(() => {
            document.addEventListener("keydown", handleKeyPress)
            document.addEventListener("keyup", handleKeyRelease)

            return () => {
                document.removeEventListener("keydown", handleKeyPress)
                document.removeEventListener("keyup", handleKeyRelease)
            }
        }, [])

        return (
            <Component
                {...props}
                variant={variant}
                style={{
                    transform: `scale(${shiftPressed ? scale : 1})`,
                    transition: `transform 0.1s ease-in-out`,
                }}
            />
        )
    }
}

export function withAlt(Component): ComponentType {
    return (props) => {
        const [variant, setVariant] = useState("Variant 1")
        const [scale, setScale] = useState(1)
        const [altPressed, setAltPressed] = useState(false)

        const handleKeyPress = (event) => {
            if (event.key === "Alt") {
                setVariant("Variant 2")
                setScale(0.8)
                setAltPressed(true)
            }
        }

        const handleKeyRelease = (event) => {
            if (event.key === "Alt") {
                setScale(1)
                setAltPressed(false)
                setTimeout(() => {
                    setVariant("Variant 1")
                }, 100)
            }
        }

        useEffect(() => {
            document.addEventListener("keydown", handleKeyPress)
            document.addEventListener("keyup", handleKeyRelease)

            return () => {
                document.removeEventListener("keydown", handleKeyPress)
                document.removeEventListener("keyup", handleKeyRelease)
            }
        }, [])

        return (
            <Component
                {...props}
                variant={variant}
                style={{
                    transform: `scale(${altPressed ? scale : 1})`,
                    transition: `transform 0.1s ease-in-out`,
                }}
            />
        )
    }
}

export function withCmd(Component): ComponentType {
    return (props) => {
        const [variant, setVariant] = useState("Variant 1")
        const [scale, setScale] = useState(1)

        const handleKeyDown = (event) => {
            if (event.metaKey && event.key === "Meta") {
                setVariant("Variant 2")
                setScale(1.2)
            }
        }

        const handleKeyUp = (event) => {
            if (event.metaKey && event.key === "Meta") {
                setVariant("Variant 1")
                setScale(1)
            }
        }

        useEffect(() => {
            document.addEventListener("keydown", handleKeyDown)
            document.addEventListener("keyup", handleKeyUp)
            return () => {
                document.removeEventListener("keydown", handleKeyDown)
                document.removeEventListener("keyup", handleKeyUp)
            }
        }, [])

        return (
            <Component
                {...props}
                variant={variant}
                style={{ transform: `scale(${scale})` }}
            />
        )
    }
}

export function withCtrl(Component): ComponentType {
    return (props) => {
        const [variant, setVariant] = useState("Variant 1")
        const [scale, setScale] = useState(1)
        const [shiftPressed, setShiftPressed] = useState(false)

        const handleKeyPress = (event) => {
            if (event.ctrlKey) {
                setVariant("Variant 2")
                setScale(0.8)
                setShiftPressed(true)
            }
        }

        const handleKeyRelease = (event) => {
            if (event.key == "Control") {
                setScale(1)
                setShiftPressed(false)
                setTimeout(() => {
                    setVariant("Variant 1")
                }, 100)
            }
        }

        useEffect(() => {
            document.addEventListener("keydown", handleKeyPress)
            document.addEventListener("keyup", handleKeyRelease)

            return () => {
                document.removeEventListener("keydown", handleKeyPress)
                document.removeEventListener("keyup", handleKeyRelease)
            }
        }, [])

        return (
            <Component
                {...props}
                variant={variant}
                style={{
                    transform: `scale(${shiftPressed ? scale : 1})`,
                    transition: `transform 0.1s ease-in-out`,
                }}
            />
        )
    }
}

// Letters
export const withA = (Component): ComponentType => withKey(Component, "a")
export const withB = (Component): ComponentType => withKey(Component, "b")
export const withC = (Component): ComponentType => withKey(Component, "c")
export const withD = (Component): ComponentType => withKey(Component, "d")
export const withE = (Component): ComponentType => withKey(Component, "e")
export const withF = (Component): ComponentType => withKey(Component, "f")
export const withG = (Component): ComponentType => withKey(Component, "g")
export const withH = (Component): ComponentType => withKey(Component, "h")
export const withI = (Component): ComponentType => withKey(Component, "i")
export const withJ = (Component): ComponentType => withKey(Component, "j")
export const withK = (Component): ComponentType => withKey(Component, "k")
export const withL = (Component): ComponentType => withKey(Component, "l")
export const withM = (Component): ComponentType => withKey(Component, "m")
export const withN = (Component): ComponentType => withKey(Component, "n")
export const withO = (Component): ComponentType => withKey(Component, "o")
export const withP = (Component): ComponentType => withKey(Component, "p")
export const withQ = (Component): ComponentType => withKey(Component, "q")
export const withR = (Component): ComponentType => withKey(Component, "r")
export const withS = (Component): ComponentType => withKey(Component, "s")
export const withT = (Component): ComponentType => withKey(Component, "t")
export const withU = (Component): ComponentType => withKey(Component, "u")
export const withV = (Component): ComponentType => withKey(Component, "v")
export const withW = (Component): ComponentType => withKey(Component, "w")
export const withX = (Component): ComponentType => withKey(Component, "x")
export const withY = (Component): ComponentType => withKey(Component, "y")
export const withZ = (Component): ComponentType => withKey(Component, "z")

// Numbers
export const with1 = (Component): ComponentType => withKey(Component, "1")
export const with2 = (Component): ComponentType => withKey(Component, "2")
export const with3 = (Component): ComponentType => withKey(Component, "3")
export const with4 = (Component): ComponentType => withKey(Component, "4")
export const with5 = (Component): ComponentType => withKey(Component, "5")
export const with6 = (Component): ComponentType => withKey(Component, "6")
export const with7 = (Component): ComponentType => withKey(Component, "7")
export const with8 = (Component): ComponentType => withKey(Component, "8")
export const with9 = (Component): ComponentType => withKey(Component, "9")

// Arrow keys
export const withUpArrow = (Component): ComponentType =>
    withKey(Component, "ArrowUp")
export const withDownArrow = (Component): ComponentType =>
    withKey(Component, "ArrowDown")
export const withLeftArrow = (Component): ComponentType =>
    withKey(Component, "ArrowLeft")
export const withRightArrow = (Component): ComponentType =>
    withKey(Component, "ArrowRight")

// Special keys
export const withEnter = (Component): ComponentType =>
    withKey(Component, "enter")
export const withCaps = (Component): ComponentType =>
    withKey(Component, "CapsLock")
// © Framer University. All rights reserved.


import { ComponentType, useEffect, useState } from "react"
import { addPropertyControls, ControlType } from "framer"

function withKey(Component, key): ComponentType {
    return (props) => {
        // Initial variant, scale
        const [variant, setVariant] = useState("Variant 1")
        const [scale, setScale] = useState(1)

        // Set variant and decrease scale
        const handleKeyDown = (event) => {
            if (event.key == key) {
                setVariant("Variant 2")
            }
        }

        // Set variant back and increase scale
        const handleKeyUp = (event) => {
            if (event.key === key) {
                setVariant("Variant 1")
            }
        }

        useEffect(() => {
            document.addEventListener("keydown", handleKeyDown)
            document.addEventListener("keyup", handleKeyUp)

            return () => {
                document.removeEventListener("keydown", handleKeyDown)
                document.removeEventListener("keyup", handleKeyUp)
            }
        }, [])

        // Animation fine-tuned via the transition property
        return (
            <Component
                {...props}
                variant={variant}
                style={{
                    transform: `scale(${scale})`,
                    transition: "transform 100ms ease-out",
                }}
            />
        )
    }
}

export function withShift(Component): ComponentType {
    return (props) => {
        const [variant, setVariant] = useState("Variant 1")
        const [scale, setScale] = useState(1)
        const [shiftPressed, setShiftPressed] = useState(false)

        const handleKeyPress = (event) => {
            if (event.key === "Shift") {
                setVariant("Variant 2")
                setScale(0.8)
                setShiftPressed(true)
            }
        }

        const handleKeyRelease = (event) => {
            if (event.key === "Shift") {
                setScale(1)
                setShiftPressed(false)
                setTimeout(() => {
                    setVariant("Variant 1")
                }, 100)
            }
        }

        useEffect(() => {
            document.addEventListener("keydown", handleKeyPress)
            document.addEventListener("keyup", handleKeyRelease)

            return () => {
                document.removeEventListener("keydown", handleKeyPress)
                document.removeEventListener("keyup", handleKeyRelease)
            }
        }, [])

        return (
            <Component
                {...props}
                variant={variant}
                style={{
                    transform: `scale(${shiftPressed ? scale : 1})`,
                    transition: `transform 0.1s ease-in-out`,
                }}
            />
        )
    }
}

export function withAlt(Component): ComponentType {
    return (props) => {
        const [variant, setVariant] = useState("Variant 1")
        const [scale, setScale] = useState(1)
        const [altPressed, setAltPressed] = useState(false)

        const handleKeyPress = (event) => {
            if (event.key === "Alt") {
                setVariant("Variant 2")
                setScale(0.8)
                setAltPressed(true)
            }
        }

        const handleKeyRelease = (event) => {
            if (event.key === "Alt") {
                setScale(1)
                setAltPressed(false)
                setTimeout(() => {
                    setVariant("Variant 1")
                }, 100)
            }
        }

        useEffect(() => {
            document.addEventListener("keydown", handleKeyPress)
            document.addEventListener("keyup", handleKeyRelease)

            return () => {
                document.removeEventListener("keydown", handleKeyPress)
                document.removeEventListener("keyup", handleKeyRelease)
            }
        }, [])

        return (
            <Component
                {...props}
                variant={variant}
                style={{
                    transform: `scale(${altPressed ? scale : 1})`,
                    transition: `transform 0.1s ease-in-out`,
                }}
            />
        )
    }
}

export function withCmd(Component): ComponentType {
    return (props) => {
        const [variant, setVariant] = useState("Variant 1")
        const [scale, setScale] = useState(1)

        const handleKeyDown = (event) => {
            if (event.metaKey && event.key === "Meta") {
                setVariant("Variant 2")
                setScale(1.2)
            }
        }

        const handleKeyUp = (event) => {
            if (event.metaKey && event.key === "Meta") {
                setVariant("Variant 1")
                setScale(1)
            }
        }

        useEffect(() => {
            document.addEventListener("keydown", handleKeyDown)
            document.addEventListener("keyup", handleKeyUp)
            return () => {
                document.removeEventListener("keydown", handleKeyDown)
                document.removeEventListener("keyup", handleKeyUp)
            }
        }, [])

        return (
            <Component
                {...props}
                variant={variant}
                style={{ transform: `scale(${scale})` }}
            />
        )
    }
}

export function withCtrl(Component): ComponentType {
    return (props) => {
        const [variant, setVariant] = useState("Variant 1")
        const [scale, setScale] = useState(1)
        const [shiftPressed, setShiftPressed] = useState(false)

        const handleKeyPress = (event) => {
            if (event.ctrlKey) {
                setVariant("Variant 2")
                setScale(0.8)
                setShiftPressed(true)
            }
        }

        const handleKeyRelease = (event) => {
            if (event.key == "Control") {
                setScale(1)
                setShiftPressed(false)
                setTimeout(() => {
                    setVariant("Variant 1")
                }, 100)
            }
        }

        useEffect(() => {
            document.addEventListener("keydown", handleKeyPress)
            document.addEventListener("keyup", handleKeyRelease)

            return () => {
                document.removeEventListener("keydown", handleKeyPress)
                document.removeEventListener("keyup", handleKeyRelease)
            }
        }, [])

        return (
            <Component
                {...props}
                variant={variant}
                style={{
                    transform: `scale(${shiftPressed ? scale : 1})`,
                    transition: `transform 0.1s ease-in-out`,
                }}
            />
        )
    }
}

// Letters
export const withA = (Component): ComponentType => withKey(Component, "a")
export const withB = (Component): ComponentType => withKey(Component, "b")
export const withC = (Component): ComponentType => withKey(Component, "c")
export const withD = (Component): ComponentType => withKey(Component, "d")
export const withE = (Component): ComponentType => withKey(Component, "e")
export const withF = (Component): ComponentType => withKey(Component, "f")
export const withG = (Component): ComponentType => withKey(Component, "g")
export const withH = (Component): ComponentType => withKey(Component, "h")
export const withI = (Component): ComponentType => withKey(Component, "i")
export const withJ = (Component): ComponentType => withKey(Component, "j")
export const withK = (Component): ComponentType => withKey(Component, "k")
export const withL = (Component): ComponentType => withKey(Component, "l")
export const withM = (Component): ComponentType => withKey(Component, "m")
export const withN = (Component): ComponentType => withKey(Component, "n")
export const withO = (Component): ComponentType => withKey(Component, "o")
export const withP = (Component): ComponentType => withKey(Component, "p")
export const withQ = (Component): ComponentType => withKey(Component, "q")
export const withR = (Component): ComponentType => withKey(Component, "r")
export const withS = (Component): ComponentType => withKey(Component, "s")
export const withT = (Component): ComponentType => withKey(Component, "t")
export const withU = (Component): ComponentType => withKey(Component, "u")
export const withV = (Component): ComponentType => withKey(Component, "v")
export const withW = (Component): ComponentType => withKey(Component, "w")
export const withX = (Component): ComponentType => withKey(Component, "x")
export const withY = (Component): ComponentType => withKey(Component, "y")
export const withZ = (Component): ComponentType => withKey(Component, "z")

// Numbers
export const with1 = (Component): ComponentType => withKey(Component, "1")
export const with2 = (Component): ComponentType => withKey(Component, "2")
export const with3 = (Component): ComponentType => withKey(Component, "3")
export const with4 = (Component): ComponentType => withKey(Component, "4")
export const with5 = (Component): ComponentType => withKey(Component, "5")
export const with6 = (Component): ComponentType => withKey(Component, "6")
export const with7 = (Component): ComponentType => withKey(Component, "7")
export const with8 = (Component): ComponentType => withKey(Component, "8")
export const with9 = (Component): ComponentType => withKey(Component, "9")

// Arrow keys
export const withUpArrow = (Component): ComponentType =>
    withKey(Component, "ArrowUp")
export const withDownArrow = (Component): ComponentType =>
    withKey(Component, "ArrowDown")
export const withLeftArrow = (Component): ComponentType =>
    withKey(Component, "ArrowLeft")
export const withRightArrow = (Component): ComponentType =>
    withKey(Component, "ArrowRight")

// Special keys
export const withEnter = (Component): ComponentType =>
    withKey(Component, "enter")
export const withCaps = (Component): ComponentType =>
    withKey(Component, "CapsLock")

Free Framer Course

Learn how to create stunning websites with ease by learning the fundamentals of Framer.

Free
Framer Course

Learn how to create stunning websites with ease by learning the fundamentals of Framer.

Free Framer Course

Learn how to create stunning websites with ease by learning the fundamentals of Framer.