@sellout/ui 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.storybook/main.js +8 -0
- package/.storybook/preview-head.html +21 -0
- package/README.md +44 -0
- package/package.json +62 -0
- package/public/favicon.ico +0 -0
- package/public/index.html +43 -0
- package/public/logo192.png +0 -0
- package/public/logo512.png +0 -0
- package/public/manifest.json +25 -0
- package/public/robots.txt +3 -0
- package/src/Colors.ts +12 -0
- package/src/components/Button.tsx +134 -0
- package/src/components/Counter.tsx +92 -0
- package/src/components/Icon.tsx +48 -0
- package/src/components/Icons.ts +189 -0
- package/src/components/Input.tsx +250 -0
- package/src/components/Loader.tsx +84 -0
- package/src/components/Product.tsx +157 -0
- package/src/index.tsx +8 -0
- package/src/react-app-env.d.ts +1 -0
- package/src/setupTests.ts +5 -0
- package/src/stories/Button.stories.js +30 -0
- package/src/stories/Counter.stories.js +30 -0
- package/src/stories/Icon.stories.js +25 -0
- package/src/stories/Input.stories.js +79 -0
- package/src/stories/Loader.stories.js +51 -0
- package/src/stories/Product.stories.js +69 -0
- package/tsconfig.json +25 -0
- package/utils/generateIconLibrary.js +37 -0
- package/utils/icon-library.csv +98 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { faUserFriends as AudienceRegular } from "@fortawesome/pro-regular-svg-icons";
|
|
2
|
+
import { faCashRegister as BoxOfficeRegular } from "@fortawesome/pro-regular-svg-icons";
|
|
3
|
+
import { faCalculator as CalculatorRegular } from "@fortawesome/pro-regular-svg-icons";
|
|
4
|
+
import { faCalendarStar as CalendarStarRegular } from "@fortawesome/pro-regular-svg-icons";
|
|
5
|
+
import { faCheck as Check } from "@fortawesome/pro-regular-svg-icons";
|
|
6
|
+
import { faGlassCheers as Cheers } from "@fortawesome/pro-regular-svg-icons";
|
|
7
|
+
import { faClipboardList as Clipboard } from "@fortawesome/pro-regular-svg-icons";
|
|
8
|
+
import { faCrown as CrownRegular } from "@fortawesome/pro-regular-svg-icons";
|
|
9
|
+
import { faTachometer as DashboardRegular } from "@fortawesome/pro-regular-svg-icons";
|
|
10
|
+
import { faTrash as DeleteRegular } from "@fortawesome/pro-regular-svg-icons";
|
|
11
|
+
import { faDollarSign as Dollar } from "@fortawesome/pro-regular-svg-icons";
|
|
12
|
+
import { faArrowAltDown as DownArrow } from "@fortawesome/pro-regular-svg-icons";
|
|
13
|
+
import { faFileDownload as DownloadReport } from "@fortawesome/pro-regular-svg-icons";
|
|
14
|
+
import { faCode as Embed } from "@fortawesome/pro-regular-svg-icons";
|
|
15
|
+
import { faFileExport as Export } from "@fortawesome/pro-regular-svg-icons";
|
|
16
|
+
import { faUsdSquare as FeeRegular } from "@fortawesome/pro-regular-svg-icons";
|
|
17
|
+
import { faFilter as FilterRegular } from "@fortawesome/pro-regular-svg-icons";
|
|
18
|
+
import { faGlobeAmericas as GlobeRegular } from "@fortawesome/pro-regular-svg-icons";
|
|
19
|
+
import { faChartLine as GraphGrowth } from "@fortawesome/pro-regular-svg-icons";
|
|
20
|
+
import { faKeySkeleton as KeyRegular } from "@fortawesome/pro-regular-svg-icons";
|
|
21
|
+
import { faChevronLeft as LeftChevron } from "@fortawesome/pro-regular-svg-icons";
|
|
22
|
+
import { faLink as Link } from "@fortawesome/pro-regular-svg-icons";
|
|
23
|
+
import { faMicrophoneAlt as MicrophoneRegular } from "@fortawesome/pro-regular-svg-icons";
|
|
24
|
+
import { faPrint as PrintRegular } from "@fortawesome/pro-regular-svg-icons";
|
|
25
|
+
import { faReceipt as ReceiptRegular } from "@fortawesome/pro-regular-svg-icons";
|
|
26
|
+
import { faFileChartLine as ReportRegular } from "@fortawesome/pro-regular-svg-icons";
|
|
27
|
+
import { faSearch as SearchRegular } from "@fortawesome/pro-regular-svg-icons";
|
|
28
|
+
import { faTicketAlt as TicketRegular } from "@fortawesome/pro-regular-svg-icons";
|
|
29
|
+
import { faUnlock as Unlock } from "@fortawesome/pro-regular-svg-icons";
|
|
30
|
+
import { faArrowAltUp as UpArrow } from "@fortawesome/pro-regular-svg-icons";
|
|
31
|
+
import { faArrowAltSquareUp as UpgradeRegular } from "@fortawesome/pro-regular-svg-icons";
|
|
32
|
+
import { faUpload as Upload } from "@fortawesome/pro-regular-svg-icons";
|
|
33
|
+
import { faUsers as UsersRegular } from "@fortawesome/pro-regular-svg-icons";
|
|
34
|
+
import { faLandmark as VenueRegular } from "@fortawesome/pro-regular-svg-icons";
|
|
35
|
+
import { faUserFriends as AudienceSolid } from "@fortawesome/free-solid-svg-icons";
|
|
36
|
+
import { faArrowLeft as BackArrow } from "@fortawesome/free-solid-svg-icons";
|
|
37
|
+
import { faBold as Bold } from "@fortawesome/free-solid-svg-icons";
|
|
38
|
+
import { faCashRegister as BoxOfficeSolid } from "@fortawesome/free-solid-svg-icons";
|
|
39
|
+
import { faBullhorn as Bullhorn } from "@fortawesome/free-solid-svg-icons";
|
|
40
|
+
import { faCalculator as CalculatorSolid } from "@fortawesome/free-solid-svg-icons";
|
|
41
|
+
import { faCalendarDay as CalendarDaySolid } from "@fortawesome/free-solid-svg-icons";
|
|
42
|
+
import { faTimes as Cancel } from "@fortawesome/free-solid-svg-icons";
|
|
43
|
+
import { faTimesCircle as CancelCircle } from "@fortawesome/free-solid-svg-icons";
|
|
44
|
+
import { faCaretDown as CaretDown } from "@fortawesome/free-solid-svg-icons";
|
|
45
|
+
import { faMoneyBill as Cash } from "@fortawesome/free-solid-svg-icons";
|
|
46
|
+
import { faCheckCircle as CheckCircle } from "@fortawesome/free-solid-svg-icons";
|
|
47
|
+
import { faCopy as CopySolid } from "@fortawesome/free-solid-svg-icons";
|
|
48
|
+
import { faCreditCard as CreditCardBack } from "@fortawesome/free-solid-svg-icons";
|
|
49
|
+
import { faCrown as CrownSolid } from "@fortawesome/free-solid-svg-icons";
|
|
50
|
+
import { faICursor as Cursor } from "@fortawesome/free-solid-svg-icons";
|
|
51
|
+
import { faTrash as DeleteSolid } from "@fortawesome/free-solid-svg-icons";
|
|
52
|
+
import { faEnvelope as EnvelopeSolid } from "@fortawesome/free-solid-svg-icons";
|
|
53
|
+
import { faEye as EyeSolid } from "@fortawesome/free-solid-svg-icons";
|
|
54
|
+
import { faQuestionCircle as HelpSolid } from "@fortawesome/free-solid-svg-icons";
|
|
55
|
+
import { faItalic as Italic } from "@fortawesome/free-solid-svg-icons";
|
|
56
|
+
import { faMicrophoneAlt as MicrophoneSolid } from "@fortawesome/free-solid-svg-icons";
|
|
57
|
+
import { faMobileAlt as Mobile } from "@fortawesome/free-solid-svg-icons";
|
|
58
|
+
import { faPlusCircle as PlusCircle } from "@fortawesome/free-solid-svg-icons";
|
|
59
|
+
import { faPrint as PrintSolid } from "@fortawesome/free-solid-svg-icons";
|
|
60
|
+
import { faReceipt as ReceiptSolid } from "@fortawesome/free-solid-svg-icons";
|
|
61
|
+
import { faChevronCircleRight as RightChevronCircle } from "@fortawesome/free-solid-svg-icons";
|
|
62
|
+
import { faSearch as SearchSolid } from "@fortawesome/free-solid-svg-icons";
|
|
63
|
+
import { faSort as Sort } from "@fortawesome/free-solid-svg-icons";
|
|
64
|
+
import { faTicketAlt as TicketSolid } from "@fortawesome/free-solid-svg-icons";
|
|
65
|
+
import { faUnderline as Underline } from "@fortawesome/free-solid-svg-icons";
|
|
66
|
+
import { faUserCircle as UserCircle } from "@fortawesome/free-solid-svg-icons";
|
|
67
|
+
import { faUser as UserSolid } from "@fortawesome/free-solid-svg-icons";
|
|
68
|
+
import { faUsers as UsersSolid } from "@fortawesome/free-solid-svg-icons";
|
|
69
|
+
import { faLandmark as VenueSolid } from "@fortawesome/free-solid-svg-icons";
|
|
70
|
+
import { faExclamationTriangle as Warning } from "@fortawesome/free-solid-svg-icons";
|
|
71
|
+
import { faCalendarAlt as Calendar } from "@fortawesome/free-regular-svg-icons";
|
|
72
|
+
import { faClock as Clock } from "@fortawesome/free-regular-svg-icons";
|
|
73
|
+
import { faCopy as CopyRegular } from "@fortawesome/free-regular-svg-icons";
|
|
74
|
+
import { faEdit as Edit } from "@fortawesome/free-regular-svg-icons";
|
|
75
|
+
import { faEye as EyeRegular } from "@fortawesome/free-regular-svg-icons";
|
|
76
|
+
import { faEyeSlash as EyeSlashRegular } from "@fortawesome/free-regular-svg-icons";
|
|
77
|
+
import { faQuestionCircle as HelpRegular } from "@fortawesome/free-regular-svg-icons";
|
|
78
|
+
import { faSadTear as SadTear } from "@fortawesome/free-regular-svg-icons";
|
|
79
|
+
import { faUser as UserRegular } from "@fortawesome/free-regular-svg-icons";
|
|
80
|
+
import { faCalendarDay as CalendarDayLight } from "@fortawesome/pro-light-svg-icons";
|
|
81
|
+
import { faMapMarkerAlt as mapPinLight } from "@fortawesome/pro-light-svg-icons";
|
|
82
|
+
import { faMinusCircle as MinusCircleLight } from "@fortawesome/pro-light-svg-icons";
|
|
83
|
+
import { faPlusCircle as PlusCircleLight } from "@fortawesome/pro-light-svg-icons";
|
|
84
|
+
import { faCalendarStar as CalendarStarSolid } from "@fortawesome/pro-solid-svg-icons";
|
|
85
|
+
import { faCreditCardFront as CreditCardFront } from "@fortawesome/pro-solid-svg-icons";
|
|
86
|
+
import { faTachometer as DashboardSolid } from "@fortawesome/pro-solid-svg-icons";
|
|
87
|
+
import { faUsdSquare as FeeSolid } from "@fortawesome/pro-solid-svg-icons";
|
|
88
|
+
import { faKeySkeleton as KeySolid } from "@fortawesome/pro-solid-svg-icons";
|
|
89
|
+
import { faLongArrowRight as LongRightArrow } from "@fortawesome/pro-solid-svg-icons";
|
|
90
|
+
import { faFileChartLine as ReportSolid } from "@fortawesome/pro-solid-svg-icons";
|
|
91
|
+
import { faSortAlt as SortBy } from "@fortawesome/pro-solid-svg-icons";
|
|
92
|
+
import { faArrowAltSquareUp as UpgradeSolid } from "@fortawesome/pro-solid-svg-icons";
|
|
93
|
+
|
|
94
|
+
// import { library } from "@fortawesome/fontawesome-svg-core";
|
|
95
|
+
|
|
96
|
+
export const IconEnum = {
|
|
97
|
+
AudienceRegular,
|
|
98
|
+
BoxOfficeRegular,
|
|
99
|
+
CalculatorRegular,
|
|
100
|
+
CalendarStarRegular,
|
|
101
|
+
Check,
|
|
102
|
+
Cheers,
|
|
103
|
+
Clipboard,
|
|
104
|
+
CrownRegular,
|
|
105
|
+
DashboardRegular,
|
|
106
|
+
DeleteRegular,
|
|
107
|
+
Dollar,
|
|
108
|
+
DownArrow,
|
|
109
|
+
DownloadReport,
|
|
110
|
+
Embed,
|
|
111
|
+
Export,
|
|
112
|
+
FeeRegular,
|
|
113
|
+
FilterRegular,
|
|
114
|
+
GlobeRegular,
|
|
115
|
+
GraphGrowth,
|
|
116
|
+
KeyRegular,
|
|
117
|
+
LeftChevron,
|
|
118
|
+
Link,
|
|
119
|
+
MicrophoneRegular,
|
|
120
|
+
PrintRegular,
|
|
121
|
+
ReceiptRegular,
|
|
122
|
+
ReportRegular,
|
|
123
|
+
SearchRegular,
|
|
124
|
+
TicketRegular,
|
|
125
|
+
Unlock,
|
|
126
|
+
UpArrow,
|
|
127
|
+
UpgradeRegular,
|
|
128
|
+
Upload,
|
|
129
|
+
UsersRegular,
|
|
130
|
+
VenueRegular,
|
|
131
|
+
AudienceSolid,
|
|
132
|
+
BackArrow,
|
|
133
|
+
Bold,
|
|
134
|
+
BoxOfficeSolid,
|
|
135
|
+
Bullhorn,
|
|
136
|
+
CalculatorSolid,
|
|
137
|
+
CalendarDaySolid,
|
|
138
|
+
Cancel,
|
|
139
|
+
CancelCircle,
|
|
140
|
+
CaretDown,
|
|
141
|
+
Cash,
|
|
142
|
+
CheckCircle,
|
|
143
|
+
CopySolid,
|
|
144
|
+
CreditCardBack,
|
|
145
|
+
CrownSolid,
|
|
146
|
+
Cursor,
|
|
147
|
+
DeleteSolid,
|
|
148
|
+
EnvelopeSolid,
|
|
149
|
+
EyeSolid,
|
|
150
|
+
HelpSolid,
|
|
151
|
+
Italic,
|
|
152
|
+
MicrophoneSolid,
|
|
153
|
+
Mobile,
|
|
154
|
+
PlusCircle,
|
|
155
|
+
PrintSolid,
|
|
156
|
+
ReceiptSolid,
|
|
157
|
+
RightChevronCircle,
|
|
158
|
+
SearchSolid,
|
|
159
|
+
Sort,
|
|
160
|
+
TicketSolid,
|
|
161
|
+
Underline,
|
|
162
|
+
UserCircle,
|
|
163
|
+
UserSolid,
|
|
164
|
+
UsersSolid,
|
|
165
|
+
VenueSolid,
|
|
166
|
+
Warning,
|
|
167
|
+
Calendar,
|
|
168
|
+
Clock,
|
|
169
|
+
CopyRegular,
|
|
170
|
+
Edit,
|
|
171
|
+
EyeRegular,
|
|
172
|
+
EyeSlashRegular,
|
|
173
|
+
HelpRegular,
|
|
174
|
+
SadTear,
|
|
175
|
+
UserRegular,
|
|
176
|
+
CalendarDayLight,
|
|
177
|
+
mapPinLight,
|
|
178
|
+
MinusCircleLight,
|
|
179
|
+
PlusCircleLight,
|
|
180
|
+
CalendarStarSolid,
|
|
181
|
+
CreditCardFront,
|
|
182
|
+
DashboardSolid,
|
|
183
|
+
FeeSolid,
|
|
184
|
+
KeySolid,
|
|
185
|
+
LongRightArrow,
|
|
186
|
+
ReportSolid,
|
|
187
|
+
SortBy,
|
|
188
|
+
UpgradeSolid,
|
|
189
|
+
};
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import React, { Fragment, useState } from "react";
|
|
2
|
+
import styled from 'styled-components';
|
|
3
|
+
import * as Polished from 'polished';
|
|
4
|
+
import { Colors } from "../Colors";
|
|
5
|
+
import Icon, { Icons } from './Icon'
|
|
6
|
+
import Loader, { LoaderSizes } from "./Loader";
|
|
7
|
+
|
|
8
|
+
type FormProps = {
|
|
9
|
+
hovered: boolean;
|
|
10
|
+
focused: boolean;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const Form = styled.form<FormProps>`
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-direction: row;
|
|
16
|
+
position: relative;
|
|
17
|
+
border-radius: 10px;
|
|
18
|
+
transition: all 0.2s;
|
|
19
|
+
border: 1px solid
|
|
20
|
+
${props => {
|
|
21
|
+
if (props.focused) return Colors.Grey3;
|
|
22
|
+
if (props.hovered) return Colors.Grey4;
|
|
23
|
+
return Colors.Grey5;
|
|
24
|
+
}};
|
|
25
|
+
`;
|
|
26
|
+
|
|
27
|
+
type ButtonProps = {
|
|
28
|
+
canSubmit: boolean;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const Button = styled.div<ButtonProps>`
|
|
32
|
+
position: absolute;
|
|
33
|
+
display: flex;
|
|
34
|
+
align-items: center;
|
|
35
|
+
justify-content: center;
|
|
36
|
+
color: ${Colors.White};
|
|
37
|
+
height: 50px;
|
|
38
|
+
width: 50px;
|
|
39
|
+
border-radius: 0 10px 10px 0;
|
|
40
|
+
top: -1px;
|
|
41
|
+
right: -1px;
|
|
42
|
+
transition: all 0.2s;
|
|
43
|
+
background-color: ${props =>
|
|
44
|
+
props.canSubmit ? Colors.Orange : Colors.Grey6};
|
|
45
|
+
|
|
46
|
+
&:hover {
|
|
47
|
+
cursor: ${props => (props.onClick ? "pointer" : null)};
|
|
48
|
+
background-color: ${props =>
|
|
49
|
+
props.canSubmit ? Polished.lighten(0.025, Colors.Orange) : null};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
&:active {
|
|
53
|
+
cursor: ${props => (props.onClick ? "pointer" : null)};
|
|
54
|
+
background-color: ${props =>
|
|
55
|
+
props.canSubmit ? Polished.darken(0.025, Colors.Orange) : null};
|
|
56
|
+
}
|
|
57
|
+
`;
|
|
58
|
+
|
|
59
|
+
const LeftContainer = styled.div`
|
|
60
|
+
position: relative;
|
|
61
|
+
display: flex;
|
|
62
|
+
align-items: center;
|
|
63
|
+
justify-content: center;
|
|
64
|
+
margin-left: 15px;
|
|
65
|
+
top: 0px;
|
|
66
|
+
left: 0px;
|
|
67
|
+
`;
|
|
68
|
+
|
|
69
|
+
const RightContainer = styled.div`
|
|
70
|
+
position: absolute;
|
|
71
|
+
display: flex;
|
|
72
|
+
align-items: center;
|
|
73
|
+
justify-content: center;
|
|
74
|
+
height: 50px;
|
|
75
|
+
width: 50px;
|
|
76
|
+
top: -1px;
|
|
77
|
+
right: -1px;
|
|
78
|
+
|
|
79
|
+
&:hover {
|
|
80
|
+
cursor: ${props => (props.onClick ? "pointer" : null)};
|
|
81
|
+
}
|
|
82
|
+
`;
|
|
83
|
+
|
|
84
|
+
const Spacer = styled.div`
|
|
85
|
+
width: 50px;
|
|
86
|
+
`;
|
|
87
|
+
|
|
88
|
+
type StyledInputProps = {
|
|
89
|
+
margin?: string;
|
|
90
|
+
padding?: string;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const InputStyled = styled.input<StyledInputProps>`
|
|
94
|
+
background-color: ${Colors.White};
|
|
95
|
+
color: ${Colors.Grey1};
|
|
96
|
+
outline: none;
|
|
97
|
+
border: 0px;
|
|
98
|
+
border-radius: 10px;
|
|
99
|
+
height: 48px;
|
|
100
|
+
width: fill-available;
|
|
101
|
+
font-size: 1.4rem;
|
|
102
|
+
font-weight: 500;
|
|
103
|
+
padding: 0 0 0 10px;
|
|
104
|
+
transition: all 0.2s;
|
|
105
|
+
margin: ${props => props.margin};
|
|
106
|
+
padding: ${props => props.padding};
|
|
107
|
+
|
|
108
|
+
::placeholder {
|
|
109
|
+
color: ${Colors.Grey4};
|
|
110
|
+
}
|
|
111
|
+
`;
|
|
112
|
+
|
|
113
|
+
export type InputProps = {
|
|
114
|
+
autoFocus?: boolean | undefined;
|
|
115
|
+
placeholder?: string;
|
|
116
|
+
value: string;
|
|
117
|
+
defaultValue?: string;
|
|
118
|
+
icon?: string;
|
|
119
|
+
type?: string;
|
|
120
|
+
onMouseEnter?: any;
|
|
121
|
+
onMouseLeave?: any;
|
|
122
|
+
onChange?: any;
|
|
123
|
+
onFocus?: any;
|
|
124
|
+
onBlur?: any;
|
|
125
|
+
onSubmit?: Function;
|
|
126
|
+
onClear?: Function;
|
|
127
|
+
canSubmit?: boolean,
|
|
128
|
+
loading?: boolean;
|
|
129
|
+
margin?: string;
|
|
130
|
+
padding?: string;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
export default function Input({
|
|
134
|
+
autoFocus,
|
|
135
|
+
placeholder,
|
|
136
|
+
value,
|
|
137
|
+
defaultValue,
|
|
138
|
+
icon,
|
|
139
|
+
type = 'text',
|
|
140
|
+
onMouseEnter,
|
|
141
|
+
onMouseLeave,
|
|
142
|
+
onChange,
|
|
143
|
+
onFocus,
|
|
144
|
+
onBlur,
|
|
145
|
+
onSubmit,
|
|
146
|
+
onClear,
|
|
147
|
+
canSubmit = true,
|
|
148
|
+
loading,
|
|
149
|
+
margin,
|
|
150
|
+
padding,
|
|
151
|
+
}: InputProps) {
|
|
152
|
+
const [hovered, setHovered] = useState(false);
|
|
153
|
+
const [focused, setFocused] = useState(false);
|
|
154
|
+
|
|
155
|
+
const submit = (event: any) => {
|
|
156
|
+
event.preventDefault();
|
|
157
|
+
if(onSubmit && canSubmit && !loading) {
|
|
158
|
+
onSubmit();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return (
|
|
163
|
+
<Form
|
|
164
|
+
hovered={hovered}
|
|
165
|
+
focused={focused}
|
|
166
|
+
onSubmit={event => submit(event)}
|
|
167
|
+
>
|
|
168
|
+
{icon && (
|
|
169
|
+
<LeftContainer>
|
|
170
|
+
<Icon
|
|
171
|
+
icon={icon}
|
|
172
|
+
size={16}
|
|
173
|
+
color={focused ? Colors.Grey1 : Colors.Grey4}
|
|
174
|
+
/>
|
|
175
|
+
</LeftContainer>
|
|
176
|
+
)}
|
|
177
|
+
<InputStyled
|
|
178
|
+
autoFocus={autoFocus}
|
|
179
|
+
placeholder={placeholder}
|
|
180
|
+
value={value}
|
|
181
|
+
defaultValue={defaultValue}
|
|
182
|
+
type={type}
|
|
183
|
+
onChange={onChange}
|
|
184
|
+
onFocus={event => {
|
|
185
|
+
setFocused(true);
|
|
186
|
+
if (onFocus) onFocus(event);
|
|
187
|
+
}}
|
|
188
|
+
onBlur={event => {
|
|
189
|
+
setFocused(false);
|
|
190
|
+
if (onFocus) onBlur(event);
|
|
191
|
+
}}
|
|
192
|
+
onMouseEnter={(event: any) => {
|
|
193
|
+
setHovered(true);
|
|
194
|
+
if (onMouseEnter) onMouseEnter(event);
|
|
195
|
+
}}
|
|
196
|
+
onMouseLeave={(event: any) => {
|
|
197
|
+
setHovered(false);
|
|
198
|
+
if (onMouseLeave) onMouseLeave(event);
|
|
199
|
+
}}
|
|
200
|
+
margin={margin}
|
|
201
|
+
padding={padding}
|
|
202
|
+
/>
|
|
203
|
+
|
|
204
|
+
{(() => {
|
|
205
|
+
if (onSubmit) {
|
|
206
|
+
return (
|
|
207
|
+
<Fragment>
|
|
208
|
+
<Spacer />
|
|
209
|
+
<Button
|
|
210
|
+
canSubmit={canSubmit}
|
|
211
|
+
onClick={event => submit(event)}
|
|
212
|
+
>
|
|
213
|
+
{(() => {
|
|
214
|
+
if (loading) {
|
|
215
|
+
return <Loader size={LoaderSizes.VerySmall} />;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
return (
|
|
219
|
+
<Icon
|
|
220
|
+
icon={Icons.RightChevronCircle}
|
|
221
|
+
color={canSubmit ? Colors.White : Colors.Grey4}
|
|
222
|
+
size={16}
|
|
223
|
+
/>
|
|
224
|
+
);
|
|
225
|
+
})()}
|
|
226
|
+
</Button>
|
|
227
|
+
</Fragment>
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (Boolean(value) && onClear) {
|
|
232
|
+
return (
|
|
233
|
+
<Fragment>
|
|
234
|
+
<Spacer />
|
|
235
|
+
<RightContainer onClick={() => onClear()}>
|
|
236
|
+
<Icon
|
|
237
|
+
icon={Icons.CancelCircle}
|
|
238
|
+
color={Colors.Grey3}
|
|
239
|
+
size={16}
|
|
240
|
+
/>
|
|
241
|
+
</RightContainer>
|
|
242
|
+
</Fragment>
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
return <Spacer />;
|
|
247
|
+
})()}
|
|
248
|
+
</Form>
|
|
249
|
+
);
|
|
250
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import styled from "styled-components";
|
|
3
|
+
import { Colors } from "./../Colors";
|
|
4
|
+
|
|
5
|
+
export enum LoaderSizes {
|
|
6
|
+
VerySmall = "VerySmall",
|
|
7
|
+
Small = "Small",
|
|
8
|
+
Medium = "Medium",
|
|
9
|
+
Large = "Large"
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const LoaderSizesMap = {
|
|
13
|
+
[LoaderSizes.VerySmall]: 24,
|
|
14
|
+
[LoaderSizes.Small]: 30,
|
|
15
|
+
[LoaderSizes.Medium]: 40,
|
|
16
|
+
[LoaderSizes.Large]: 60
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
type StyledLoaderProps = {
|
|
20
|
+
size: number;
|
|
21
|
+
color: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const scale = (size: number, scale: number) => `${size * scale}px`;
|
|
25
|
+
|
|
26
|
+
const StyledLoader = styled.div<StyledLoaderProps>`
|
|
27
|
+
position: relative;
|
|
28
|
+
top: 1.5px;
|
|
29
|
+
|
|
30
|
+
.lds-ring {
|
|
31
|
+
display: inline-block;
|
|
32
|
+
position: relative;
|
|
33
|
+
width: ${props => scale(props.size, 1)};
|
|
34
|
+
height: ${props => scale(props.size, 1)};
|
|
35
|
+
}
|
|
36
|
+
.lds-ring div {
|
|
37
|
+
box-sizing: border-box;
|
|
38
|
+
display: block;
|
|
39
|
+
position: absolute;
|
|
40
|
+
width: ${props => scale(props.size, .8)};
|
|
41
|
+
height: ${props => scale(props.size, .8)};
|
|
42
|
+
margin: ${props => scale(props.size, .1)};
|
|
43
|
+
border: ${props => scale(props.size, 0.066)} solid ${props => props.color};
|
|
44
|
+
border-radius: 50%;
|
|
45
|
+
animation: lds-ring 0.8s cubic-bezier(0.5, 0, 0.5, 1) infinite;
|
|
46
|
+
border-color: ${props => props.color} transparent transparent transparent;
|
|
47
|
+
}
|
|
48
|
+
.lds-ring div:nth-child(1) {
|
|
49
|
+
animation-delay: -0.3s;
|
|
50
|
+
}
|
|
51
|
+
.lds-ring div:nth-child(2) {
|
|
52
|
+
animation-delay: -0.2s;
|
|
53
|
+
}
|
|
54
|
+
.lds-ring div:nth-child(3) {
|
|
55
|
+
animation-delay: -0.1s;
|
|
56
|
+
}
|
|
57
|
+
@keyframes lds-ring {
|
|
58
|
+
0% {
|
|
59
|
+
transform: rotate(0deg);
|
|
60
|
+
}
|
|
61
|
+
100% {
|
|
62
|
+
transform: rotate(360deg);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
`;
|
|
66
|
+
|
|
67
|
+
export default function Loader({
|
|
68
|
+
size = LoaderSizes.Medium,
|
|
69
|
+
color = Colors.White,
|
|
70
|
+
}) {
|
|
71
|
+
return (
|
|
72
|
+
<StyledLoader
|
|
73
|
+
size={LoaderSizesMap[size]}
|
|
74
|
+
color={color}
|
|
75
|
+
>
|
|
76
|
+
<div className="lds-ring">
|
|
77
|
+
<div></div>
|
|
78
|
+
<div></div>
|
|
79
|
+
{/* <div></div> */}
|
|
80
|
+
<div></div>
|
|
81
|
+
</div>
|
|
82
|
+
</StyledLoader>
|
|
83
|
+
);
|
|
84
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import React, { Fragment, useState } from "react";
|
|
2
|
+
import styled from "styled-components";
|
|
3
|
+
import * as Polished from "polished";
|
|
4
|
+
import AnimateHeight from "react-animate-height";
|
|
5
|
+
import { Colors } from "../Colors";
|
|
6
|
+
import Counter, { CounterProps } from './Counter';
|
|
7
|
+
// import Icon from "./Icon";
|
|
8
|
+
|
|
9
|
+
type RowProps = {
|
|
10
|
+
justify?: string;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const Row = styled.div<RowProps>`
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-direction: row;
|
|
16
|
+
justify-content: ${props => props.justify};
|
|
17
|
+
`;
|
|
18
|
+
|
|
19
|
+
const Column = styled.div`
|
|
20
|
+
display: flex;
|
|
21
|
+
flex-direction: column;
|
|
22
|
+
`;
|
|
23
|
+
|
|
24
|
+
const Container = styled.div`
|
|
25
|
+
background-color: ${Colors.White};
|
|
26
|
+
padding: 15px;
|
|
27
|
+
`;
|
|
28
|
+
|
|
29
|
+
const Title = styled.div`
|
|
30
|
+
font-size: 1.8rem;
|
|
31
|
+
color: ${Colors.Grey1};
|
|
32
|
+
font-weight: 600;
|
|
33
|
+
margin-bottom: 5px;
|
|
34
|
+
`;
|
|
35
|
+
|
|
36
|
+
const Price = styled.div`
|
|
37
|
+
font-size: 1.4rem;
|
|
38
|
+
font-weight: 500;
|
|
39
|
+
color: ${Colors.Grey2};
|
|
40
|
+
margin-bottom: 5px;
|
|
41
|
+
`;
|
|
42
|
+
|
|
43
|
+
const Subtitle = styled.div`
|
|
44
|
+
font-size: 1.2rem;
|
|
45
|
+
font-weight: 500;
|
|
46
|
+
line-height: 160%;
|
|
47
|
+
color: ${Colors.Grey3};
|
|
48
|
+
`;
|
|
49
|
+
|
|
50
|
+
const Description = styled.div`
|
|
51
|
+
font-size: 1.2rem;
|
|
52
|
+
font-weight: 500;
|
|
53
|
+
line-height: 160%;
|
|
54
|
+
color: ${Colors.Grey2};
|
|
55
|
+
margin-top: 10px;
|
|
56
|
+
`;
|
|
57
|
+
|
|
58
|
+
type EllipsisProps = {
|
|
59
|
+
active: boolean
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const Ellipsis = styled.div<EllipsisProps>`
|
|
63
|
+
display: -webkit-box;
|
|
64
|
+
-webkit-line-clamp: ${props => props.active ? 3 : null};
|
|
65
|
+
-webkit-box-orient: ${props => props.active ? 'vertical' : null};
|
|
66
|
+
overflow: hidden;
|
|
67
|
+
text-overflow: ellipsis;
|
|
68
|
+
`;
|
|
69
|
+
|
|
70
|
+
const ShowMore = styled.div`
|
|
71
|
+
font-size: 1.2rem;
|
|
72
|
+
font-weight: 500;
|
|
73
|
+
line-height: 160%;
|
|
74
|
+
color: ${Colors.Orange};
|
|
75
|
+
transition: all 0.2s;
|
|
76
|
+
|
|
77
|
+
&:hover {
|
|
78
|
+
cursor: pointer;
|
|
79
|
+
color: ${Polished.lighten(0.025, Colors.Orange)};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
&:active {
|
|
83
|
+
color: ${Polished.darken(0.025, Colors.Orange)};
|
|
84
|
+
}
|
|
85
|
+
`;
|
|
86
|
+
|
|
87
|
+
export type ProductProps = {
|
|
88
|
+
title: string;
|
|
89
|
+
price: number;
|
|
90
|
+
subtitle?: string;
|
|
91
|
+
description?: string;
|
|
92
|
+
imageUrl?: string;
|
|
93
|
+
} & CounterProps
|
|
94
|
+
|
|
95
|
+
export default function Product({
|
|
96
|
+
title = '',
|
|
97
|
+
price = 0,
|
|
98
|
+
subtitle = '',
|
|
99
|
+
description = '',
|
|
100
|
+
// Counter Props
|
|
101
|
+
value,
|
|
102
|
+
minValue,
|
|
103
|
+
maxValue,
|
|
104
|
+
onIncrement,
|
|
105
|
+
onDecrement,
|
|
106
|
+
}: ProductProps) {
|
|
107
|
+
const [showMore, setShowMore] = useState(false);
|
|
108
|
+
const [showEllipsis, setShowEllipsis] = useState(true);
|
|
109
|
+
|
|
110
|
+
let descModified = description;
|
|
111
|
+
if (descModified.length > 210 && !showMore) {
|
|
112
|
+
descModified = descModified.substring(0, 210) + '...';
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const toggle = () => {
|
|
116
|
+
setShowEllipsis(!showEllipsis);
|
|
117
|
+
setShowMore(!showMore)
|
|
118
|
+
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return (
|
|
122
|
+
<Container>
|
|
123
|
+
<Row justify="space-between">
|
|
124
|
+
<Column>
|
|
125
|
+
<Title>{title}</Title>
|
|
126
|
+
<Price>{price}</Price>
|
|
127
|
+
</Column>
|
|
128
|
+
<Counter
|
|
129
|
+
value={value}
|
|
130
|
+
minValue={minValue}
|
|
131
|
+
maxValue={maxValue}
|
|
132
|
+
onIncrement={onIncrement}
|
|
133
|
+
onDecrement={onDecrement}
|
|
134
|
+
/>
|
|
135
|
+
</Row>
|
|
136
|
+
<Row>
|
|
137
|
+
{subtitle && <Subtitle>{subtitle}</Subtitle>}
|
|
138
|
+
{(() => {
|
|
139
|
+
if(!description) return;
|
|
140
|
+
|
|
141
|
+
return (
|
|
142
|
+
<Fragment>
|
|
143
|
+
<AnimateHeight height={showMore ? "auto" : 67}>
|
|
144
|
+
<Ellipsis active={showEllipsis}>
|
|
145
|
+
<Description>{description}</Description>
|
|
146
|
+
</Ellipsis>
|
|
147
|
+
</AnimateHeight>
|
|
148
|
+
<ShowMore onClick={() => toggle()}>
|
|
149
|
+
{showMore ? "Show Less" : "Show More"}
|
|
150
|
+
</ShowMore>
|
|
151
|
+
</Fragment>
|
|
152
|
+
);
|
|
153
|
+
})()}
|
|
154
|
+
</Row>
|
|
155
|
+
</Container>
|
|
156
|
+
);
|
|
157
|
+
}
|
package/src/index.tsx
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import ReactDOM from 'react-dom';
|
|
3
|
+
|
|
4
|
+
ReactDOM.render(<div />, document.getElementById('root'));
|
|
5
|
+
|
|
6
|
+
// If you want your app to work offline and load faster, you can change
|
|
7
|
+
// unregister() to register() below. Note this comes with some pitfalls.
|
|
8
|
+
// Learn more about service workers: https://bit.ly/CRA-PWA
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference types="react-scripts" />
|