Skip to content

Instantly share code, notes, and snippets.

@alapini
Forked from prevwong/example-grid-craft.js
Created November 7, 2021 13:40
Show Gist options
  • Save alapini/e8b6a394d8872b055a7a8c28eea40b5b to your computer and use it in GitHub Desktop.
Save alapini/e8b6a394d8872b055a7a8c28eea40b5b to your computer and use it in GitHub Desktop.
A simple Grid layout system with Craft.js
// Get total `width` of all children
const getAccumulatedChildrenWidth = (helper, parentId) => {
return helper(self.id).decendants().map(id => helper(id).get())
.reduce((a, b) => a.data.props.width + b.data.props.width, 0);
}
const Grid = () => {
return (
<div>
{children}
</div>
)
}
// 1. Add a rule to reject any more GridItem if there is no more space on the Grid
Grid.craft = {
canMoveIn = (node, self, helper) => node.data.type == GridItem && getAccumulatedChildrenWidth(helper, self.id) <= 12;
}
export const GridItem = ({width = 2, children}) => {
const isNew = useRef(true);
const { parentId, setProp } = useNode((node) => ({
parentId: node.id
}));
/** 2.
* If the GridItem is rendered with a `width` that is more than the remaining space on the Grid,
* then, resize the GridItem to fit the remaining space
*/
useManager((_, query) => {
const accumulatedChildrenWidth = getAccumulatedChildrenWidth(query.node, parentId);
const remainingWidth = 12 - accumulatedChildrenWidth;
if ( isNew.current && width > remainingWidth ) {
setProp(props => props.width = remainingWidth);
isNew.current = false;
}
});
return (
<div className={`md-${width}`}>
{children}
</div>
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment