🐛 (numberInput) Fix input clearing out on dot or comma press
This commit is contained in:
1
packages/bot-engine/blocks/inputs/number/parseNumber.ts
Normal file
1
packages/bot-engine/blocks/inputs/number/parseNumber.ts
Normal file
@ -0,0 +1 @@
|
||||
export const parseNumber = (value: string) => Number(value).toString()
|
@ -1 +1,10 @@
|
||||
export const validateNumber = (inputValue: string) => !isNaN(Number(inputValue))
|
||||
import { isNotDefined } from '@typebot.io/lib'
|
||||
import { NumberInputBlock } from '@typebot.io/schemas'
|
||||
|
||||
export const validateNumber = (
|
||||
inputValue: string,
|
||||
options: NumberInputBlock['options']
|
||||
) =>
|
||||
inputValue !== '' &&
|
||||
(isNotDefined(options?.min) || Number(inputValue) >= Number(options.min)) &&
|
||||
(isNotDefined(options?.max) || Number(inputValue) <= Number(options.max))
|
||||
|
@ -30,6 +30,7 @@ import { parseVariables } from './variables/parseVariables'
|
||||
import { updateVariablesInSession } from './variables/updateVariablesInSession'
|
||||
import { startBotFlow } from './startBotFlow'
|
||||
import { TRPCError } from '@trpc/server'
|
||||
import { parseNumber } from './blocks/inputs/number/parseNumber'
|
||||
|
||||
type Params = {
|
||||
version: 1 | 2
|
||||
@ -344,9 +345,9 @@ const parseReply =
|
||||
}
|
||||
case InputBlockType.NUMBER: {
|
||||
if (!inputValue) return { status: 'fail' }
|
||||
const isValid = validateNumber(inputValue)
|
||||
const isValid = validateNumber(inputValue, block.options)
|
||||
if (!isValid) return { status: 'fail' }
|
||||
return { status: 'success', reply: inputValue }
|
||||
return { status: 'success', reply: parseNumber(inputValue) }
|
||||
}
|
||||
case InputBlockType.DATE: {
|
||||
if (!inputValue) return { status: 'fail' }
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@typebot.io/js",
|
||||
"version": "0.2.8",
|
||||
"version": "0.2.9",
|
||||
"description": "Javascript library to display typebots on your website",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { ShortTextInput } from '@/components'
|
||||
import { SendButton } from '@/components/SendButton'
|
||||
import { CommandData } from '@/features/commands/types'
|
||||
import { InputSubmitContent } from '@/types'
|
||||
import { isMobile } from '@/utils/isMobileSignal'
|
||||
import type { NumberInputBlock } from '@typebot.io/schemas'
|
||||
import { createSignal, onCleanup, onMount } from 'solid-js'
|
||||
import { numberInputHelper } from '../numberInputHelper'
|
||||
|
||||
type NumberInputProps = {
|
||||
block: NumberInputBlock
|
||||
@ -13,16 +13,21 @@ type NumberInputProps = {
|
||||
}
|
||||
|
||||
export const NumberInput = (props: NumberInputProps) => {
|
||||
const [inputValue, setInputValue] = createSignal(props.defaultValue ?? '')
|
||||
const [inputValue, setInputValue] = createSignal<string | number>(
|
||||
props.defaultValue ?? ''
|
||||
)
|
||||
// eslint-disable-next-line solid/reactivity
|
||||
const [staticValue, bindValue, targetValue] = numberInputHelper(() =>
|
||||
inputValue()
|
||||
)
|
||||
let inputRef: HTMLInputElement | undefined
|
||||
|
||||
const handleInput = (inputValue: string) => setInputValue(inputValue)
|
||||
|
||||
const checkIfInputIsValid = () =>
|
||||
inputValue() !== '' && inputRef?.reportValidity()
|
||||
|
||||
const submit = () => {
|
||||
if (checkIfInputIsValid()) props.onSubmit({ value: inputValue() })
|
||||
if (checkIfInputIsValid())
|
||||
props.onSubmit({ value: inputValue().toString() })
|
||||
}
|
||||
|
||||
const submitWhenEnter = (e: KeyboardEvent) => {
|
||||
@ -53,15 +58,21 @@ export const NumberInput = (props: NumberInputProps) => {
|
||||
}}
|
||||
onKeyDown={submitWhenEnter}
|
||||
>
|
||||
<ShortTextInput
|
||||
<input
|
||||
ref={inputRef}
|
||||
value={inputValue()}
|
||||
class="focus:outline-none bg-transparent px-4 py-4 flex-1 w-full text-input"
|
||||
style={{ 'font-size': '16px', appearance: 'auto' }}
|
||||
value={staticValue}
|
||||
// @ts-expect-error not defined
|
||||
// eslint-disable-next-line solid/jsx-no-undef
|
||||
use:bindValue
|
||||
placeholder={
|
||||
props.block.options?.labels?.placeholder ?? 'Type your answer...'
|
||||
}
|
||||
onInput={handleInput}
|
||||
onInput={(e) => {
|
||||
setInputValue(targetValue(e.currentTarget))
|
||||
}}
|
||||
type="number"
|
||||
style={{ appearance: 'auto' }}
|
||||
min={props.block.options?.min}
|
||||
max={props.block.options?.max}
|
||||
step={props.block.options?.step ?? 'any'}
|
||||
|
@ -0,0 +1,32 @@
|
||||
import { createEffect, untrack } from 'solid-js'
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export const numberInputHelper = function (value: () => any) {
|
||||
const bindDirective = function (el: HTMLInputElement) {
|
||||
createEffect(function () {
|
||||
const v = value()
|
||||
if (v == null) {
|
||||
el.value = v
|
||||
return
|
||||
}
|
||||
|
||||
const nodeV = el.value
|
||||
if ((v === 0 && nodeV === '') || v != nodeV) {
|
||||
el.value = v + ''
|
||||
}
|
||||
})
|
||||
}
|
||||
const targetValue = function (el: HTMLInputElement) {
|
||||
if (el.validity.badInput) {
|
||||
return value()
|
||||
}
|
||||
|
||||
if (el.value == '') {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return el.valueAsNumber
|
||||
}
|
||||
|
||||
return [untrack(value), bindDirective, targetValue]
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@typebot.io/nextjs",
|
||||
"version": "0.2.8",
|
||||
"version": "0.2.9",
|
||||
"description": "Convenient library to display typebots on your Next.js website",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@typebot.io/react",
|
||||
"version": "0.2.8",
|
||||
"version": "0.2.9",
|
||||
"description": "Convenient library to display typebots on your React app",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
|
Reference in New Issue
Block a user