mirror of
https://github.com/oceanprotocol/commons.git
synced 2023-03-15 18:03:00 +01:00
one input component for form elements: input, select, textarea
This commit is contained in:
parent
3fbebcad81
commit
be1faa96de
@ -1,12 +1,12 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import ReactDOM from 'react-dom'
|
import ReactDOM from 'react-dom'
|
||||||
|
|
||||||
import FormHelp from './FormHelp'
|
import Help from './Help'
|
||||||
|
|
||||||
it('FormHelp renders without crashing', () => {
|
it('FormHelp renders without crashing', () => {
|
||||||
const div = document.createElement('div')
|
const div = document.createElement('div')
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<FormHelp>Price of your data set asset in Ocean Tokens.</FormHelp>,
|
<Help>Price of your data set asset in Ocean Tokens.</Help>,
|
||||||
div
|
div
|
||||||
)
|
)
|
||||||
ReactDOM.unmountComponentAtNode(div)
|
ReactDOM.unmountComponentAtNode(div)
|
@ -1,5 +1,5 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import styles from './FormHelp.module.scss'
|
import styles from './Help.module.scss'
|
||||||
|
|
||||||
const FormHelp = ({ children }: { children: string }) => (
|
const FormHelp = ({ children }: { children: string }) => (
|
||||||
<div className={styles.help}>{children}</div>
|
<div className={styles.help}>{children}</div>
|
@ -1,10 +1,10 @@
|
|||||||
@import '../../styles/variables';
|
@import '../../../styles/variables';
|
||||||
|
|
||||||
.formGroup {
|
.formGroup {
|
||||||
margin-bottom: $spacer;
|
margin-bottom: $spacer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-wrap {
|
.inputWrap {
|
||||||
background: $brand-gradient;
|
background: $brand-gradient;
|
||||||
border-radius: $border-radius;
|
border-radius: $border-radius;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -12,10 +12,6 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
&.is-focused {
|
|
||||||
background: $brand-black;
|
|
||||||
}
|
|
||||||
|
|
||||||
.is-dimmed & {
|
.is-dimmed & {
|
||||||
background: $brand-grey-lighter;
|
background: $brand-grey-lighter;
|
||||||
|
|
||||||
@ -25,7 +21,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-wrap-search {
|
.isFocused {
|
||||||
|
composes: inputWrap;
|
||||||
|
background: $brand-black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inputWrapSearch {
|
||||||
|
composes: inputWrap;
|
||||||
|
|
||||||
.input {
|
.input {
|
||||||
padding-left: $spacer * 1.25;
|
padding-left: $spacer * 1.25;
|
||||||
}
|
}
|
||||||
@ -92,8 +95,29 @@
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// stylelint-disable-next-line
|
.label {
|
||||||
select.input {
|
color: $brand-grey;
|
||||||
|
font-size: $font-size-base;
|
||||||
|
font-family: $font-family-title;
|
||||||
|
line-height: 1.2;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: $spacer / 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.required {
|
||||||
|
composes: label;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
content: '*';
|
||||||
|
font-size: $font-size-base;
|
||||||
|
color: $brand-grey-light;
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: .1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.select {
|
||||||
|
composes: input;
|
||||||
height: 43px;
|
height: 43px;
|
||||||
padding-right: 3rem;
|
padding-right: 3rem;
|
||||||
border: 0;
|
border: 0;
|
||||||
@ -118,45 +142,12 @@ select.input {
|
|||||||
outline: 0;
|
outline: 0;
|
||||||
font-family: $font-family-base;
|
font-family: $font-family-base;
|
||||||
}
|
}
|
||||||
// stylelint-disable
|
|
||||||
.is-dimmed & {
|
|
||||||
background-image: linear-gradient(
|
|
||||||
45deg,
|
|
||||||
transparent 50%,
|
|
||||||
$brand-grey-light 50%
|
|
||||||
),
|
|
||||||
linear-gradient(135deg, $brand-grey-light 50%, transparent 50%),
|
|
||||||
linear-gradient(
|
|
||||||
to right,
|
|
||||||
$brand-grey-lighter 1px,
|
|
||||||
lighten($brand-grey-lighter, 5%) 2px,
|
|
||||||
lighten($brand-grey-lighter, 5%)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// stylelint-enable
|
|
||||||
}
|
|
||||||
|
|
||||||
.label {
|
|
||||||
color: $brand-grey;
|
|
||||||
font-size: $font-size-base;
|
|
||||||
font-family: $font-family-title;
|
|
||||||
line-height: 1.2;
|
|
||||||
display: block;
|
|
||||||
margin-bottom: $spacer / 6;
|
|
||||||
|
|
||||||
&.is-required {
|
|
||||||
&:after {
|
|
||||||
content: '*';
|
|
||||||
font-size: $font-size-base;
|
|
||||||
color: $brand-grey-light;
|
|
||||||
display: inline-block;
|
|
||||||
margin-left: .1rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Size modifiers
|
// Size modifiers
|
||||||
.input-sm {
|
|
||||||
|
.inputSmall {
|
||||||
|
composes: input;
|
||||||
font-size: $font-size-small;
|
font-size: $font-size-small;
|
||||||
min-height: 32px;
|
min-height: 32px;
|
||||||
padding: $spacer / 4;
|
padding: $spacer / 4;
|
||||||
@ -166,8 +157,8 @@ select.input {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// stylelint-disable-next-line
|
.selectSmall {
|
||||||
select.input-sm {
|
composes: select;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
padding-right: 2rem;
|
padding-right: 2rem;
|
||||||
|
|
@ -1,48 +1,51 @@
|
|||||||
import React, { PureComponent } from 'react'
|
import React, { PureComponent } from 'react'
|
||||||
import { ReactComponent as SearchIcon } from '../../../svg/search.svg'
|
// import { ReactComponent as SearchIcon } from '../../../svg/search.svg'
|
||||||
import FormHelp from './FormHelp'
|
import Help from './Help'
|
||||||
import styles from './FormInput.module.scss'
|
import styles from './Input.module.scss'
|
||||||
|
|
||||||
interface IFormInputProps {
|
interface IInputProps {
|
||||||
name: string
|
name: string
|
||||||
label: string
|
label: string
|
||||||
placeholder: string
|
placeholder?: string
|
||||||
required?: boolean
|
required?: boolean
|
||||||
help?: string
|
help?: string
|
||||||
tag?: string
|
tag?: string
|
||||||
type: string
|
type?: string
|
||||||
small?: boolean
|
small?: boolean
|
||||||
additionalComponent?: void
|
additionalComponent?: void
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IFormInputState {
|
interface IInputState {
|
||||||
isFocused: boolean
|
isFocused: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class FormInput extends PureComponent<
|
const Tag = ({ ...props }) => {
|
||||||
IFormInputProps,
|
if (props.tag && props.tag === 'select') {
|
||||||
IFormInputState
|
return <select className={styles.select} {...props} />
|
||||||
> {
|
} else if (props.tag && props.tag === 'textarea') {
|
||||||
public state: IFormInputState = { isFocused: false }
|
return <textarea className={styles.input} {...props} />
|
||||||
|
} else {
|
||||||
|
return <input className={styles.input} {...props} />
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class Input extends PureComponent<IInputProps, IInputState> {
|
||||||
|
public state: IInputState = { isFocused: false }
|
||||||
|
|
||||||
public inputWrapClasses() {
|
public inputWrapClasses() {
|
||||||
if (this.props.type === 'search') {
|
if (this.props.type === 'search') {
|
||||||
return 'input-wrap input-wrap-search'
|
return styles.inputWrapSearch
|
||||||
} else if (this.props.type === 'search' && this.state.isFocused) {
|
} else if (this.props.type === 'search' && this.state.isFocused) {
|
||||||
return 'input-wrap input-wrap-search is-focused'
|
return 'input-wrap input-wrap-search is-focused'
|
||||||
} else if (this.state.isFocused && this.props.type !== 'search') {
|
} else if (this.state.isFocused && this.props.type !== 'search') {
|
||||||
return 'input-wrap is-focused'
|
return styles.isFocused
|
||||||
} else {
|
} else {
|
||||||
return 'input-wrap'
|
return styles.inputWrap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public handleBlur() {
|
public toggleFocus = () => {
|
||||||
this.setState({ isFocused: true })
|
this.setState({ isFocused: !this.state.isFocused })
|
||||||
}
|
|
||||||
|
|
||||||
public handleFocus() {
|
|
||||||
this.setState({ isFocused: false })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
@ -53,7 +56,9 @@ export default class FormInput extends PureComponent<
|
|||||||
type,
|
type,
|
||||||
help,
|
help,
|
||||||
small,
|
small,
|
||||||
|
tag,
|
||||||
additionalComponent,
|
additionalComponent,
|
||||||
|
children,
|
||||||
...props
|
...props
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
@ -61,25 +66,27 @@ export default class FormInput extends PureComponent<
|
|||||||
<div className={styles.formGroup}>
|
<div className={styles.formGroup}>
|
||||||
<label
|
<label
|
||||||
htmlFor={name}
|
htmlFor={name}
|
||||||
className={styles.label}
|
className={required ? styles.required : styles.label}
|
||||||
title={required ? 'Required' : ''}
|
title={required ? 'Required' : ''}
|
||||||
>
|
>
|
||||||
{label}
|
{label}
|
||||||
</label>
|
</label>
|
||||||
<div className={this.inputWrapClasses()}>
|
<div className={this.inputWrapClasses()}>
|
||||||
<input
|
<Tag
|
||||||
className={small ? 'input input-sm' : 'input'}
|
|
||||||
id={name}
|
id={name}
|
||||||
name={name}
|
name={name}
|
||||||
required={required}
|
required={required}
|
||||||
type={type}
|
type={type}
|
||||||
|
tag={tag}
|
||||||
{...props}
|
{...props}
|
||||||
onFocus={this.handleFocus}
|
onFocus={this.toggleFocus}
|
||||||
onBlur={this.handleBlur}
|
onBlur={this.toggleFocus}
|
||||||
/>
|
>
|
||||||
{type === 'search' && <SearchIcon />}
|
{children}
|
||||||
|
</Tag>
|
||||||
|
{/* {type === 'search' && <SearchIcon />} */}
|
||||||
</div>
|
</div>
|
||||||
{help && <FormHelp>{help}</FormHelp>}
|
{help && <Help>{help}</Help>}
|
||||||
|
|
||||||
{additionalComponent && additionalComponent}
|
{additionalComponent && additionalComponent}
|
||||||
</div>
|
</div>
|
@ -8,9 +8,25 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
padding-top: 4rem;
|
||||||
|
padding-bottom: 4rem;
|
||||||
|
|
||||||
> div {
|
> div {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.form {
|
||||||
|
width: 100%;
|
||||||
|
background: $brand-grey-lighter;
|
||||||
|
margin: 0 auto;
|
||||||
|
max-width: 40rem;
|
||||||
|
padding: $spacer;
|
||||||
|
margin-top: 4rem;
|
||||||
|
|
||||||
|
fieldset {
|
||||||
|
border: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import Button from '../components/atoms/Button'
|
import Button from '../components/atoms/Button'
|
||||||
|
import Input from '../components/atoms/Form/Input'
|
||||||
import styles from './Home.module.scss'
|
import styles from './Home.module.scss'
|
||||||
|
|
||||||
class Home extends Component {
|
class Home extends Component {
|
||||||
@ -13,6 +14,47 @@ class Home extends Component {
|
|||||||
<Button href="https://hello.com">
|
<Button href="https://hello.com">
|
||||||
I am a link disguised as a button
|
I am a link disguised as a button
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
<form className={styles.form}>
|
||||||
|
<fieldset>
|
||||||
|
<Input
|
||||||
|
name="hellotext"
|
||||||
|
label="Hello Text"
|
||||||
|
placeholder="Hello placeholder"
|
||||||
|
type="text"
|
||||||
|
required={true}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
name="hellotextwithhelp"
|
||||||
|
label="Hello Text with Help"
|
||||||
|
placeholder="Hello placeholder"
|
||||||
|
type="text"
|
||||||
|
required={true}
|
||||||
|
help="Help me Obiwan."
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
name="hellosearch"
|
||||||
|
label="Hello Search"
|
||||||
|
placeholder="Hello placeholder"
|
||||||
|
type="search"
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
name="helloselect"
|
||||||
|
label="Hello Select"
|
||||||
|
tag="select"
|
||||||
|
>
|
||||||
|
<option value="0">---</option>
|
||||||
|
<option value="1">Hello Option</option>
|
||||||
|
<option value="2">Hello Option</option>
|
||||||
|
</Input>
|
||||||
|
<Input
|
||||||
|
name="hellotextarea"
|
||||||
|
label="Hello Textarea"
|
||||||
|
placeholder="Hello placeholder"
|
||||||
|
tag="textarea"
|
||||||
|
/>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user