controlled text field never updates if first controlled values is `undefined`
When having controlled TextField, it never updates if the value at construction time is undefined. I would expect that the controlled value is allowed to be initially undefined and update the text field content when it becomes a string. Both pairs of text fields in following example should be kept in sync:
https://stackblitz.com/edit/solidjs-templates-yxfy22g2
This regression was introduced in #9ccdc68.
// Disable reactivity to only track controllability on first run
// Our current implementation breaks with undefined (stops tracking controlled value)
const initialValue = local.value;
const [value, setValue] = createControllableSignal({
value: () => (initialValue === undefined ? undefined : local.value ?? ""),
defaultValue: () => local.defaultValue,
onChange: (value) => local.onChange?.(value),
});
It's not clear to me what this commit fixes, therefore not proposing a PR reverting it.
Would this work?
value: () => local.value ?? "",
Also a note that null value will work the way you intend.
Additionally, as someone who only transpiles to javascript, it's wild that it's normal to leave something uninitialized (or even accept a null) 😅.
It's a bit strong to say it's "wild that it's normal to leave something uninitialized". I assumed that because the TypeScript definition allows for both string and undefined, but I realize not that the undefined comes just from the optional property, so it was indeed a misunderstanding on my side of the component's interface.
It's very common to have controlled value as undefined in a select when nothing is selected. I was coming from there, but I agree it doesn't make much sense for a TextField because when all the text is deleted, there is no way to make the distinction between empty string and undefined. I will make sure to avoid using a signal that may be undefined. Unfortunately TypeScript won't be able to help me there.
I didn't close the issue before because I wasn't sure if this is a bug or not.
I think this should be considered as a bug. props of solidjs components should allow for passing constant values or signals without surprise for the user of the component. When value changes from undefined to a string it effecvely becomes a controlled text field. It's more idomatic for a solidjs component if it can accept a change anytime.
In case the value at construction time puts the component permanetly in a different mode, this should be documented.
null is a case I personally don't care since the component doesn't accept null according to documented types.
Oh don’t misunderstand me, I understand it’s normal for it to be uninitialised. I’m just having a laugh to myself because I’m not used to dynamic languages, so the idea of something being uninitialised is alien.
That’s my own thing though. I do agree with you here.
At the very least, if this is a bug that is known, then it should be documented
On Tue, 2 Sep 2025 at 12:34 am, Jean-Claude Monnin @.***> wrote:
jcmonnin left a comment (kobaltedev/kobalte#627) https://github.com/kobaltedev/kobalte/issues/627#issuecomment-3242888030
I didn't close the issue before because I wasn't sure if this is a bug or not.
I think this should be considered as a bug. props of solidjs components should allow for passing constant values or signals without surprise for the user of the component. When value changes from undefined to a string it effecvely becomes a controlled text field. It's more idomatic for a solidjs component if it can accept a change anytime.
In case the value at construction time puts the component permanetly in a different mode, this should be documented.
null is a case I personally don't care since the component doesn't accept null according to documented types.
— Reply to this email directly, view it on GitHub https://github.com/kobaltedev/kobalte/issues/627#issuecomment-3242888030, or unsubscribe https://github.com/notifications/unsubscribe-auth/AN2EZW3646VO2BECK2SUAO33QRYQDAVCNFSM6AAAAACFJ3UWCWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTENBSHA4DQMBTGA . You are receiving this because you commented.Message ID: @.***>
Supporting undefined as is tricky since it's also used for "not controlled". I tried supporting it a while ago, will need to revisit.
Otherwise will update types and docs to mention using null.