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.
Created by
About the resource
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.
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.
About the resource
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.
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.
About the resource
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.
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.
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")
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")
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")