瀏覽代碼

Refactor Input component: Remove unnecessary Input components

Tatiana Inama 6 年之前
父節點
當前提交
0e2ef7f912

+ 21 - 115
recipes/src/components/Input/index.tsx

@@ -1,95 +1,9 @@
-import React, { InputHTMLAttributes } from 'react';
-import TextField, { HelperText, Input as Field } from '@material/react-text-field';
-import classNames from 'classnames';
-import Button from 'components/Button';
-import Icon from '../Icon';
+import React, { InputHTMLAttributes, ChangeEvent } from 'react';
 import {FieldProps} from 'formik';
+
 import '@material/react-text-field/dist/text-field.css';
 import './styles.scss';
 
-type InputProps = {
-	label: string,
-	value: string|number,
-	onChange: (e: any) => void,
-	textarea?: boolean,
-	onKeyDown? : (e: any) => void,
-	onBlur?: (e: React.FocusEvent) => void,
-	type?: 'text'|'number',
-	style?: 'display'|'regular',
-	icon?: string,
-	button?: {
-		icon: string,
-		onClick: () => void,
-	},
-	field?: any,
-	className?: string,
-};
-
-const Input = ({
-	label,
-	textarea,
-	value,
-	onChange,
-	onKeyDown,
-	onBlur,
-	type = 'text',
-	style = 'regular',
-	icon,
-	button,
-	field = { name: '', value: '', onBlur: ()=>{}, onChange: ()=>{}},
-	className = '',
-
-}: InputProps) => {
-	const fieldClasses = classNames(
-		'cbk-input',
-		{
-			'cbk-input--prefilled': value!=='',
-			[`cbk-input-${style}`]: true,
-			'mdc-text-field--no-label': style === 'display',
-		}
-	);
-	const containerClasses = classNames({
-		'cbk-input-container': !!icon || !!button,
-		[className]: className,
-	})
-
-	return (
-		<div className={containerClasses}>
-			{
-				icon && 
-				<Icon
-					icon={icon}
-					width={46}
-					fill='#9E9E9E'
-				/>
-			}
-			<div className="cbk-input-box">
-				<TextField
-					label={field.name || label}
-					textarea={textarea}
-					className={fieldClasses}
-					fullWidth={style === 'display'}
-				>
-					<Field
-						value={value}
-						//@ts-ignore
-						onChange={onChange}
-						onKeyDown={onKeyDown}
-						onBlur={onBlur}
-						type={type}
-						min={0}
-						rows={1}
-						placeholder={style === 'display' ? label : ''}
-					/>
-				</TextField>
-			</div>
-			{
-				button && 
-				<Button className='cbk-input-button' onClick={button.onClick} icon={button.icon} />
-			}
-		</div>
-)};
-
 export const Input2: React.FunctionComponent<InputHTMLAttributes<{}>> = (props) => (
 	<div className='cbk-input-2'>
 		<input
@@ -99,47 +13,39 @@ export const Input2: React.FunctionComponent<InputHTMLAttributes<{}>> = (props)
 	</div>
 )
 
-interface LightInputProps extends FieldProps {
+type InputProps = {
+	[x: string]: any,
 	label?: string,
-	type?: 'textarea' | 'text' | 'number',
-};
-
-export const LightInput = (label?: string, type = 'text') => ({ field }: FieldProps) => {
-	const Tag = type === 'textarea' ? 'textarea' : 'input';
-
+	type?: 'text' | 'number' ,
+	onChange?: (e: React.FormEvent<HTMLInputElement>) => void,
+}
+export const Input = ({label, type = 'text', ...props }: InputProps) => {
 	return (
 		<div className="cbk-light-input">
-			{ label && (<label>{label}</label>)}
-			<Tag
-				className={field.value ? 'has-value': ''}
+			{ label && (<label htmlFor={props.name}>{label}</label>)}
+			<input
+				className={props.value ? 'has-value': ''}
 				type={type}
-				{...field}
-
+				{...props}
 			/>
-			{/* {
-				type === 'text' ?
-				(<input className={field.value ? 'has-value': ''} type="text" onChange={field.onChange} name={field.name} onBlur={field.onBlur} />) :
-				(<textarea className={field.value ? 'has-value': ''} onChange={field.onChange} name={field.name} onBlur={field.onBlur} />)
-			} */}
-			
 			<span></span>
 		</div>
-	);
-};
+	)
+}
 
