diff --git a/docs/src/pages/components/NumberInput.svx b/docs/src/pages/components/NumberInput.svx index 930044d9..e8ebc97d 100644 --- a/docs/src/pages/components/NumberInput.svx +++ b/docs/src/pages/components/NumberInput.svx @@ -33,7 +33,9 @@ Set `required` to `false` to allow for no value. Set `value` to `null` to denote "no value." -Set `invalid` to `true` to set the input in `invalid` state. +Set `invalid` to `true` to force a `error` state for the input. + +The input is reactive to `min`, `max` and `required` attributes. diff --git a/docs/src/pages/framed/NumberInput/NumberInputEmpty.svelte b/docs/src/pages/framed/NumberInput/NumberInputEmpty.svelte index c33a801c..e7dd225c 100644 --- a/docs/src/pages/framed/NumberInput/NumberInputEmpty.svelte +++ b/docs/src/pages/framed/NumberInput/NumberInputEmpty.svelte @@ -3,14 +3,24 @@ let value = null; let invalid = false; + let min; + let max; + let required = false; - +
+

@@ -21,3 +31,11 @@ Invalid: {invalid}

+ +

+ Required: + {required} +

+ + + diff --git a/src/NumberInput/NumberInput.svelte b/src/NumberInput/NumberInput.svelte index 48e2444a..5be17be8 100644 --- a/src/NumberInput/NumberInput.svelte +++ b/src/NumberInput/NumberInput.svelte @@ -101,7 +101,7 @@ let error = false; - import { createEventDispatcher, onMount } from "svelte"; + import { createEventDispatcher, tick } from "svelte"; import Add from "../icons/Add.svelte"; import Subtract from "../icons/Subtract.svelte"; import WarningFilled from "../icons/WarningFilled.svelte"; @@ -121,12 +121,18 @@ } else { ref.stepDown(); } - value = parse(ref.value); + value = +ref.value; dispatch("input", value); dispatch("change", value); } + async function setErrorState() { + // We need to wait for the values to be synced before checking the validity. + await tick(); + error = !ref.checkValidity() || invalid; + } + $: incrementLabel = translateWithId("increment"); $: decrementLabel = translateWithId("decrement"); $: errorId = `error-${id}`; @@ -134,30 +140,7 @@ $$props["aria-label"] || "Numeric input field with increment and decrement buttons"; $: if (ref) ref.setCustomValidity(invalid ? invalidText : ""); - - function parse(raw) { - return raw != "" ? Number(raw) : null; - } - - function getValidity() { - return !ref.checkValidity() || invalid; - } - - function onInput({ target }) { - error = getValidity(); - - dispatch("input", parse(target.value)); - } - - function onChange({ target }) { - error = getValidity(); - - dispatch("change", parse(target.value)); - } - - onMount(() => { - error = getValidity(); - }); + $: value, invalid, required, min, max, setErrorState(); @@ -199,31 +182,31 @@ type="number" pattern="[0-9]*" aria-describedby="{errorId}" - data-invalid="{invalid || error ? true : undefined}" - aria-invalid="{invalid || error ? true : undefined}" - aria-label="{label ? undefined : ariaLabel}" + data-invalid="{error ? true : undefined}" + aria-invalid="{error ? true : undefined}" + aria-label="{label ? ariaLabel : undefined}" disabled="{disabled}" id="{id}" name="{name}" max="{max}" min="{min}" step="{step}" - value="{value ?? ''}" + bind:value="{value}" readonly="{readonly}" required="{required}" {...$$restProps} - on:change="{onChange}" - on:input="{onInput}" + on:change + on:input on:keydown on:keyup on:focus on:blur on:paste /> - {#if invalid || error} + {#if error} {/if} - {#if !invalid && !error && warn} + {#if !error && warn} @@ -266,7 +249,7 @@ {/if} - {#if !invalid && !error && !warn && helperText} + {#if !error && !warn && helperText}
{/if} - {#if invalid || error} + {#if error}
{invalidText}