Untitled
unknown
typescript
a year ago
34 kB
4
Indexable
Never
import { useCallback, useEffect, useRef, useState } from "react"; import useResponsive from "src/hooks/useResponsive"; import {LocalizationProvider, DatePicker, TimePicker} from '@mui/x-date-pickers' import {FormControlLabel, Checkbox, RadioGroup, Radio} from '@mui/material' import { useSetRecoilState } from "recoil"; import { captchaAtom } from "src/atoms/captcha"; import { GoogleReCaptchaProvider, GoogleReCaptcha } from 'react-google-recaptcha-v3'; import { useClickAway } from "use-click-away"; import PhoneInput from 'react-phone-input-2' import globalSettings from "src/constants/globalSettings_backup"; import PlacesAutocomplete, {geocodeByAddress} from 'react-places-autocomplete'; import { AddListItemButton, AddressContainer, AddressOption, AddressOptions, CheckBoxesContainer, CheckBoxesWrapper, ChipStyle, ChipText, ChipX, ConsetContainer, Container, FileInput, HTMLBlockStyle, InputStyle, ListContainer, ListInput, ListInputContainer, ListItem, ListItemText, ListItemsContainer, MultiSelectedOption, Option, PageNavigation, PageNavigationContainer, PhoneContainer, RemoveListItemButton, Required, RoundedInputContainer, RoundedInputStyle, RoundedOption, RoundedSelectOptionsStyle, RoundedSelectStyle, RoundedSelectStyleProps, RoundedSelectedOption, SectionLine, SelectArrow, SelectContainer, SelectStyle, SelectedOption, TextareaStyle, Title, UploadButton, UploadIcon, UploadText } from "./styles"; import { ReactComponent as SearchIcon } from "../../assets/icons/search.svg"; import { InputProps } from "../../types/input"; import 'react-phone-input-2/lib/style.css' type TextFieldProps = { title: string; placeholder: string; required?: boolean; type?: 'text' | 'number' | 'hidden'; defaultValue?: string; size?: string; onChange?: (data : any) => void; errorMessage?: string; layoutGridColumnSpan?: string; } export function TextField({title, placeholder, required, type = 'text', defaultValue, size, onChange, errorMessage, layoutGridColumnSpan} : TextFieldProps){ return ( <Container sx={layoutGridColumnSpan ? {gridColumn: `span ${layoutGridColumnSpan}`} : {}}> <InputStyle value={defaultValue} type={type} placeholder={errorMessage || placeholder} placeholderOpacity={errorMessage ? 1 : 0.5} placeholderColor={errorMessage ? 'red' : globalSettings.Colors.bodyBlack} required={required} onChange={onChange} /> </Container> ) } type RoundedTextFieldProps = { placeholder: string; icon?: React.ReactNode; size?: string; onChange: (e:any) => void; width?: string; }; export function RoundedTextField({placeholder, icon, size, onChange, width} : RoundedTextFieldProps){ return ( <RoundedInputContainer minWidth={width} width={width} > {icon || <SearchIcon />} <RoundedInputStyle placeholder={placeholder} onChange={(e)=>onChange(e)} /> </RoundedInputContainer> ) } type SelectProps = { title: string; options: { text: string; value: string; }[]; required?: boolean; size?: string; onSelect?: (item:string) => void; onChange?: (data : any) => void; errorMessage?: string; layoutGridColumnSpan?: string; } export function SelectDropDown ({title, options, required, size, onSelect, onChange, errorMessage, layoutGridColumnSpan} : SelectProps) { const [selectedOption, setSelectedOption] = useState<string | null>(null) const [showSelect, setShowSelect] = useState<boolean>(false) const showSelectDropDown = () => { setShowSelect(true) } const selectOption = (item : string) => { setSelectedOption(item) setShowSelect(false) if(onSelect){ onSelect(item) } if(onChange){ onChange({target: {value: item}}) } } const dropDownRef = useRef(null) useClickAway(dropDownRef, () => { setShowSelect(false) }) return ( <Container sx={layoutGridColumnSpan ? {gridColumn: `span ${layoutGridColumnSpan}`} : {}}> <Title>{title}{required?<Required>*</Required>:null}</Title> <SelectContainer onMouseDown={showSelectDropDown} ref={dropDownRef}> <SelectArrow selected={showSelect} /> <SelectedOption>{selectedOption || <div style={errorMessage ? {opacity: 1, color: 'red'} : {opacity: 0.5}}>{errorMessage || 'Please Select'}</div>}</SelectedOption> {showSelect? <SelectStyle defaultValue=""> {options.map((item, key) => ( <Option key={key} onClick={()=>selectOption(item.text)} selected={item.text===selectedOption}>{item.text}</Option> ))} </SelectStyle> :null} </SelectContainer> </Container> ) } type RoundedSelectProps = RoundedSelectStyleProps & { firstItem?: { title: string; onClick: () => void; }; placeholder?: string; options: { title: string; id: any; }[]; optionBackgroundColor?: string; optionTextColor?: string; size?: string; onSelect?: (item:any) => void; selectwidth?: string; width?: string; } export function RoundedSelect ({selectwidth, firstItem, options, placeholder, activetextcolor, bordercolor, arrowcolor, optionBackgroundColor, optionTextColor, size, onSelect, width} : RoundedSelectProps) { const [selectedOption, setSelectedOption] = useState<{title: string, id: any} | null>(null) const [showSelect, setShowSelect] = useState<boolean>(false) const showSelectDropDown = () => { setShowSelect(true) } const selectOption = (item : {title: string; id: any}) => { setSelectedOption(item) if(onSelect){ onSelect(item.id) } setShowSelect(false) } const dropDownRef = useRef(null) useClickAway(dropDownRef, () => { setShowSelect(false) }) const firstItemClick = () => { if(firstItem){ firstItem.onClick() } setSelectedOption(null) setShowSelect(false) } return ( <RoundedSelectStyle selected={showSelect} width={width} minWidth={width} ref={dropDownRef} onMouseDown={showSelectDropDown} activetextcolor={activetextcolor} bordercolor={bordercolor} arrowcolor={arrowcolor}> <SelectArrow selected={showSelect} /> <RoundedSelectedOption>{selectedOption?.title || placeholder}</RoundedSelectedOption> {showSelect? <RoundedSelectOptionsStyle defaultValue=""> {firstItem ? <RoundedOption backgroundColor={optionBackgroundColor} textcolor={optionTextColor} onClick={firstItemClick}>{firstItem.title}</RoundedOption> : null} {options.map((item, key) => ( <RoundedOption backgroundColor={optionBackgroundColor} textcolor={optionTextColor} key={key} onClick={()=>selectOption(item)} selected={item.id===selectedOption?.id}>{item.title}</RoundedOption> ))} </RoundedSelectOptionsStyle> :null} </RoundedSelectStyle> ) } type TextAreaProps = { title: string; placeholder: string; required?: boolean; size?: string; onChange?: (data : any) => void; layoutGridColumnSpan?: string; } export function Textarea ({title, placeholder, required, size, onChange, layoutGridColumnSpan} : TextAreaProps) { return ( <Container sx={layoutGridColumnSpan ? {gridColumn: `span ${layoutGridColumnSpan}`} : {}}> <TextareaStyle placeholder={placeholder} onChange={onChange} /> </Container> ) } type RadioProps = { options: { text: string; value: string; }[], name: string; size?: string; onChange?: (data : any) => void; layoutGridColumnSpan?: string; } export function RadioButtons ({options, name, size, onChange, layoutGridColumnSpan} : RadioProps) { useEffect(() => { if(onChange){ onChange({target: options[0]}) } // eslint-disable-next-line react-hooks/exhaustive-deps }, []) let radio_styles = { gap: '3.3vw', padding: '0.2vw', margin: '0.1vw 0.6vw 0.1vw 1vw', height: '1.5vw', width: '1.5vw', fontSize: '0.9vw !important', margin2: '0 0 0 -1.5vw', marginTop: '0' } const isMobile = useResponsive('down', 768) if(isMobile){ radio_styles = { gap: '7.5vw', padding: '0', margin: '0vw 3vw 0vw 0vw', height: '7vw', width: '7vw', fontSize: '3.8vw !important', margin2: '0 0 0 -1vw', marginTop: '5.5vw' } }else{ radio_styles = { gap: '3.3vw', padding: '0.2vw', margin: '0.1vw 0.6vw 0.1vw 1vw', height: '1.5vw', width: '1.5vw', fontSize: '0.9vw !important', margin2: '0 0 0 -1.5vw', marginTop: '0' } } return ( <RadioGroup aria-labelledby={name} defaultValue={options[0].value} name={name} row sx={{marginTop: radio_styles.marginTop, gap: radio_styles.gap, columnSpan: layoutGridColumnSpan || null}} > {options.map((item, index) => <FormControlLabel sx={{'& > span:first-of-type': {'&:hover': {backgroundColor: globalSettings.Colors.primaryLight1}, padding: radio_styles.padding, margin: radio_styles.margin, '& > svg': {height: radio_styles.height, width: radio_styles.width}}, '& > span:last-of-type': { fontSize: radio_styles.fontSize }, margin: radio_styles.margin2}} onChange={onChange} key={index} value={item.value} control={<Radio sx={{'&.Mui-checked':{color:"#66A4F9"}}} />} label={item.text} />)} </RadioGroup> ) } type CheckBoxesProps = { label: string; options: { text: string; value: string; }[], required?: boolean; size?: string; } export function CheckBoxes ({label, options, required, size} : CheckBoxesProps) { return ( <CheckBoxesContainer> <Title>{label}{required && <Required>*</Required>}</Title> <CheckBoxesWrapper> {options.map((item, index)=><FormControlLabel control={<Checkbox />} label={item.text} key={index} />)} </CheckBoxesWrapper> </CheckBoxesContainer> ) } type HTMLBlockProps = { content: string; size?: string; } export function HTMLBlock ({content, size} : HTMLBlockProps) { return ( <HTMLBlockStyle dangerouslySetInnerHTML={{__html: content}} /> ) } export function Section ({size}:{size?: string}) { return <SectionLine /> } type DateProps = { label: string; size?: string; }; export function MultiSelect ({title, options, required, size, onSelect, onChange, errorMessage, layoutGridColumnSpan} : SelectProps) { const [showSelect, setShowSelect] = useState<boolean>(false) const showSelectDropDown = (e : React.MouseEvent) => { const target = e.target as HTMLElement; if(target){ if(target.classList.contains('chip')){ return } } setShowSelect(true) } const [selectedOptions, setSelectedOptions] = useState<string[]>([]) const selectOption = (item : string) => { if(selectedOptions.includes(item)){ const newSelectedOptions = selectedOptions.filter(option=>option!==item) setSelectedOptions(newSelectedOptions) if(onChange){ onChange({target: {value: newSelectedOptions}}) } }else{ setSelectedOptions([...selectedOptions, item]) if(onChange){ onChange({target: {value: [...selectedOptions, item]}}) } } setShowSelect(false) } const removeChip = (text : string) => { if(onChange){ setSelectedOptions(selectedOptions.filter(item=>item!==text)) onChange({target: {value: selectedOptions.filter(item=>item!==text).length === 0 ? null : selectedOptions.filter(item=>item!==text)}}) } } const Chip = ({text} : {text: string}) => <ChipStyle className="chip" onClick={()=>removeChip(text)}><ChipText>{text}</ChipText><ChipX /></ChipStyle> const dropDownRef = useRef(null) useClickAway(dropDownRef, () => { setShowSelect(false) }) return ( <Container sx={layoutGridColumnSpan ? {gridColumn: `span ${layoutGridColumnSpan}`} : {}}> <Title>{title}{required?<Required>*</Required>:null}</Title> <SelectContainer onMouseDown={showSelectDropDown} ref={dropDownRef}> <SelectArrow selected={showSelect} /> <MultiSelectedOption>{selectedOptions.length > 0 ? selectedOptions.map((item, index)=> ( <Chip text={item} key={index} /> )) : <div style={{opacity: 0.5}}>Please Select</div>}</MultiSelectedOption> {showSelect? <SelectStyle defaultValue=""> {options.map((item, key) => ( <Option key={key} onClick={()=>selectOption(item.text)} selected={selectedOptions.includes(item.text)}>{item.text}</Option> ))} </SelectStyle> :null} </SelectContainer> </Container> ) } export function Date({ label, size }: DateProps) { return ( <div> <LocalizationProvider> <DatePicker label={label} /> </LocalizationProvider> </div> ); } export function Time({label, size} : DateProps) { return ( <div> <LocalizationProvider> <TimePicker label={label} /> <style> {` .MuiButtonBase-root { line-height: 1.5; } `} </style> </LocalizationProvider> </div> ) } type AddressProps = { required?: boolean; inputs: { id: number; label: string; placeholder: string; name: string; autocompleteAttribute?: string; }[]; onChange?: (data:any) => void; } type Suggestion = { description: string; place_id: string; } type PlacesAutocompleteProps = { getInputProps: any; suggestions: Suggestion[]; getSuggestionItemProps: any; loading: boolean; } export function Address({required, inputs, onChange} : AddressProps) { const [address, setAddress] = useState<string>(''); const handleChange = (newAddress: string) => { setAddress(newAddress); onGlobalChange(); }; const inputMap = { address: 1, city: 2, state: 3, postcode: 4, country: 5 } const handleSelect = (selectedAddress: string) => { geocodeByAddress(selectedAddress) .then((results: google.maps.GeocoderResult[]) => { const addressComponents = results[0].address_components; let addressLineOne = '' for (let i = 0; i < addressComponents.length; i+=1) { const component = addressComponents[i]; const componentType = component.types[0]; switch (componentType) { case "street_number": addressLineOne = `${addressLineOne} ${component.long_name}` break; case "route": addressLineOne = `${addressLineOne} ${component.long_name}` break; case "establishment": addressLineOne = `${addressLineOne} ${component.long_name}` break; case "locality": addressLineOne = `${addressLineOne}, ${component.long_name}` break; case "administrative_area_level_1": { const stateInputElem = document.getElementsByClassName('addressForm')[inputMap.state] as HTMLInputElement if(stateInputElem){ stateInputElem.value = component.long_name } } break; case "country": { const countryInputElem = document.getElementsByClassName('addressForm')[inputMap.country] as HTMLInputElement if(countryInputElem){ countryInputElem.value = component.long_name } } break; case 'administrative_area_level_2': { const cityInputElem = document.getElementsByClassName('addressForm')[inputMap.city] as HTMLInputElement; if (cityInputElem) { cityInputElem.value = component.short_name; } break; } case 'postal_code': { const postalCodeInputElem = document.getElementsByClassName('addressForm')[inputMap.postcode] as HTMLInputElement; if (postalCodeInputElem) { postalCodeInputElem.value = component.long_name; } break; } default: break; } const addressInputElem = document.getElementsByClassName('addressForm')[inputMap.address] as HTMLInputElement if(addressInputElem){ setAddress(addressLineOne) } onGlobalChange(); } }) .catch((error: any) => console.error('Error', error)); }; const onGlobalChange = () => { const elem = document.getElementsByClassName('addressForm') as HTMLCollectionOf<HTMLInputElement> if(onChange){ setTimeout(() => { const addressMap = { 1: elem[inputMap.address].value, 3: elem[inputMap.city].value, 4: elem[inputMap.state].value, 5: elem[inputMap.postcode].value, 6: elem[inputMap.country].value } onChange({target: {value: addressMap}}) }, 300) } } return ( <> {inputs.map(({id, label, placeholder, name}, index) => { if(index === 0){ return ( <PlacesAutocomplete key={index} value={address} onChange={handleChange} onSelect={handleSelect} > {({ getInputProps, suggestions, getSuggestionItemProps }:PlacesAutocompleteProps) => ( <AddressContainer sx={{gridColumn: 'span 6'}}> <Container> <Title>{label}{required && <Required>*</Required>}</Title> <InputStyle className="addressForm" {...getInputProps()} type='text' placeholder={placeholder} required={required} /> </Container> <AddressOptions> {suggestions?.map((suggestion: Suggestion, key:number) => { const style = { cursor: 'pointer' }; return ( <AddressOption {...getSuggestionItemProps(suggestion, { style, })} key={key} > {suggestion.description} </AddressOption> ); })} </AddressOptions> </AddressContainer> )} </PlacesAutocomplete> ) } return ( <Container key={index} sx={{gridColumn: 'span 6'}}> <Title>{label}{required && <Required>*</Required>}</Title> <InputStyle onChange={onGlobalChange} className="addressForm" type='text' placeholder={placeholder} required={required} /> </Container> ) })} </> ); } type PhoneProps = { label: string; required?: boolean; placeholder?: string; size?: string; onChange?: (data : any) => void; } export function Phone({label, required, placeholder, size, onChange} : PhoneProps) { const [value, setValue] = useState('') const setPhone = (data : any) => { setValue(data) if(onChange){ onChange(data) } } return ( <PhoneContainer> {label!==''?<Title>{label}{required && <Required>*</Required>}</Title>:null} <PhoneInput country='au' value={value} onChange={setPhone} placeholder={placeholder} /> </PhoneContainer> ) } type EmailProps = { title: string; placeholder: string; required?: boolean; size?: string; onChange?: (data : any) => void; errorMessage?: string; layoutGridColumnSpan?: string; } export function Email({title, placeholder, required, size, onChange, errorMessage, layoutGridColumnSpan} : EmailProps) { return ( <Container sx={layoutGridColumnSpan ? {gridColumn: `span ${layoutGridColumnSpan}`} : {}}> <InputStyle id='email' onChange={onChange} type='email' placeholder={errorMessage || placeholder} placeholderOpacity={errorMessage ? 1 : 0.5} placeholderColor={errorMessage ? 'red' : globalSettings.Colors.bodyBlack} required={required} /> </Container> ) } export function FileUpload({size} : {size?: string}) { const onFileUpload = (file: File | null) => { console.log(`uploaded ${file?.name}`) } const [selectedFile, setSelectedFile] = useState<File | null>(null); const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => { const file = event.target?.files ? event.target.files[0] : null; setSelectedFile(file); onFileUpload(file); }; const fileInputRef = useRef<HTMLInputElement | null>(null); const onUploadButtonClick = () => { if(fileInputRef.current){ fileInputRef.current.click() } } return ( <UploadButton onClick={onUploadButtonClick}> <UploadIcon /> <UploadText>{selectedFile ? selectedFile.name : 'Upload File'}</UploadText> <FileInput ref={fileInputRef} type="file" onChange={handleFileChange} /> </UploadButton> ); } export function CaptchaComponent () { const setCaptcha = useSetRecoilState(captchaAtom) const onCaptchaChange = useCallback(async (e : any) => { const url = 'https://automation.orangedigital.au/api/v1.0/pilot-partners-development/recaptcha'; try { const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: new URLSearchParams({ response: e, }) }); const data = await response.json(); const { success, score } = data; if (success && score >= 0.5) { setCaptcha(true) } else { setCaptcha(false) } } catch (error) { setCaptcha(false) } // eslint-disable-next-line react-hooks/exhaustive-deps }, []) return ( <> <div id='captcha' style={{gridColumn: 'span 12'}} /> <GoogleReCaptchaProvider reCaptchaKey="6LeJa1UnAAAAAI3kR1QWAcsaSV4ugwjvrZFMiuzP" container={{ element: "captcha", parameters: { theme: 'light', } }} > <GoogleReCaptcha onVerify={onCaptchaChange} /> </GoogleReCaptchaProvider> </> ) } type WebsiteProps = { title: string; placeholder: string; required?: boolean; size?: string; } export function Website({title, placeholder, required, size} : WebsiteProps) { return ( <Container> <Title>{title}{required && <Required>*</Required>}</Title> <InputStyle type='text' placeholder={placeholder} required={required} /> </Container> ) } type NameProps = { required?: boolean; inputs: { id: number; label: string; placeholder: string; name: string; autocompleteAttribute?: string; choices?: {text: string, value: string}[] }[]; } export function Name({required, inputs} : NameProps) { return ( <> {inputs.map(({id, label, placeholder, name, choices}, index) => ( <Container key={index}> {!choices?<Title>{label}{required && <Required>*</Required>}</Title>:null} {choices?<SelectDropDown title={label} options={choices} />:<InputStyle id={name} type='text' placeholder={placeholder} required={required} />} </Container> ) )} </> ); } type ListProps = { label: string; placeholder?: string; id: number; formId: number; size?: string; } export function List({label, placeholder, id, formId, size} : ListProps) { const [listItems, setListItems] = useState<string[]>([]) const listInputRef = useRef<HTMLInputElement>(null) const addListItem = () => { if(listInputRef.current && listInputRef.current.value.length > 0){ setListItems([...listItems, listInputRef.current.value]) } } const onKeyDown = (e : React.KeyboardEvent) => { if(e.key === 'Enter'){ addListItem() } } const removeListItem = (item: string) => { const newListItems = listItems.filter(e=>e!==item) setListItems(newListItems) } return ( <ListContainer> <Title>{label}</Title> <ListInputContainer> <ListInput onKeyDown={onKeyDown} placeholder={placeholder} ref={listInputRef} /> <AddListItemButton onMouseDown={addListItem} /> </ListInputContainer> <ListItemsContainer> {listItems.map((item, index) => ( <ListItem key={index}> <ListItemText>{item}</ListItemText> <RemoveListItemButton onClick={()=>removeListItem(item)} /> </ListItem> ))} </ListItemsContainer> </ListContainer> ) } type ConsetProps = { id: number; formId: number; label: string; inputs?: { id: string; label: string; name?: string; isHidden?: boolean; }[]; checkboxLabel: string; isRequired?: boolean; size?: string; } export function Consent ({label, id, formId, inputs, checkboxLabel, isRequired = true, size} : ConsetProps) { return ( <ConsetContainer> <Title>{label}{isRequired && <Required>*</Required>}</Title> <FormControlLabel control={<Checkbox />} label={checkboxLabel} /> </ConsetContainer> ) } type PageProps = { nextButton: { text: string; }; previousButton: { text: string; }; goToNextPage?: () => void; goToPreviousPage?: () => void; isFirstPage?: boolean; isLastPage?: boolean; } export function Page ({nextButton, previousButton, goToNextPage, goToPreviousPage, isFirstPage, isLastPage} : PageProps) { return ( <PageNavigationContainer> {!isFirstPage?<PageNavigation onClick={goToPreviousPage}>{previousButton.text}</PageNavigation>:null} {!isLastPage?<PageNavigation onClick={goToNextPage}>{nextButton.text}</PageNavigation>:null} </PageNavigationContainer> ) } export default function Input ({type, label, placeholder, isRequired, choices, defaultValue, content, inputs, id, formId, checkboxLabel, size, nextButton, previousButton, goToNextPage, goToPreviousPage, isFirstPage, isLastPage, onChange, errorMessage, layoutGridColumnSpan} : InputProps) { switch (type) { case 'text': if(placeholder){ return <TextField title={label} placeholder={placeholder} required={isRequired} layoutGridColumnSpan={layoutGridColumnSpan} onChange={onChange} errorMessage={errorMessage} /> } throw new Error('placeholder is invalid for text'); case 'textarea': if(placeholder){ return <Textarea title={label} placeholder={placeholder} required={isRequired} layoutGridColumnSpan={layoutGridColumnSpan} onChange={onChange} /> } throw new Error('placeholder is invalid for textarea'); case 'select': if(choices){ return <SelectDropDown title={label} required={isRequired} options={choices} layoutGridColumnSpan={layoutGridColumnSpan} onChange={onChange} errorMessage={errorMessage} /> } throw new Error('choices is invalid for select'); case 'multiselect': if(choices){ return <MultiSelect title={label} required={isRequired} options={choices} layoutGridColumnSpan={layoutGridColumnSpan} onChange={onChange} errorMessage={errorMessage} /> } throw new Error('choices is invalid for multiselect'); case 'number': if(placeholder){ return <TextField title={label} placeholder={placeholder} required={isRequired} type="number" layoutGridColumnSpan={layoutGridColumnSpan} /> } throw new Error('placeholder is invalid for number'); case 'checkbox': if(choices){ return null } throw new Error('choices is invalid for checkbox'); case 'radio': if(choices){ return <RadioButtons name={label} options={choices} onChange={onChange} /> } throw new Error('choices is invalid for radio'); case 'hidden': return <TextField title={label} placeholder='' type="hidden" defaultValue={defaultValue} /> case 'html': if(content){ return <HTMLBlock content={content} /> } throw new Error('content is invalid for html'); case 'section': return <Section /> case 'date': return <Date label={label} /> case 'time': return <Time label={label} /> case 'address': if(inputs){ return <Address inputs={inputs} onChange={onChange} /> } throw new Error('inputs is invalid for address'); case 'phone': return <Phone label={label} onChange={onChange} /> case 'email': if(placeholder){ return <Email title={label} placeholder={placeholder} required={isRequired} onChange={onChange} errorMessage={errorMessage} layoutGridColumnSpan={layoutGridColumnSpan} /> } throw new Error('placeholder is invalid for email'); case 'fileupload': return <FileUpload /> case 'captcha': return <CaptchaComponent /> case 'website': if(placeholder){ return <Website title={label} placeholder={placeholder} required={isRequired} /> } throw new Error('placeholder is invalid for website'); case 'name': if(inputs){ return <Name inputs={inputs} /> } throw new Error('inputs is invalid for name'); case 'list': if(placeholder){ return <List label={label} placeholder={placeholder} id={id} formId={formId} /> } throw new Error('placeholder is invalid for list'); case 'consent': if(checkboxLabel){ return <Consent label={label} id={id} formId={formId} checkboxLabel={checkboxLabel} isRequired={isRequired} /> } throw new Error('checkboxLabel is invalid for consent'); case 'page': if(nextButton && previousButton && goToNextPage && goToPreviousPage && isFirstPage!==undefined && isLastPage!==undefined){ return <Page nextButton={nextButton} previousButton={previousButton} goToNextPage={goToNextPage} goToPreviousPage={goToPreviousPage} isFirstPage={isFirstPage} isLastPage={isLastPage} /> } throw new Error('nextButton or previousButton or goToNextPage or goToPreviousPage or isFirstPage or isLastPage is invalid for page'); default: throw new Error('type is invalid for input'); } }