-type NoFormikProps = {
+type TextareaProps = {
 	[x: string]: any,
 	label?: string,
-	type?: 'input' | 'textarea',
+	type?: 'text' | 'number' ,
+	onChange?: (e: ChangeEvent<HTMLTextAreaElement>) => void,
 }
-export const LightInputNotFormk = ({label, type = 'input', ...props }: NoFormikProps) => {
-	const Tag = type;
+
+export const Textarea = ({label, type = 'text', ...props }: TextareaProps) => {
 	return (
 		<div className="cbk-light-input">
-			{ label && (<label>{label}</label>)}
-			<Tag
+			{ label && (<label htmlFor={props.name}>{label}</label>)}
+			<textarea
 				className={props.value ? 'has-value': ''}
-				type={type}
 				{...props}
 			/>
 			<span></span>

+ 37 - 18
recipes/src/components/RecipeForm/index.tsx

@@ -1,11 +1,11 @@
-import React, { useState, Component } from 'react';
+import React, { useState, Component, JSXElementConstructor } from 'react';
 
 import Recipe, { Ingredient, Suggestion, _ingredient, _subRecipe, DBRecipe } from 'types/recipes';
 import { Grid, Row, Cell } from '@material/react-layout-grid';
 import './styles.scss';
 import sample_image from 'sample.png';
 import { MeasuresTypes } from 'services/measurements';
-import { LightInput as Input } from 'components/Input';
+import { Input, Textarea } from 'components/Input';
 import Button from 'components/Button';
 import Dialog from 'components/DialogConverter';
 import { GetMeasure } from 'services/measurements';
@@ -180,24 +180,43 @@ const SubrecipeForm = (props: any) => {
 
 type FormikInputProps = {
   [x: string]: any,
-  label?: string,
   name: string,
+  label?: string,
 };
 
-const FormikInput = ({label, ...props}: FormikInputProps) => {
+const FormikInput = ({ label, ...props }: FormikInputProps)  => {
   const [field, meta] = useField(props);
   return (
     <>
-      {
-        label && (<label htmlFor={props.id || props.name}>{label}</label>)
-      }
-      <input className="text-input" {...field} {...props} />
+      <Input
+        label={label}
+        { ...props }
+        { ...field }
+      />
+      {/* TODO: Add validation errors when onSubmit */}
       {meta.touched && meta.error ? (
         <div className="error">{meta.error}</div>
       ) : null}
     </>
-  )
-}
+  );
+};
+
+const FormikTextarea = ({ label, ...props }: FormikInputProps)  => {
+  const [field, meta] = useField(props);
+  return (
+    <>
+      <Textarea
+        label={label}
+        { ...props }
+        { ...field }
+      />
+      {/* TODO: Add validation errors when onSubmit */}
+      {meta.touched && meta.error ? (
+        <div className="error">{meta.error}</div>
+      ) : null}
+    </>
+  );
+};
 
 const RecipeForm = <T extends Recipe|DBRecipe>({ initialValues, onSubmit }: RecipeFormProps<T>) => (
   <>
@@ -218,9 +237,9 @@ const RecipeForm = <T extends Recipe|DBRecipe>({ initialValues, onSubmit }: Reci
                 <img src={sample_image} style={{ width: '100%' }}/>
               </Cell>
               <Cell columns={10}>
-                <Field name='name' component={Input('name')}/>
+                <FormikInput name='name' label='name' />
         
-                <Field name='summary' component={Input('summary', 'textarea')}/>
+                <FormikTextarea name='summary' label='summary' />
               </Cell>
             </Row>
             
@@ -228,10 +247,10 @@ const RecipeForm = <T extends Recipe|DBRecipe>({ initialValues, onSubmit }: Reci
             <section>
               <Row>
                 <Cell columns={3}>
-                  <Field name='author.name' component={Input('name')}/>
+                  <FormikInput name='author.name' label='name' />
                 </Cell>
                 <Cell columns={3}>
-                  <Field name='author.website' component={Input('website')}/>
+                  <FormikInput name='author.website' label='website' />
                 </Cell>
               </Row>
             </section>
@@ -240,16 +259,16 @@ const RecipeForm = <T extends Recipe|DBRecipe>({ initialValues, onSubmit }: Reci
             <section>
               <Row>
                 <Cell columns={3}>
-                  <Field name='details.preparationTime' component={Input('preparation time')}/>
+                  <FormikInput name='details.preparationTime' label='preparation time' />
                 </Cell>
                 <Cell columns={3}>
-                  <Field name='details.cookingTime' component={Input('cooking time')}/>
+                  <FormikInput name='details.cookingTime' label='cooking time' />
                 </Cell>
                 <Cell columns={3}>
-                  <Field name='details.servings' component={Input('servings', 'number')}/>
+                  <FormikInput name='details.servings' label='servings' type='number' />
                 </Cell>
                 <Cell columns={3}>
-                  <Field name='details.url' component={Input('recipe url')}/>
+                  <FormikInput name='details.url' label='recipe url' />
                 </Cell>
               </Row>
               <Row>

+ 2 - 7
recipes/src/components/TagInput/index.tsx

@@ -2,16 +2,11 @@
 import React, { Component } from 'react';
 import { ChipSet, Chip } from '@material/react-chips';
 import MaterialIcon from '@material/react-material-icon';
-import Input, {LightInputNotFormk} from 'components/Input';
+import { Input } from 'components/Input';
 import { uniq } from 'ramda';
 
 import './styles.scss';
 
-interface Tag {
-  label?: string,
-  id?: string
-};
-
 type TagInputProps = {
   onNewTag: (tags: string[]) => void,
   initialValues?: string[],
@@ -53,7 +48,7 @@ class TagInput extends Component<TagInputProps, TagInputState> {
   render() {
     return (
       <div className="cbk-tag-input">
-        <LightInputNotFormk
+        <Input
           label={this.props.label}
           value={this.state.newTag}
           onChange={(e: any) => this.setState({newTag: e.currentTarget.value})}