usePuck
A hook for building custom components that can interact with Puck. The best way to access usePuck
is via the createUsePuck()
factory.
import { createUsePuck } from "@measured/puck";
const usePuck = createUsePuck();
const Example = () => {
const type = usePuck((s) => s.selectedItem?.type || "Nothing");
return <h2>{type} selected</h2>;
};
You can also access usePuck
as a direct export, but you won’t be able to use selectors, resulting in unwanted re-renders and degraded performance.
Components using the usePuck
hook must be rendered within the <Puck>
context as children
, overrides
or plugins
.
Args
Param | Example | Type |
---|---|---|
selector(data) | (s: UsePuckData) => s.appState | Function |
selector(data)
A selector function that describes what usePuck
returns. Receives UsePuckData
and returns anything. Be as granular as possible to minimize re-renders.
// Good: only re-render when the `selectedItem` changes
const selectedItem = usePuck((s) => s.selectedItem);
// Bad: re-render when anything changes
const { selectedItem } = usePuck();
const { selectedItem } = usePuck((s) => s);
// Bad: selector creates a new object reference, causing an infinite comparison loop
const { selectedItem } = usePuck((s) => ({ ...s.selectedItem }));
Returns
Whatever is returned by the selector
.
UsePuckData
Param | Example | Type |
---|---|---|
appState | { data: {}, ui: {} } | AppState |
dispatch | (action: PuckAction) => void | Function |
getPermissions | () => ({ delete: true }) | Function |
history | {} | Object |
refreshPermissions | () => void | Function |
selectedItem | { type: "Heading", props: {id: "my-heading"} } | ComponentData |
appState
The current application state for this Puck instance.
console.log(appState.data);
// { content: [], root: {}, zones: {} }
dispatch(action)
Execute an action to mutate the Puck application state.
dispatch({
type: "setUi",
ui: {
leftSideBarVisible: false,
},
});
getPermissions(params)
Get global, component or resolved dynamic permissions.
getPermissions();
// { delete: true, edit: true }
Params
Param | Example | Type |
---|---|---|
item | { type: "HeadingBlock", props: { id: "1234" } } | Object |
root | false | Boolean |
type | "HeadingBlock" | String |
item
Specify item
to retrieve the permissions for a given component instance, resolving any dynamic permissions for that component, as set by the resolvePermissions
parameter.
getPermissions({
item: { type: "HeadingBlock", props: { id: "Heading-1234" } }, // Get resolved permissions for Heading-1234
});
// { delete: false }
The getPermissions
function will be redefined when after resolving dynamic permissions, so it’s generally required to wrap it in a useEffect
hook:
const [myPermissions, setMyPermissions] = useState(getPermissions());
useEffect(() => {
setMyPermissions(getPermissions());
}, [getPermissions]);
root
Specify root
to retrieve the permissions for the root
, as set by the permissions
parameter.
getPermissions({ root: true });
// { delete: false }
type
Specify type
to retrieve the permissions for a given component type, as set by the permissions
parameter.
getPermissions({ type: "HeadingBlock" });
// { delete: false }
history
The history
API provides programmatic access to the undo/redo AppState history.
Param | Example | Type |
---|---|---|
back | () => void | Function |
forward | () => void | Function |
hasPast | true | Boolean |
hasFuture | false | Boolean |
histories | [{ id: 'abc123', data: {} }] | History[] |
index | 5 | Number |
setHistories | setHistories: (histories) => void | Function |
setHistoryIndex | setHistoryIndex: (index) => void | Function |
history.back()
A function to move the app state back through the histories.
history.forward()
A function to move the app state forward through the histories.
history.hasPast
A boolean describing whether or not the present app state has past history items.
history.hasFuture
A boolean describing whether or not the present app state has future history items.
history.histories
An array describing the recorded history as History
objects.
History
params
Param | Example | Type |
---|---|---|
state | {} | AppState |
id | abc123 | String |
state
The app state payload for this history entry.
id
An optional ID for this history entry.
history.index
The index of the currently selected history in history.histories
setHistories
A function to set the history state.
setHistories([]); // clears all history
setHistoryIndex
A function to set current history index.
setHistoryIndex(2);
refreshPermissions(params)
Force the permissions to refresh, running all resolvePermissions
functions and skipping the cache.
resolvePermissions(); // Refresh all permissions
Params
Param | Example | Type |
---|---|---|
item | { type: "HeadingBlock", props: { id: "1234" } } | Object |
root | false | Boolean |
type | "HeadingBlock" | String |
item
Specify item
to refresh the permissions for a given component instance only.
refreshPermissions({
item: { type: "HeadingBlock", props: { id: "Heading-1234" } }, // Force refresh the resolved permissions for Heading-1234
});
root
Specify root
to refresh the permissions for the root
only.
refreshPermissions({ root: true });
type
Specify type
to refresh the permissions for all components of a given component type.
refreshPermissions({ type: "HeadingBlock" });
selectedItem
The currently selected item, as defined by appState.ui.itemSelector
.
console.log(selectedItem);
// { type: "Heading", props: {id: "my-heading"} }