feat(inputs): ✨ Add Phone number input
This commit is contained in:
@ -10,15 +10,18 @@
|
||||
"fast-equals": "^2.0.4",
|
||||
"models": "*",
|
||||
"react-frame-component": "^5.2.1",
|
||||
"react-phone-number-input": "^3.1.44",
|
||||
"react-scroll": "^1.8.4",
|
||||
"react-transition-group": "^4.4.2",
|
||||
"utils": "*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "^21.0.1",
|
||||
"@rollup/plugin-json": "^4.1.0",
|
||||
"@rollup/plugin-node-resolve": "^13.1.3",
|
||||
"@rollup/plugin-typescript": "^8.3.0",
|
||||
"@types/react": "^17.0.38",
|
||||
"@types/react-phone-number-input": "^3.0.13",
|
||||
"@types/react-scroll": "^1.8.3",
|
||||
"@types/react-transition-group": "^4.4.4",
|
||||
"autoprefixer": "^10.4.1",
|
||||
|
@ -1,6 +1,7 @@
|
||||
import resolve from '@rollup/plugin-node-resolve'
|
||||
import commonjs from '@rollup/plugin-commonjs'
|
||||
import typescript from '@rollup/plugin-typescript'
|
||||
import json from '@rollup/plugin-json'
|
||||
import dts from 'rollup-plugin-dts'
|
||||
import postcss from 'rollup-plugin-postcss'
|
||||
import { terser } from 'rollup-plugin-terser'
|
||||
@ -28,6 +29,7 @@ export default [
|
||||
plugins: [
|
||||
peerDepsExternal(),
|
||||
resolve(),
|
||||
json(),
|
||||
commonjs(),
|
||||
typescript({ tsconfig: './tsconfig.json' }),
|
||||
postcss({
|
||||
|
@ -38,6 +38,10 @@
|
||||
--typebot-header-border: none;
|
||||
--typebot-header-shadow: none;
|
||||
--typebot-header-max-width: 1000px;
|
||||
|
||||
/* Phone input */
|
||||
--PhoneInputCountryFlag-borderColor: transparent;
|
||||
--PhoneInput-color--focus: transparent;
|
||||
}
|
||||
|
||||
/* Hide scrollbar for Chrome, Safari and Opera */
|
||||
|
@ -56,6 +56,7 @@ const InputChatStep = ({
|
||||
case InputStepType.NUMBER:
|
||||
case InputStepType.EMAIL:
|
||||
case InputStepType.URL:
|
||||
case InputStepType.PHONE:
|
||||
return <TextForm step={step} onSubmit={handleSubmit} />
|
||||
case InputStepType.DATE:
|
||||
return <DateForm options={step.options} onSubmit={handleSubmit} />
|
||||
|
@ -1,6 +1,7 @@
|
||||
import {
|
||||
EmailInputStep,
|
||||
NumberInputStep,
|
||||
PhoneNumberInputStep,
|
||||
TextInputStep,
|
||||
UrlInputStep,
|
||||
} from 'models'
|
||||
@ -9,7 +10,12 @@ import { SendButton } from '../SendButton'
|
||||
import { TextInput } from './TextInputContent'
|
||||
|
||||
type TextFormProps = {
|
||||
step: TextInputStep | EmailInputStep | NumberInputStep | UrlInputStep
|
||||
step:
|
||||
| TextInputStep
|
||||
| EmailInputStep
|
||||
| NumberInputStep
|
||||
| UrlInputStep
|
||||
| PhoneNumberInputStep
|
||||
onSubmit: (value: string) => void
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@ import {
|
||||
NumberInputStep,
|
||||
InputStepType,
|
||||
UrlInputStep,
|
||||
PhoneNumberInputStep,
|
||||
} from 'models'
|
||||
import React, {
|
||||
ChangeEvent,
|
||||
@ -12,14 +13,20 @@ import React, {
|
||||
useEffect,
|
||||
useRef,
|
||||
} from 'react'
|
||||
import PhoneInput, { Value } from 'react-phone-number-input'
|
||||
|
||||
type TextInputProps = {
|
||||
step: TextInputStep | EmailInputStep | NumberInputStep | UrlInputStep
|
||||
step:
|
||||
| TextInputStep
|
||||
| EmailInputStep
|
||||
| NumberInputStep
|
||||
| UrlInputStep
|
||||
| PhoneNumberInputStep
|
||||
onChange: (value: string) => void
|
||||
}
|
||||
|
||||
export const TextInput = ({ step, onChange }: TextInputProps) => {
|
||||
const inputRef = useRef<HTMLInputElement>(null)
|
||||
const inputRef = useRef<any>(null)
|
||||
|
||||
useEffect(() => {
|
||||
if (!inputRef.current) return
|
||||
@ -30,6 +37,10 @@ export const TextInput = ({ step, onChange }: TextInputProps) => {
|
||||
e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
|
||||
) => onChange(e.target.value)
|
||||
|
||||
const handlePhoneNumberChange = (value?: Value | undefined) => {
|
||||
onChange(value as string)
|
||||
}
|
||||
|
||||
switch (step.type) {
|
||||
case InputStepType.TEXT: {
|
||||
return step.options?.isLong ? (
|
||||
@ -88,6 +99,17 @@ export const TextInput = ({ step, onChange }: TextInputProps) => {
|
||||
/>
|
||||
)
|
||||
}
|
||||
case InputStepType.PHONE: {
|
||||
return (
|
||||
<PhoneInput
|
||||
ref={inputRef}
|
||||
onChange={handlePhoneNumberChange}
|
||||
placeholder={
|
||||
step.options?.labels?.placeholder ?? 'Your phone number...'
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,8 @@ import { TypebotContext } from '../contexts/TypebotContext'
|
||||
import Frame from 'react-frame-component'
|
||||
//@ts-ignore
|
||||
import style from '../assets/style.css'
|
||||
//@ts-ignore
|
||||
import phoneNumberInputStyle from 'react-phone-number-input/style.css'
|
||||
import { ConversationContainer } from './ConversationContainer'
|
||||
import { AnswersContext } from '../contexts/AnswersContext'
|
||||
import { Answer, BackgroundType, PublicTypebot } from 'models'
|
||||
@ -39,7 +41,12 @@ export const TypebotViewer = ({
|
||||
return (
|
||||
<Frame
|
||||
id="typebot-iframe"
|
||||
head={<style>{style}</style>}
|
||||
head={
|
||||
<style>
|
||||
{phoneNumberInputStyle}
|
||||
{style}
|
||||
</style>
|
||||
}
|
||||
style={{ width: '100%', height: '100%', border: 'none' }}
|
||||
>
|
||||
<style
|
||||
|
1
packages/models/.gitignore
vendored
1
packages/models/.gitignore
vendored
@ -3,5 +3,4 @@ node_modules
|
||||
.env
|
||||
|
||||
dist
|
||||
types
|
||||
yarn-error.log
|
@ -2,7 +2,7 @@
|
||||
"name": "models",
|
||||
"version": "1.0.0",
|
||||
"main": "dist/index.js",
|
||||
"types": "types/index.d.ts",
|
||||
"types": "dist/types/index.d.ts",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
@ -14,6 +14,6 @@
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"dev": "tsc --watch"
|
||||
"dev": "tsc --watch --preserveWatchOutput"
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ export type InputStep =
|
||||
| EmailInputStep
|
||||
| UrlInputStep
|
||||
| DateInputStep
|
||||
| PhoneNumberInputStep
|
||||
|
||||
export enum InputStepType {
|
||||
TEXT = 'text input',
|
||||
@ -13,6 +14,7 @@ export enum InputStepType {
|
||||
EMAIL = 'email input',
|
||||
URL = 'url input',
|
||||
DATE = 'date input',
|
||||
PHONE = 'phone number input',
|
||||
}
|
||||
|
||||
export type TextInputStep = StepBase & {
|
||||
@ -40,6 +42,11 @@ export type DateInputStep = StepBase & {
|
||||
options?: DateInputOptions
|
||||
}
|
||||
|
||||
export type PhoneNumberInputStep = StepBase & {
|
||||
type: InputStepType.PHONE
|
||||
options?: InputOptionsBase
|
||||
}
|
||||
|
||||
export type DateInputOptions = {
|
||||
labels?: { button?: string; from?: string; to?: string }
|
||||
hasTime?: boolean
|
||||
|
@ -7,7 +7,7 @@
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"declaration": true,
|
||||
"declarationDir": "./types",
|
||||
"declarationDir": "./dist/types",
|
||||
"outDir": "./dist"
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user