Rich Tree View - Headless
Create your custom Tree View.
Create a custom plugin
Basic plugin
A custom plugins contains 2 required elements:
A hook that will be executed by the
useTreeView
hook:const useCustomPlugin = ({ params }) => { React.useEffect(() => { console.log(params.customParam); }); return {}; };
A property containing the params used by this topic:
useCustomPlugin.params = { customParam: true, };
Params default value
Use the applyDefaultValuesToParams
property to set a default value to your plugin params:
const useCustomPlugin = ({ params }) => {
React.useEffect(() => {
console.log(params.customParam);
});
return {};
};
useCustomPlugin.params = { customParam: true };
useCustomPlugin.applyDefaultValuesToParams = ({ params }) => ({
...params,
customParam: params.customParam ?? false,
});
Use elements from another plugin
Your plugin can access the instance methods, the params and the state of any other plugin.
const useCustomPlugin = ({ store }) => {
const handleSomeAction = () => {
// Log the id of the items currently expanded
console.log(store.value.expansion.expandedItems);
// Check if an item is expanded
const isExpanded = useSelector(selectorIsItemExpanded, 'some-item-id');
};
};
Define a plugin state
TODO
Populate the Tree View instance
The Tree View instance is an object accessible in all the plugins and in the Tree Item. It is the main way a plugin can provide features to the rest of the component.
const useCustomPlugin = ({ store }) => {
const toggleCustomModel = () =>
store.update((prevState) => ({
...prevState,
customModel: !prevState.customModel,
}));
return {
instance: {
toggleCustomModel,
},
};
};
You can then use this instance method in any other plugin:
const useOtherCustomPlugin = ({ instance }) => {
const handleSomeAction = () => {
instance.toggleCustomModel();
};
};
Emit and receive events
const useCustomPlugin = ({ store }) => {
const toggleCustomModel = () => {
const newValue = !selectorCustomModel(store.value);
store.update((prevState) => ({
...prevState,
customModel: newValue,
}));
publishTreeViewEvent(instance, 'toggleCustomModel', { value: newValue });
};
return {
instance: {
toggleCustomModel,
},
};
};
You can then subscribe to this event in any other plugin:
const useOtherCustomPlugin = ({ instance }) => {
useInstanceEventHandler(instance, 'toggleCustomModel', ({ value }) => {
console.log('New value of customModel', value);
});
};
Pass props to your root element
Use the getRootProps
property of your returned value to pass props to your root element:
const useCustomPlugin = ({ params }) => {
return {
getRootProps: () => ({
'data-customparam': params.customParam,
}),
};
};
Pass elements to the Tree Item
Use the contextValue
property in the returned object to pass elements to the Tree Item:
const useCustomPlugin = ({ params }) => {
return {
contextValue: () => ({
customPlugin: { enabled: true },
}),
};
};
function useTreeItemState(itemId: string) {
const {
customPlugin,
// ...other elements returned by the context
} = useTreeViewContext<DefaultTreeViewPluginSignatures>();
// ...rest of the `useTreeItemState` hook content
return {
customPlugin,
// ...other elements returned by `useTreeItemState`
};
}
function TreeItemContent() {
const {
customPlugin,
// ...other elements returned by `useTreeItemState`
} = useTreeItemState(props.itemId);
// Do something with customPlugin.enabled
}
Plugin typing
The typing of a plugin is defined using its signature. This type contains the following information:
type UseCustomPluginSignature = TreeViewPluginSignature<{
// The params specific to your plugin before running `applyDefaultValuesToParams`
params: UseCustomPluginParams;
// The params specific to your plugins after running `applyDefaultValuesToParams`
paramsWithDefaults: UseCustomPluginParamsWithDefaults;
// The methods added to the Tree View instance by your plugin
instance: UseCustomPluginInstance;
// The events emitted by your plugin
events: UseCustomPluginEvents;
// The states defined by your plugin
state: UseCustomPluginState;
// The plugins this plugin needs to work correctly
dependencies: UseCustomPluginDependantPlugins;
}>;
The most basic plugin would have the following signature:
type UseCustomPluginSignature = TreeViewPluginSignature<{}>;
The plugin built in the sections above would have the following signature:
type UseCustomPluginSignature = TreeViewPluginSignature<{
params: {
customParam?: boolean;
customModel?: boolean;
defaultCustomModel?: boolean;
};
// `customParam` and `defaultCustomModel` have a default value defined in `applyDefaultValuesToParams`
paramsWithDefaults: {
customParam: boolean;
customModel?: boolean;
defaultCustomModel: boolean;
};
instance: { toggleCustomModel: () => void };
events: {
toggleCustomModel: {
params: { value: boolean };
};
};
contextValue: { customPlugin: { enabled: boolean } };
dependencies: [UseTreeViewExpansionSignature];
}>;
Examples
Log expanded items
Interact with the Tree View to see the expanded items being logged:
- Data Grid
- Date and Time Pickers
- Charts
- Tree View