error: 'type' attribute cannot be dynamic if input uses two-way binding
use
a function in your component to set the node type:
Input.svelte:
<script>
export let type = 'text'
export let label
export let value
function typeAction(node) {
node.type = type;
}
</script>
<div class="space-y-1">
<label>{label}</label>
<input use:typeAction bind:value class="rounded-md w-full">
<p class="text-sm text-red-600">errors</p>
</div>
Form.svelte:
<form on:submit|preventDefault={login}>
<Input type="email" label="Email" bind:value={values.email}/>
<Input type="password" label="Password" bind:value={values.password}/>
<Button type="submit" label="Login"/>
</form>
The reason type
must be static with two-way binding is that the code Svelte generates is different for different kinds of input. For example, number
and range
inputs must have their values coerced to a number, some inputs need change
event listeners instead of input
events or vice versa, and so on.
But you can manually do the same thing the generated code would have been doing — adding an event listener that reflects state:
<script>
export let placeholder = "";
export let label = "";
export let description = "";
export let value = "";
export let type = "text";
const handleInput = e => {
// in here, you can switch on type and implement
// whatever behaviour you need
value = type.match(/^(number|range)$/)
? +e.target.value
: e.target.value;
};
</script>
<div class="container">
<label>{label}</label>
<input {type} {value} {placeholder} on:input={handleInput} />
<p>{description}</p>
</div>