craft.js
craft.js copied to clipboard
Nested div tag styling by changing the settings of the component (does not work)
Issue I am trying to change the styling of a component based on the settings. It works great when I apply the settings in the top level element. But If the component has sub element, it seems not to change any of it's style.
To Reproduce Here's an example code of the component:
import { Element, useNode } from '@craftjs/core';
import React from 'react';
import { AppBarSettings } from '../../../component-settings/AppBarSettings';
import { Icon } from '../elementary-components/Icon';
export const Left = ({ children }) => {
const {
connectors: { connect },
} = useNode();
return (
<div ref={connect} className="flex flex-row justify-start space-x-2">
{children}
</div>
);
};
Left.craft = {
rules: {
// Only accept Icon
canMoveIn: (incomingNodes) =>
incomingNodes.every((incomingNode) => incomingNode.data.type === Icon),
},
};
export type AppBarProps = {
height: number;
backgroundColor: string;
isLeftIconEnabled: boolean;
};
export const AppBar = ({
backgroundColor,
height,
isLeftIconEnabled,
}: Partial<AppBarProps>) => {
const {
connectors: { connect, drag },
} = useNode();
return (
<div
className="flex flex-row items-center p-2"
ref={(ref) => connect(drag(ref!))}
style={{
height: `${height}px`,
width: '100%',
backgroundColor: `${backgroundColor}`,
// if I use 'isLeftIconEnabled' here to change any style, it works just fine
}}
>
<div className="w-2/12">
<Element id="left" is={Left} canvas>
<div
style={{
display: isLeftIconEnabled ? 'block' : 'none',
// if I use 'isLeftIconEnabled' here to change any style, it does not work
}}
>
<Icon />
</div>
</Element>
</div>
</div>
);
};
AppBar.craft = {
props: {
height: 60,
backgroundColor: '#F4C430',
isLeftIconEnabled: true,
},
related: {
// AppBarSettings has the form to change height, background color, IsLeftIconEnabled properties
settings: AppBarSettings,
},
};
- Here with 'isLeftIconEnabled', I am trying to change the styling of the nested component, which does not work.
- If this is not the right way to change sub element styling, how should I proceed?
- My end goal is to disable/enable left Icon from the "AppBar" component.
My environment
Software Version(s) craft.js 0.2.0-beta.8 React 18.2.0 TypeScript 4.8.4 Browser Chrome Yarn 122.19 Operating System Windows 10
When you create a linked node like what you have in your component:
<Element id="left" is={Left} canvas>
<div
style={{
display: isLeftIconEnabled ? 'block' : 'none',
// if I use 'isLeftIconEnabled' here to change any style, it does not work
}}
>
<Icon />
</div>
</Element>
What happens is Craft looks for an existing linked node with the id left
, and if it doesn't exist, it then creates the necessary Nodes for the linked node and its children (in this case the child div
) node.
But once the nodes has been created, Craft will not recreate the nodes again and the only way to update the linked node and its children is via Craft's APIs:
const AppBar = () => {
const { id } = useNode();
const { actions, query, linkedNodes } = useEditor();
useEffect(() => {
const linkedNode = query.node(id).get().linkedNodes['left'];
if ( !linkedNode ) { return; }
// make some changes
actions.setProp(linkedNode.id, props => {...});
}, [actions, query]);
}