Good morning,
I'm creating a custom widget that renders a React component (from Reactstrap) inside Bryntum Gantt.
The widget works fine visually and fires the change event correctly, but I have an issue with initializing the value — it always shows the default color (#c2202b) instead of the value passed in the editor config.
Here’s my code:
import { Widget } from '@bryntum/gantt';
import React, { useState, useEffect } from 'react';
import { createRoot } from 'react-dom/client';
import { Input } from 'reactstrap';
const ColorPickerInput = ({ initialColor, onChange }) => {
const [color, setColor] = useState(initialColor);
useEffect(() => setColor(initialColor), [initialColor]);
return (
<Input
type="color"
value={color}
onChange={(e) => {
const newColor = e.target.value;
setColor(newColor);
onChange(newColor);
}}
/>
);
};
export default class MyColorPicker extends Widget {
static type = 'customColorPicker';
static get configurable() {
return {
color: '#c2202b',
label: 'Color'
};
}
construct(config) {
super.construct(config);
this.color = config.color || config.value || '#c2202b';
}
onPaint({ firstPaint }) {
if (firstPaint) {
this.root = createRoot(this.element);
this.root.render(
<ColorPickerInput
initialColor={this.color}
onChange={(newColor) => {
this.color = newColor;
this.trigger('change', { value: newColor });
}}
/>
);
}
}
doDestroy() {
this.root?.unmount();
super.doDestroy();
}
}
MyColorPicker.initClass();
And this is how I use it inside my editor configuration:
// workOrderEditor.ts
export const workOrderEditor: any = {
items: [
{
type: 'panel',
items: [
{
type: 'container',
layout: "hbox",
width: "100%",
style: 'display: flex; gap: 12px;',
items: [
{
type: 'text',
label: strings.code,
name: 'code',
disabled: true,
style: 'flex-direction: column',
labelPosition: 'top',
flex: '1'
},
{
type: 'text',
label: strings.name,
name: 'name',
disabled: true,
style: 'flex-direction: column',
labelPosition: 'top',
flex: '1'
}
]
},
{
type: 'text',
label: strings.description,
name: 'description',
style: 'flex-direction: column',
labelPosition: 'top'
},
// DIVIDER
{
html: '',
dataset: { text: strings.temporalFields },
cls: 'b-divider',
flex: '1 0 100%'
},
// DIVIDER
{
type: 'number',
label: strings.duration,
name: 'duration',
disabled: true,
style: 'flex-direction: column',
labelPosition: 'top',
flex: '1'
},
{
type: 'dateTime',
label: strings.startDate,
name: 'startDate',
style: 'flex-direction: column',
flex: '1'
},
{
type: 'dateTime',
label: strings.endDate,
name: 'endDate',
style: 'flex-direction: column',
flex: '1'
},
{
type: 'date',
label: 'Fecha límite',
name: 'deadline',
labelPosition: 'top'
},
{
type: 'number',
label: 'Prioridad',
name: 'priority',
min: 0,
max: 10,
step: 1,
labelPosition: 'top'
},
{
type: 'customColorPicker',
label: 'Color',
name: 'color',
labelPosition: 'top'
}
]
}
]
};The widget always renders with the default #c2202b, even though the record’s field color or the config’s color value is #ff9900.
I’ve logged the config object in construct(), but it seems the value property is not passed.
Could you please clarify the correct way to receive the bound field’s value (like the name binding in regular Bryntum form fields) inside a custom widget class?
Or if there’s another lifecycle hook I should use to read the record value before rendering?
Thanks a lot!