component InputNumber { props { size = "default" color = "primary" variant = "default" class = "" id = "" name = "quantity" value = 0 min = "" max = "" step = 1 precision = "auto" label = "" description = "" helpText = "" error = "" invalid = false prefix = "" suffix = "" placeholder = "" autocomplete = "off" inputMode = "decimal" ariaLabel = "" required = false disabled = false inputDisabled = false buttonsDisabled = false readonly = false allowInput = true keyboard = true wheel = false clamp = true fullWidth = false showButtons = true showValidationMessage = true decrementLabel = "Decrease value" incrementLabel = "Increase value" controlsLabel = "Quantity controls" requiredMessage = "A value is required." minMessage = "Value is below the minimum." maxMessage = "Value is above the maximum." @event input = function @event change = function @event increment = function @event decrement = function } state currentValue = value state committedValue = value functions { function inputId() { if (id !== "") { return id } if (name !== "") { return name } return "input-number" } function descriptionId() { return inputId() + "-description" } function messageId() { return inputId() + "-message" } function componentColor() { if (color === "secondary") { return "var(--wire-color-secondary)" } if (color === "success") { return "var(--wire-color-success)" } if (color === "warning") { return "var(--wire-color-warning)" } if (color === "danger") { return "var(--wire-color-danger)" } if (color === "info") { return "var(--wire-color-info)" } return "var(--wire-color-primary)" } function hasMin() { return min !== "" && min !== null && min !== undefined } function hasMax() { return max !== "" && max !== null && max !== undefined } function isBlank() { return currentValue === "" || currentValue === null || currentValue === undefined } function normalizedStep() { return Number(step) > 0 ? Number(step) : 1 } function inferredPrecision() { if (precision !== "auto" && precision !== "") { return Math.max(0, Number(precision) || 0) } if (String(normalizedStep()).includes(".")) { return String(normalizedStep()).split(".")[1].length } return 0 } function precisionFactor() { return Math.pow(10, inferredPrecision()) } function roundValue(nextValue) { return Math.round(Number(nextValue) * precisionFactor()) / precisionFactor() } function clampValue(nextValue) { nextValue = Number(nextValue) if (hasMin() && nextValue < Number(min)) { nextValue = Number(min) } if (hasMax() && nextValue > Number(max)) { nextValue = Number(max) } return roundValue(nextValue) } function isBelowMin() { return !isBlank() && hasMin() && Number(currentValue) < Number(min) } function isAboveMax() { return !isBlank() && hasMax() && Number(currentValue) > Number(max) } function isInvalid() { return ( invalid || error !== "" || (required && isBlank()) || isBelowMin() || isAboveMax() ) } function validationMessage() { if (error !== "") { return error } if (required && isBlank()) { return requiredMessage } if (isBelowMin()) { return minMessage } if (isAboveMax()) { return maxMessage } return "" } function hasMessage() { return ( helpText !== "" || (showValidationMessage && isInvalid() && validationMessage() !== "") ) } function describedBy() { if (description !== "" && hasMessage()) { return descriptionId() + " " + messageId() } if (description !== "") { return descriptionId() } if (hasMessage()) { return messageId() } return "" } function decrementDisabled() { return ( disabled || readonly || buttonsDisabled || (hasMin() && !isBlank() && Number(currentValue) <= Number(min)) ) } function incrementDisabled() { return ( disabled || readonly || buttonsDisabled || (hasMax() && !isBlank() && Number(currentValue) >= Number(max)) ) } function dispatchInputNumberEvent( sourceEvent, eventName, action, previousValue, root, customEvent ) { root = sourceEvent.currentTarget.closest("[data-wrn-input-number]") if (!root && sourceEvent.target) { root = sourceEvent.target.closest("[data-wrn-input-number]") } if (!root) { return } customEvent = document.createEvent("CustomEvent") customEvent.initCustomEvent(eventName, true, false, { component: "InputNumber", name: name, value: currentValue, previousValue: previousValue, action: action, min: hasMin() ? Number(min) : null, max: hasMax() ? Number(max) : null, step: normalizedStep(), valid: !isInvalid() }) root.dispatchEvent(customEvent) } function applyControlValue(nextValue, action, sourceEvent, previousValue) { previousValue = currentValue currentValue = clampValue(nextValue) committedValue = currentValue dispatchInputNumberEvent( sourceEvent, "input", action, previousValue ) dispatchInputNumberEvent( sourceEvent, "change", action, previousValue ) dispatchInputNumberEvent( sourceEvent, action, action, previousValue ) } function incrementValue(sourceEvent, nextValue) { if (incrementDisabled()) { return } if (isBlank()) { nextValue = hasMin() ? Number(min) : normalizedStep() } else { nextValue = Number(currentValue) + normalizedStep() * (sourceEvent.shiftKey ? 10 : 1) } applyControlValue(nextValue, "increment", sourceEvent) } function decrementValue(sourceEvent, nextValue) { if (decrementDisabled()) { return } if (isBlank()) { nextValue = hasMax() ? Number(max) : -normalizedStep() } else { nextValue = Number(currentValue) - normalizedStep() * (sourceEvent.shiftKey ? 10 : 1) } applyControlValue(nextValue, "decrement", sourceEvent) } function handleInput(sourceEvent, previousValue, nextValue) { sourceEvent.stopPropagation() previousValue = currentValue nextValue = sourceEvent.target.value if (nextValue === "") { currentValue = "" } else if (!Number.isNaN(Number(nextValue))) { currentValue = roundValue(Number(nextValue)) } dispatchInputNumberEvent( sourceEvent, "input", "input", previousValue ) } function handleChange(sourceEvent, previousValue) { sourceEvent.stopPropagation() previousValue = committedValue if (!isBlank()) { currentValue = clamp ? clampValue(currentValue) : roundValue(currentValue) } committedValue = currentValue dispatchInputNumberEvent( sourceEvent, "change", "change", previousValue ) } function handleKeydown(sourceEvent) { if ( !keyboard || disabled || readonly || inputDisabled || !allowInput ) { return } if (sourceEvent.key === "ArrowUp") { sourceEvent.preventDefault() incrementValue(sourceEvent) } else if (sourceEvent.key === "ArrowDown") { sourceEvent.preventDefault() decrementValue(sourceEvent) } else if (sourceEvent.key === "Home" && hasMin()) { sourceEvent.preventDefault() applyControlValue(Number(min), "decrement", sourceEvent) } else if (sourceEvent.key === "End" && hasMax()) { sourceEvent.preventDefault() applyControlValue(Number(max), "increment", sourceEvent) } } function handleWheel(sourceEvent) { if ( !wheel || disabled || readonly || inputDisabled || !allowInput ) { return } sourceEvent.preventDefault() if (sourceEvent.deltaY < 0) { incrementValue(sourceEvent) } else if (sourceEvent.deltaY > 0) { decrementValue(sourceEvent) } } } view {
{description}
{/if}{validationMessage()}
{/if} {#if (!showValidationMessage || !isInvalid() || validationMessage() === "") && helpText !== ""}{helpText}
{/if}