-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b5238c7
commit 472a30d
Showing
8 changed files
with
416 additions
and
2 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
145 changes: 145 additions & 0 deletions
145
src/components/FormFields/TextFieldMultiline/TextFieldMultiline.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
import React, { useState } from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import classNames from 'classnames'; | ||
import { useField } from 'formik'; | ||
import TextareaAutosize from 'react-textarea-autosize'; | ||
import { Label } from '../Label'; | ||
import { HelperText } from '../HelperText'; | ||
import { Icon } from '../../Icon'; | ||
import { IconButton } from '../../IconButton'; | ||
import './TextFieldMultiline.scss'; | ||
|
||
const TextFieldMultiline = ({ | ||
addClass, | ||
autoComplete, | ||
children, | ||
domId, | ||
helperText, | ||
hideLabel, | ||
icon, | ||
iconPos, | ||
iconOnClick, | ||
iconSR, // screen reader text for icon | ||
label, | ||
maxLength, | ||
required, | ||
storybookErrorPreview, // For storybook only | ||
type, | ||
minRows, | ||
maxRows, | ||
onChange, | ||
...props | ||
}) => { | ||
// useField passes name, placeholder, value, onChange and onBlur | ||
const [field, meta] = useField({ ...props, type: 'text' }); | ||
const error = !!(meta.touched && meta.error && typeof meta.error === 'string') || storybookErrorPreview; | ||
const fieldHelperText = error ? meta.error : helperText; | ||
|
||
// eslint-disable-next-line react/destructuring-assignment | ||
const [value, setValue] = useState(props.value || ''); | ||
|
||
const onValueChange = (event) => { | ||
setValue(event.target.value) | ||
onChange(event) | ||
} | ||
|
||
const classes = classNames( | ||
'input-field-container', | ||
'input-field-text', | ||
{ 'no-helpertext': !fieldHelperText }, | ||
hideLabel && 'hidden-label', | ||
iconPos && `has-icon icon-${iconPos}`, | ||
addClass, | ||
{ error }, | ||
); | ||
|
||
const wrapperClasses = classNames( | ||
'input-field', | ||
'textarea-wrapper', | ||
{ error }, | ||
); | ||
|
||
const inputClasses = classNames( | ||
'input-field-textarea', | ||
{ error }, | ||
) | ||
const InputIcon = () => ( | ||
<> | ||
{iconOnClick ? | ||
<IconButton icon={icon} size={24} click={iconOnClick}>{iconSR}</IconButton> : | ||
<Icon name={icon} size={24} error={error || storybookErrorPreview} />} | ||
</> | ||
); | ||
// IMPORTANT: props and field should be speaded before the value and onChange, | ||
// field contains default onChange from formik which will override the defined onValueChange | ||
return ( | ||
<div className={classes} data-testid="test-id-input"> | ||
<div className={wrapperClasses}> | ||
<TextareaAutosize | ||
className={inputClasses} | ||
autoComplete={autoComplete} | ||
error={(error || storybookErrorPreview || false).toString()} | ||
maxLength={maxLength} | ||
required={required} | ||
type={type} | ||
minRows={minRows} | ||
maxRows={maxRows} | ||
// Spreading props, as required by Formik in useField: https://jaredpalmer.com/formik/docs/api/useField#example | ||
// eslint-disable-next-line react/jsx-props-no-spreading | ||
{...props} | ||
// eslint-disable-next-line react/jsx-props-no-spreading | ||
{...field} | ||
value={value} | ||
onChange={onValueChange} | ||
/> | ||
</div> | ||
{children} | ||
<Label | ||
color="gray4" | ||
display="block" | ||
fieldType="text" | ||
forId={domId} | ||
hideLabel={hideLabel} | ||
required={required} | ||
> | ||
{label} | ||
</Label> | ||
{iconPos && <InputIcon />} | ||
{ | ||
fieldHelperText && ( | ||
<HelperText error={error || storybookErrorPreview}> | ||
{fieldHelperText} | ||
</HelperText> | ||
) | ||
} | ||
</div > | ||
); | ||
}; | ||
|
||
TextFieldMultiline.defaultProps = { | ||
iconOnClick: null, | ||
}; | ||
|
||
TextFieldMultiline.propTypes = { | ||
addClass: PropTypes.string, | ||
autoComplete: PropTypes.oneOf(['on', 'off']), | ||
children: PropTypes.node, | ||
domId: PropTypes.string.isRequired, | ||
helperText: PropTypes.string, | ||
hideLabel: PropTypes.bool, | ||
icon: PropTypes.string, | ||
iconOnClick: PropTypes.func, | ||
iconPos: PropTypes.oneOf(['left', 'right']), | ||
iconSR: PropTypes.string, | ||
label: PropTypes.string, | ||
maxLength: PropTypes.number, | ||
required: PropTypes.bool, | ||
storybookErrorPreview: PropTypes.bool, | ||
type: PropTypes.string, | ||
minRows: PropTypes.number, | ||
maxRows: PropTypes.number, | ||
onChange: PropTypes.func, | ||
value: PropTypes.string, | ||
}; | ||
|
||
export default TextFieldMultiline; |
66 changes: 66 additions & 0 deletions
66
src/components/FormFields/TextFieldMultiline/TextFieldMultiline.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
.textarea-wrapper { | ||
padding: 1.15rem 0.75rem; | ||
} | ||
|
||
.input-field-textarea { | ||
border: none; | ||
width: 100%; | ||
} | ||
|
||
.input-field-textarea:focus { | ||
outline: none; | ||
} | ||
|
||
.input-field-textarea::-webkit-scrollbar { | ||
opacity: 1; | ||
-webkit-appearance: none; | ||
width: 7px; | ||
height: 3px; | ||
} | ||
.input-field-textarea::-webkit-scrollbar-thumb { | ||
opacity: 1; | ||
border-radius: 99px; | ||
background-color: rgba(156, 156, 156, 0.25); | ||
box-shadow: 0 0 1px rgba(255, 255, 255, 0.25); | ||
} | ||
|
||
.input-field-text { | ||
padding-top: $space-16; | ||
position: relative; | ||
|
||
&.icon-left { | ||
.input-field { | ||
padding-left: $space-48; | ||
} | ||
|
||
.icon { | ||
left: $space-16; | ||
} | ||
} | ||
|
||
&.icon-right { | ||
.input-field { | ||
padding-right: $space-48; | ||
} | ||
|
||
.icon { | ||
transform: translate(calc(-100% - 12px), -50%); | ||
} | ||
} | ||
|
||
&.hidden-label { | ||
label { | ||
@extend %screen-reader-text; | ||
} | ||
} | ||
|
||
.icon { | ||
position: absolute; | ||
top: rem(42px); | ||
transform: translate(0, -50%); | ||
} | ||
} | ||
|
||
input::-ms-clear { | ||
display: none; | ||
} |
67 changes: 67 additions & 0 deletions
67
src/components/FormFields/TextFieldMultiline/TextFieldMultiline.stories.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import React from "react"; | ||
import { storiesOf } from "@storybook/react"; | ||
import withFormik from "storybook-formik"; | ||
import { select, boolean } from "@storybook/addon-knobs"; | ||
import { withSmartKnobs } from "storybook-addon-smart-knobs"; | ||
import { TextFieldMultiline } from "./"; | ||
import iconArray from "../../Icon/helpers/getIconArray"; | ||
|
||
const TextFieldParameters = { | ||
component: TextFieldMultiline, | ||
componentSubtitle: "Utilize <TextFieldMultiline /> to present fields", | ||
jest: ["TextFieldMultiline"] | ||
}; | ||
|
||
storiesOf("components | Form Fields/Text Field - Multiline", module) | ||
.addParameters(TextFieldParameters) | ||
.addDecorator( | ||
withSmartKnobs({ | ||
ignoreProps: [ | ||
"icon", | ||
"touched", | ||
"type", | ||
"maxLength", | ||
"children", | ||
"storybookErrorPreview" | ||
] | ||
}) | ||
) | ||
.addDecorator(withFormik) | ||
.add("Default", () => ( | ||
<TextFieldMultiline | ||
label="Label" | ||
name="myInputName" | ||
domId="myDomId" | ||
helperText="Optional helper text" | ||
hideLabel={boolean("hideLabel", false)} | ||
icon={select("icon", iconArray, "placeholder-bold")} | ||
storybookErrorPreview={boolean("error", false)} | ||
required | ||
/> | ||
)) | ||
.add("With Min Rows", () => ( | ||
<TextFieldMultiline | ||
label="Label" | ||
name="myInputName" | ||
domId="myDomId" | ||
minRows="3" | ||
helperText="Optional helper text" | ||
hideLabel={boolean("hideLabel", false)} | ||
icon={select("icon", iconArray, "placeholder-bold")} | ||
storybookErrorPreview={boolean("error", false)} | ||
required | ||
/> | ||
)) | ||
.add("With Max Rows", () => ( | ||
<TextFieldMultiline | ||
label="Label" | ||
name="myInputName" | ||
domId="myDomId" | ||
maxRows="5" | ||
helperText="Optional helper text" | ||
hideLabel={boolean("hideLabel", false)} | ||
icon={select("icon", iconArray, "placeholder-bold")} | ||
storybookErrorPreview={boolean("error", false)} | ||
required | ||
/> | ||
)); |
30 changes: 30 additions & 0 deletions
30
src/components/FormFields/TextFieldMultiline/TextFieldMultiline.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import React from 'react'; | ||
import { mount } from 'enzyme'; | ||
import toJson from 'enzyme-to-json'; | ||
import { Formik, Form } from 'formik'; | ||
import TextareaAutosize from 'react-textarea-autosize'; | ||
import { TextFieldMultiline } from './'; | ||
import { Label } from '../Label'; | ||
import { HelperText } from '../HelperText'; | ||
|
||
describe('<TextFieldMultiline />', () => { | ||
it('Should render', () => { | ||
const wrapper = mount( | ||
<Formik initialValues={{ textField: '' }}> | ||
<Form> | ||
<TextFieldMultiline | ||
label="label" | ||
name="textField" | ||
domId="textFieldId" | ||
multiline="false" | ||
helperText="Optional helper text" | ||
/> | ||
</Form> | ||
</Formik>, | ||
); | ||
expect(wrapper.find(Label).length).toBe(1); | ||
expect(wrapper.find(HelperText).length).toBe(1); | ||
expect(wrapper.find(TextareaAutosize).length).toBe(1); | ||
expect(toJson(wrapper)).toMatchSnapshot(); | ||
}); | ||
}); |
Oops, something went wrong.