Skip to content

Commit 235cd8c

Browse files
committed
TagInput component
1 parent 7fad5ab commit 235cd8c

File tree

5 files changed

+155
-13
lines changed

5 files changed

+155
-13
lines changed
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import * as React from 'react'
2+
import { FieldProps } from 'formik'
3+
4+
import { Container, Label, StyledInput, Wrapper, Tag, CloseIcon } from './style'
5+
6+
interface State {
7+
tags: string[]
8+
inputValue: string
9+
}
10+
11+
interface Props {
12+
label?: string
13+
}
14+
15+
export class TagInput extends React.Component<FieldProps & Props, State> {
16+
public readonly state = {
17+
tags: [],
18+
inputValue: ''
19+
}
20+
21+
private handleChange = (e: any) =>
22+
this.setState({ inputValue: e.target.value })
23+
24+
private setField = (value: string[]) => {
25+
const {
26+
form: { setFieldValue }
27+
} = this.props
28+
29+
setFieldValue('amenities', value, false)
30+
}
31+
32+
private onEnterPress = (e: any) => {
33+
if (e.key === 'Enter' && this.state.inputValue) {
34+
this.setState(
35+
({ tags, inputValue }) => ({
36+
tags: [...tags, inputValue],
37+
inputValue: ''
38+
}),
39+
() => this.setField(this.state.tags)
40+
)
41+
}
42+
}
43+
44+
private deleteTag = (i: number) => {
45+
const { tags } = this.state
46+
47+
const newTags = [...tags.slice(0, i), ...tags.slice(i + 1)]
48+
49+
this.setState({ tags: newTags })
50+
51+
this.setField(newTags)
52+
}
53+
54+
public render() {
55+
const { inputValue, tags } = this.state
56+
const {
57+
field: { onChange, value, ...field },
58+
form: {},
59+
label,
60+
...props
61+
} = this.props
62+
63+
return (
64+
<Container>
65+
{label && <Label>{label}</Label>}
66+
67+
<Wrapper>
68+
{tags &&
69+
tags.map((tag, i) => (
70+
<Tag key={i}>
71+
{tag}{' '}
72+
<CloseIcon onClick={() => this.deleteTag(i)} />
73+
</Tag>
74+
))}
75+
<StyledInput
76+
value={inputValue}
77+
onChange={this.handleChange}
78+
onKeyPress={this.onEnterPress}
79+
{...field}
80+
{...props}
81+
/>
82+
</Wrapper>
83+
</Container>
84+
)
85+
}
86+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import styled from 'styled-components'
2+
3+
import { MdClose } from 'react-icons/md'
4+
5+
export const Container = styled.div`
6+
width: 100%;
7+
margin: 0 0 25px 0;
8+
display: flex;
9+
flex-direction: column;
10+
`
11+
export const Label = styled.label`
12+
margin-bottom: 10px;
13+
font-size: 12px;
14+
font-weight: 700;
15+
letter-spacing: 0.5px;
16+
color: #494a4a;
17+
`
18+
export const Wrapper = styled.div`
19+
width: 100%;
20+
display: flex;
21+
flex-wrap: wrap;
22+
min-height: 45px;
23+
border-radius: 4px;
24+
border: 1px solid;
25+
border-color: rgb(235, 235, 235);
26+
`
27+
export const Tag = styled.div`
28+
margin: 8px 0 0 8px;
29+
padding: 8px;
30+
display: flex;
31+
justify-content: space-between;
32+
align-items: center;
33+
border-radius: 3px;
34+
background-color: #ff5a66;
35+
font-size: 14px;
36+
color: white;
37+
box-sizing: border-box;
38+
`
39+
export const CloseIcon = styled(MdClose)`
40+
font-size: 16px;
41+
margin: -1px 0 0 5px;
42+
color: white;
43+
cursor: pointer;
44+
`
45+
export const StyledInput = styled.input`
46+
width: 100%;
47+
margin: 13px 10px 10px 10px;
48+
border: none;
49+
font-size: 14px;
50+
font-weight: 500;
51+
font-family: Montserrat;
52+
box-sizing: border-box;
53+
54+
&:focus {
55+
outline: none;
56+
}
57+
`

client/src/Pages/CreateListing/Components/CreateListingForm/index.tsx

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ interface FieldValues {
1414
price: number
1515
guests: number
1616
beds: number
17-
amenities: string
17+
amenities: string[]
1818
lat: number
1919
lng: number
2020
address: string
@@ -48,7 +48,7 @@ export class C extends React.PureComponent<RouteComponentProps, State> {
4848
price: 0,
4949
guests: 0,
5050
beds: 0,
51-
amenities: '',
51+
amenities: [''],
5252
lat: 0,
5353
lng: 0,
5454
address: '',
@@ -58,17 +58,9 @@ export class C extends React.PureComponent<RouteComponentProps, State> {
5858
onSubmit={async (values: FieldValues) => {
5959
this.setState({ isLoading: true })
6060

61-
console.log({
62-
variables: {
63-
...values,
64-
amenities: [values.amenities]
65-
}
66-
})
67-
6861
const response = await createListing({
6962
variables: {
70-
...values,
71-
amenities: [values.amenities]
63+
...values
7264
}
7365
})
7466

client/src/Pages/CreateListing/Components/RoomInfoForm/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as React from 'react'
22
import { Field } from 'formik'
33

44
import { FormikInput } from 'src/Components/FomikInput'
5+
import { TagInput } from 'src/Components/TagInput'
56
import { Title } from './style'
67

78
export const RoomInfoForm: React.SFC<{}> = () => (
@@ -36,7 +37,7 @@ export const RoomInfoForm: React.SFC<{}> = () => (
3637
name="amenities"
3738
placeholder="Amenities"
3839
label="Amenities"
39-
component={FormikInput}
40+
component={TagInput}
4041
/>
4142
</>
4243
)

client/src/Pages/Listings/Components/Map/index.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,13 @@ import { Postion } from 'src/Containers/Position'
66
export const Map = withGoogleMap(() => (
77
<Subscribe to={[Postion]}>
88
{({ state: { lat, lng } }) => (
9-
<GoogleMap defaultZoom={7} defaultCenter={{ lat, lng }}>
9+
<GoogleMap
10+
defaultZoom={7}
11+
defaultCenter={{
12+
lat: 52.0685,
13+
lng: 19.9475
14+
}}
15+
>
1016
<Marker position={{ lat, lng }} />
1117
</GoogleMap>
1218
)}

0 commit comments

Comments
 (0)