f-state v1.0.2
f-state
Installation
From the terminal, navigate to your Framer X project folder (File > Show Project Folder) and run:
yarn add f-state
Usage
Basic
Create a state machine.
Control the machine using the machine.send method.
Use the machine's current state to calculate overrides.
In an Overrides file:
const machine = new StateMachine({
	initial: "closed",
	states: {
		closed: {
			on: { TOGGLE: "open", OPEN: "open" }
		},
		open: {
			on: { TOGGLE: "closed", cLOSE: "closed" }
		}
	}
});
export const isItem: Override = () => {
	console.log(machine.current);
	return {
		onTap: () => machine.send("TOGGLE"),
		height: machine.current.name === "open" ? 400 : 200
	};
};
export const openButton: Override = () => machine.sendOnTap("OPEN");
export const closeButton: Override = () => machine.sendOnTap("CLOSE");Parallel States
Create a state machine with parallel states.
In an Overrides file:
const machine = new StateMachine({
	parallel: true,
	states: {
		item: {
			initial: "closed",
			states: {
				closed: {
					on: { TOGGLE_DOOR: "open" }
				},
				open: {
					on: { TOGGLE_DOOR: "closed" }
				}
			},
		},
		cat: {
			initial: "angry",
			states: {
				happy: {
					on: { POKE_CAT: "angry" }
				},
				angry: {
					on: { PET_CAT: "happy" }
				}
			},
		}
	}
});
export const toggleDoorButton: Override = () => machine.sendOnTap("TOGGLE_DOOR");
export const pokeCatButton: Override = () => machine.sendOnTap("POKE_CAT");
export const petCatButton: Override = () => machine.sendOnTap("PET_CAT")};
export const isCat: Override = () => {
	return {
		backgroundColor: machine.current.name.cat === "happy" ? "red" : "green"
	};
};
export const isItem: Override = () => {
	return {
		opacity: machine.current.name.item === "open" ? 1 : 0.5
	};
};Frame States
Use the frameStates property, together with the render method, to set props automatically depending on the machine's current state.
const machine = new StateMachine({
	initial: "closed",
	states: {
		closed: {
			on: { TOGGLE: "open" }
		},
		open: {
			on: { TOGGLE: "closed" }
		}
	},
	frameStates: {
		open: {
			item: {
				height: 400
			}
		},
		closed: {
			item: {
				height: 200
			}
		}
	}
});
export const isItem: Override = () => {
	return {
		...machine.sendOnTap("TOGGLE"),
		...machine.render("item")
	};
};Animated Frame States
Add an options object to a frameStates state to enable animations.
const machine = new StateMachine({
	initial: "closed",
	states: {
		closed: {
			on: { TOGGLE: "open" }
		},
		open: {
			on: { TOGGLE: "closed" }
		}
	},
	frameStates: {
		open: {
			item: {
				height: 400,
				options: {
					tension: 200,
					friction: 50
				}
			}
		},
		closed: {
			item: {
				height: 200,
				options: {
					tension: 200,
					friction: 50
				}
			}
		}
	}
});
export const isItem: Override = () => {
	return {
		...machine.sendOnTap("TOGGLE"),
		...machine.render("item")
	};
};Note: Animations are not currently supported for parallel or nested states.
Methods
send(eventName: string)
Send an eventName into the machine. If the machine's current state has a transition for that eventName, it will cause the machine to change states as specified.
sendOnTap(eventName: string)
Returns a tap event to send the eventName. machine.sendOnTap("TOGGLE") is equivilent to onTap() { machine.send("TOGGLE")}.
render( frameStatesName: string )
Returns the props for this item as listed in the machine's frameStates object.