Edit Attribute Selection Block
EditAttributeSelection is a controlled checkbox-selection form block built on MUI.
Installationâ
- npm
- yarn
- pnpm
- bun
npm install @nodeblocks/frontend-edit-attribute-selection-block
yarn add @nodeblocks/frontend-edit-attribute-selection-block
pnpm add @nodeblocks/frontend-edit-attribute-selection-block
bun add @nodeblocks/frontend-edit-attribute-selection-block
What You Needâ
| Item | Why it matters |
|---|---|
data | Controlled form state. Selected values live in data.attributes. |
onDataChange | Receives the next data snapshot plus metadata for the changed path. |
options | Checkbox choices rendered by the default list. This prop is required in the component source. |
labels (optional) | Copy for the title, subtitle, field name, and submit button. |
errors (optional) | Forwarded to the block context for custom flows. |
layout (optional) | Controls checkbox arrangement: one-column or grid. |
children (optional) | Use compound components or block override rendering. |
Controlled component
EditAttributeSelection does not own form state. Keep data in your app and pass updates back through onDataChange. The expected shape is data.attributes: [{ key, value }].
Code Examplesâ
- Quick Start
- Labels and Copy
- Compound Components
- Block Override
Live Editor
function Example() { const defaultData = { attributes: [] }; const [data, setData] = React.useState(defaultData); const options = [ { key: 'role', value: 'frontend', label: 'ãããŗãã¨ãŗãã¨ãŗã¸ããĸ' }, { key: 'role', value: 'backend', label: 'ããã¯ã¨ãŗãã¨ãŗã¸ããĸ' }, { key: 'role', value: 'devops', label: 'ããĢãšãŋãã¯ã¨ãŗã¸ããĸ' }, { key: 'role', value: 'security', label: 'ããŧãŋããŧãšã¨ãŗã¸ããĸ' }, ]; return ( <EditAttributeSelection data={data} options={options} labels={{ editAttributeSelectionTitle: 'čˇį¨Ž', subtitle: 'ãčĒčēĢãŽčˇį¨Žã鏿ããĻãã ãã', fieldName: 'åŊšå˛', submitButton: 'äŋå', }} layout="grid" onDataChange={(nextData) => { setData(nextData); }} /> ); }
Result
Loading...
Live Editor
function Example() { const defaultData = { attributes: [] }; const [data, setData] = React.useState(defaultData); const options = [ { key: 'role', value: 'frontend', label: 'ãããŗãã¨ãŗãã¨ãŗã¸ããĸ' }, { key: 'role', value: 'backend', label: 'ããã¯ã¨ãŗãã¨ãŗã¸ããĸ' }, { key: 'role', value: 'devops', label: 'ããĢãšãŋãã¯ã¨ãŗã¸ããĸ' }, { key: 'role', value: 'security', label: 'ããŧãŋããŧãšã¨ãŗã¸ããĸ' }, ]; const labels = { editAttributeSelectionTitle: 'Role', subtitle: 'Select the attributes that match your profile.', fieldName: 'Category', submitButton: 'Save', }; return ( <EditAttributeSelection data={data} options={options} labels={labels} layout="one-column" onDataChange={(nextData) => { setData(nextData); }} /> ); }
Result
Loading...
Labels live at the root
This block does not have URL props. Override copy with labels on the root, or replace the default text with compound components if you need a different layout.
Live Editor
function Example() { const defaultData = { attributes: [] }; const [data, setData] = React.useState(defaultData); const options = [ { key: 'role', value: 'frontend', label: 'ãããŗãã¨ãŗãã¨ãŗã¸ããĸ' }, { key: 'role', value: 'backend', label: 'ããã¯ã¨ãŗãã¨ãŗã¸ããĸ' }, { key: 'role', value: 'devops', label: 'ããĢãšãŋãã¯ã¨ãŗã¸ããĸ' }, { key: 'role', value: 'security', label: 'ããŧãŋããŧãšã¨ãŗã¸ããĸ' }, ]; return ( <EditAttributeSelection data={data} options={options} onDataChange={(nextData) => { setData(nextData); }} > <Stack spacing={3}> <EditAttributeSelection.Title sx={{ textAlign: 'left' }}>čˇį¨Ž</EditAttributeSelection.Title> <EditAttributeSelection.Subtitle>ãčĒčēĢãŽčˇį¨Žã鏿ããĻãã ãã</EditAttributeSelection.Subtitle> <Stack spacing={1.5}> <EditAttributeSelection.FieldName>åŊšå˛</EditAttributeSelection.FieldName> <EditAttributeSelection.CheckboxList layout="grid" sx={{ gap: 1 }} /> </Stack> <EditAttributeSelection.SubmitButton>äŋå</EditAttributeSelection.SubmitButton> </Stack> </EditAttributeSelection> ); }
Result
Loading...
Live Editor
function Example() { const defaultData = { attributes: [] }; const [data, setData] = React.useState(defaultData); const options = [ { key: 'role', value: 'frontend', label: 'ãããŗãã¨ãŗãã¨ãŗã¸ããĸ' }, { key: 'role', value: 'backend', label: 'ããã¯ã¨ãŗãã¨ãŗã¸ããĸ' }, { key: 'role', value: 'devops', label: 'ããĢãšãŋãã¯ã¨ãŗã¸ããĸ' }, { key: 'role', value: 'security', label: 'ããŧãŋããŧãšã¨ãŗã¸ããĸ' }, ]; return ( <EditAttributeSelection data={data} options={options} onDataChange={(nextData) => { setData(nextData); }} > {({ defaultBlocks, defaultBlockOrder }) => ({ blocks: { ...defaultBlocks, customNote: <Alert severity="info">鏿å 厚ã¯äŋåãããžããīŧããĸį¨īŧ</Alert>, }, blockOrder: ['customNote', ...defaultBlockOrder], })} </EditAttributeSelection> ); }
Result
Loading...
Important Propsâ
Core Propsâ
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
data | EditAttributeSelectionFormData ({ attributes: { key: string; value: string }[] }) | Yes | - | Controlled form state. |
onDataChange | (data: EditAttributeSelectionFormData, meta: { name: string; value: unknown; cause: one of input, change, blur, clear, reset, programmatic; event?: React.SyntheticEvent }) => void | Yes | - | Called whenever a field changes. meta.name uses bracket notation paths. |
errors | { [fieldPath: string]: string | string[] } | No | undefined | Field-level errors forwarded into the block context for custom flows. |
Content Propsâ
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
labels | { editAttributeSelectionTitle?: React.ReactNode; subtitle?: React.ReactNode; fieldName?: React.ReactNode; submitButton?: React.ReactNode } | No | undefined | Copy for the root title, subtitle, field name, and submit button. |
options | EditAttributeSelectionOption[] ({ key: string; value: string; label: string }[]) | Yes | - | Checkbox options rendered by CheckboxList. |
Layout and Composition Propsâ
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
layout | 'one-column' | 'grid' | No | 'one-column' | Controls how the default checkbox list is arranged. |
children | BlocksOverride<typeof defaultBlocks, CustomBlocks> | No | undefined | Pass JSX compound components or a function that returns blocks and blockOrder. The root renders Title, Subtitle, FieldName, CheckboxList, and SubmitButton by default. |
Inherited props come from StackProps<'form'> with children replaced by the block override API, so standard form/container props such as onSubmit, id, className, and sx are available.
Default UI Blocksâ
| Block | Built on | Notes |
|---|---|---|
EditAttributeSelection | Stack | Root form shell with component="form". |
Title | Typography | variant="h4", component="h2", centered. Uses labels.editAttributeSelectionTitle by default. |
Subtitle | Typography | variant="body2" with bold text. Uses labels.subtitle by default. |
FieldName | Typography | variant="body2" with bold text. Uses labels.fieldName by default. |
CheckboxList | Stack + CheckboxField | Renders the options array as checkboxes. layout="grid" uses a responsive grid: 2 columns on xs, 3 on sm, 4 on md. |
SubmitButton | Button | variant="contained", size="large", fullWidth, type="submit". Defaults to äŋå. |
Extra field primitivesâ
| Primitive | Main Props | Inherits | Built on | Notes |
|---|---|---|---|---|
CheckboxField | name, value, label, control | FormControlLabelProps with control optional | FormControlLabel + Checkbox | Toggles a single { key, value } entry in data.attributes. Available for custom flows, but not rendered by the stock layout. |
TypeScriptâ
export type EditAttributeSelectionFormData = {
attributes: {
key: string;
value: string;
}[];
};
export type EditAttributeSelectionOption = {
key: string;
value: string;
label: string;
};