UNPKG

3.7 kBTypeScriptView Raw
1import styled, { css, keyframes } from 'styled-components';
2
3import { Sizes, Colors, TextHelper } from '../index';
4import { IProps } from './Input';
5
6const bounceUp = keyframes`
7 from { transform: scale3d(1, 1, 1); }
8 50% { transform: scale3d(1.1618, 1.1618, 1.1618); }
9 to { transform: scale3d(1, 1, 1); }
10`;
11
12const shake = keyframes`
13 from, to { transform: translate3d(0, 0, 0); }
14 10%, 30%, 50%, 70%, 90% { transform: translate3d(-3px, 0, 0); }
15 20%, 40%, 60%, 80% { transform: translate3d(3px, 0, 0); }
16`;
17
18const bounceUpRule = css`${bounceUp} .4s forwards;`;
19
20const shakeRule = (props: any) => css`${props.isInvalid && shake} 1s forwards;`;
21
22const GroupInput = styled.div`
23 position: relative;
24 height: 75px;
25 @media screen and (max-width: 600px) {
26 width: 100%;
27 }
28
29`;
30
31const opacityAndTransition = (opacity: number, transition: string) => `
32 opacity: ${opacity};
33 transition: ${transition};
34`;
35
36const Input = styled.input<IProps>`
37 position: relative;
38 font-weight: 500;
39 color: ${Colors.codGray};
40 width: 100%;
41 box-sizing: border-box;
42 letter-spacing: 1px;
43 border: 0;
44 padding: 4px 0;
45 border-bottom: 1px solid currentColor;
46 background-color: transparent;
47 font-family: ${TextHelper.fontVariant('medium')};
48
49 &:disabled {
50 opacity: 0.5;
51 border-bottom-color: ${Colors.line};
52 }
53
54 &:not(:placeholder-shown) ~ label {
55 top: -16px;
56 color: ${Colors.support};
57 z-index: 1;
58 ${opacityAndTransition(1, '0.3s')};
59 }
60
61 ::placeholder {
62 color: ${Colors.support};
63 ${opacityAndTransition(1, '0.2s')};
64 font-family: ${TextHelper.fontVariant('medium')};
65 }
66
67 &:focus::placeholder {
68 ${opacityAndTransition(0, '0.2s')};
69 }
70
71 &:focus {
72 outline: none;
73
74 & ~ .bar {
75 width: 100%;
76 transition: 0.4s;
77 }
78
79 & ~ label {
80 top: -16px;
81 color: ${Colors.mongeral};
82 opacity: 1;
83 z-index: 1;
84 animation: ${bounceUpRule};
85 }
86 }
87
88 & ~ .bar {
89 position: relative;
90 display: inherit;
91 top: -2px;
92 width: 0;
93 height: 2px;
94 background-color: ${Colors.mongeral};
95 transition: 0.4s;
96 }
97
98 ~ label {
99 position: absolute;
100 font-size: ${TextHelper.pxToEm(Sizes.s2)}em;
101 font-family: ${TextHelper.fontVariant('medium')};
102 font-weight: 500;
103 left: 0;
104 top: -16px;
105 z-index: -1;
106 letter-spacing: 0.5px;
107 ${opacityAndTransition(0, 'all .2s ease')};
108 animation: ${shakeRule};
109 text-transform: uppercase;
110 }
111
112 ~ .feedback {
113 position: absolute;
114 font-size: ${TextHelper.pxToEm(Sizes.s2)}em;
115 font-family: ${TextHelper.fontVariant('medium')};
116 overflow: hidden;
117 font-style: italic;
118
119 ${({comment}) => comment && `
120 font-style: italic;
121 `}
122 }
123
124 ${({ isInvalid, isWarning }) => (isInvalid || isWarning) && `
125 border-color: ${isInvalid ? Colors.chestnut : Colors.goldDrop};
126 ~ .feedback,
127 ~ label,
128 &:focus ~ label, &:not(:placeholder-shown) ~ label {
129 color: ${isInvalid ? Colors.chestnut : Colors.goldDrop}
130 }
131
132 ~ label { opacity: 1; }
133 `}
134
135 ${({ type }) => type === 'search' && `
136 &::-webkit-search-decoration,
137 &::-webkit-search-cancel-button,
138 &::-webkit-search-results-button,
139 &::-webkit-search-results-decoration {
140 display: none;
141 }
142 ~ .search-icon {
143 position: absolute;
144 height: 25px;
145 fill:none;
146 stroke: ${Colors.regalBlue};
147 stroke-width: 2px;
148 top: 0;
149 right: 0;
150 padding: 2px;
151 z-index: 2;
152 }
153 `}
154
155 ${({ type }) => type === 'number' && `
156 &::-webkit-inner-spin-button,
157 &::-webkit-outer-spin-button {
158 -webkit-appearance: none;
159 margin: 0;
160 }
161 `}
162`;
163
164export default {
165 Input,
166 GroupInput,
167};