@soul-refiner/design-system 0.1.0 → 0.1.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soul-refiner/design-system",
3
- "version": "0.1.0",
3
+ "version": "0.1.3",
4
4
  "main": "src/index.ts",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -59,7 +59,7 @@
59
59
  "slate-history": "^0.93.0",
60
60
  "slate-hyperscript": "^0.77.0",
61
61
  "slate-react": "^0.94.0",
62
- "styled-components": "^6.0.0-rc.1"
62
+ "styled-components": "^6.0.0-rc.3"
63
63
  },
64
64
  "peerDependencies": {
65
65
  "@emoji-mart/react": "^1.1.1",
@@ -1,4 +1,5 @@
1
1
  export const COLORS = [
2
+ 'inherit',
2
3
  'page-bg',
3
4
  'white',
4
5
  'primary-blue-0',
@@ -62,6 +62,8 @@ export namespace Styles {
62
62
  padding: ${({ $padding }) =>
63
63
  $padding && typeof $padding === 'number'
64
64
  ? `${$padding}px`
65
+ : $padding && typeof $padding === 'string' && $padding.includes('px')
66
+ ? $padding
65
67
  : $padding && typeof $padding === 'string'
66
68
  ? `var(--${$padding})`
67
69
  : '0px'};
@@ -0,0 +1,307 @@
1
+ import React from 'react';
2
+ import styled, { css } from 'styled-components';
3
+ import { Styles } from 'common';
4
+ import { Box, P } from 'components';
5
+ import { ChevronDown, ChevronUp } from 'icons';
6
+
7
+ const LG_ICON_SIZE = 20;
8
+ const LG_ICON_SIZE_WO_CHILDREN = 24;
9
+ const LG_FONT_SIZE = 16;
10
+ const LG_PADDING = '11px 19px';
11
+ const LG_PADDING_WO_CHILDREN = '11px';
12
+
13
+ const SM_ICON_SIZE = 16;
14
+ const SM_FONT_SIZE = 14;
15
+ const SM_PADDING = '5px 15px';
16
+ const SM_PADDING_WO_CHILDREN = '7px';
17
+
18
+ type ButtonTypes =
19
+ | 'primary'
20
+ | 'secondary'
21
+ | 'outlined'
22
+ | 'danger'
23
+ | 'text'
24
+ | 'raised'
25
+ | 'special';
26
+ type ButtonSize = 'small' | 'large';
27
+ type ButtonShape = 'none' | 'small' | 'medium-small' | 'large';
28
+
29
+ export interface ButtonProps extends React.PropsWithChildren {
30
+ as?: React.ElementType;
31
+ disabled?: boolean;
32
+ icon?: React.ReactElement | undefined;
33
+ isDropdownOpen?: boolean;
34
+ roundness?: ButtonShape;
35
+ size?: ButtonSize;
36
+ type?: ButtonTypes;
37
+ }
38
+
39
+ export const Button = ({
40
+ as = 'button',
41
+ children,
42
+ disabled,
43
+ icon,
44
+ isDropdownOpen,
45
+ size = 'large',
46
+ roundness = 'large',
47
+ type = 'primary',
48
+ ...props
49
+ }: ButtonProps) => {
50
+ const Component = Components()[type];
51
+
52
+ const buttonIcon = React.Children.map(icon, (item) => {
53
+ if (React.isValidElement(item))
54
+ return {
55
+ ...item,
56
+ props: {
57
+ size:
58
+ size === 'large' && !children
59
+ ? LG_ICON_SIZE_WO_CHILDREN
60
+ : size === 'large'
61
+ ? LG_ICON_SIZE
62
+ : SM_ICON_SIZE,
63
+ },
64
+ };
65
+ })?.[0];
66
+
67
+ const dropdownIcon =
68
+ isDropdownOpen === true ? (
69
+ <ChevronUp size={size === 'large' ? LG_ICON_SIZE : SM_ICON_SIZE} />
70
+ ) : isDropdownOpen === false ? (
71
+ <ChevronDown size={size === 'large' ? LG_ICON_SIZE : SM_ICON_SIZE} />
72
+ ) : undefined;
73
+
74
+ const padding = !!children
75
+ ? size === 'large'
76
+ ? LG_PADDING
77
+ : SM_PADDING
78
+ : size === 'large'
79
+ ? LG_PADDING_WO_CHILDREN
80
+ : SM_PADDING_WO_CHILDREN;
81
+
82
+ return (
83
+ <Component
84
+ as={as}
85
+ disabled={disabled}
86
+ $align="center"
87
+ $display="flex"
88
+ $gap={size === 'large' ? 12 : 8}
89
+ $hasChildren={!!children}
90
+ $justify="center"
91
+ $padding={padding}
92
+ $roundness={roundness}
93
+ $size={size}
94
+ {...props}
95
+ >
96
+ {buttonIcon}
97
+ {children && (
98
+ <P
99
+ as="span"
100
+ $mediumBold
101
+ $fontSize={size === 'large' ? LG_FONT_SIZE : SM_FONT_SIZE}
102
+ $color="inherit"
103
+ >
104
+ {children}
105
+ </P>
106
+ )}
107
+ {!!children && dropdownIcon}
108
+ </Component>
109
+ );
110
+ };
111
+
112
+ const Components = (): Record<ButtonTypes, any> => ({
113
+ primary: Primary,
114
+ secondary: Secondary,
115
+ outlined: Outlined,
116
+ danger: Danger,
117
+ raised: Raised,
118
+ special: Special,
119
+ text: Text,
120
+ });
121
+
122
+ const base = css<{
123
+ $roundness: ButtonShape;
124
+ }>`
125
+ display: flex;
126
+ border-radius: ${({ $roundness }) =>
127
+ $roundness === 'large'
128
+ ? '32px'
129
+ : $roundness === 'medium-small'
130
+ ? '8px'
131
+ : $roundness === 'small'
132
+ ? '4px'
133
+ : '0px'};
134
+ cursor: pointer;
135
+ user-select: none;
136
+ box-sizing: border-box;
137
+ outline: none;
138
+
139
+ svg {
140
+ fill: currentColor;
141
+ }
142
+
143
+ &:disabled {
144
+ background-color: var(--color-grey-9) !important;
145
+ border: 1px solid var(--color-grey-8) !important;
146
+ color: var(--color-grey-7) !important;
147
+ cursor: unset !important;
148
+ }
149
+ `;
150
+
151
+ const Primary = styled(Box)<{
152
+ $roundness: ButtonShape;
153
+ }>`
154
+ background-color: var(--color-primary-blue-2);
155
+ color: var(--color-white);
156
+ border: 1px solid var(--color-primary-blue-2);
157
+
158
+ &:hover {
159
+ border: 1px solid var(--color-primary-blue-1);
160
+ background-color: var(--color-primary-blue-1);
161
+ }
162
+
163
+ &:active {
164
+ border: 1px solid var(--color-primary-blue-0);
165
+ background-color: var(--color-primary-blue-0);
166
+ }
167
+
168
+ ${base}
169
+ ${Styles.flex}
170
+ ${Styles.padding}
171
+ `;
172
+
173
+ const Secondary = styled(Box)<{
174
+ $roundness: ButtonShape;
175
+ }>`
176
+ background-color: var(--color-primary-blue-4);
177
+ color: var(--color-primary-blue-2);
178
+ border: 1px solid var(--color-primary-blue-4);
179
+
180
+ &:hover {
181
+ border: 1px solid var(--color-primary-blue-2);
182
+ color: var(--color-primary-blue-1);
183
+ }
184
+
185
+ &:active {
186
+ color: var(--color-primary-blue-0);
187
+ }
188
+
189
+ ${base}
190
+ ${Styles.flex}
191
+ ${Styles.padding}
192
+ `;
193
+
194
+ const Outlined = styled(Box)<{
195
+ $roundness: ButtonShape;
196
+ }>`
197
+ background-color: var(--color-white);
198
+ color: var(--color-grey-3);
199
+ border: 1px solid var(--color-grey-8);
200
+
201
+ &:active {
202
+ background-color: var(--color-grey-8);
203
+ }
204
+
205
+ ${base}
206
+ ${Styles.flex}
207
+ ${Styles.padding}
208
+ `;
209
+
210
+ const Danger = styled(Box)<{
211
+ $roundness: ButtonShape;
212
+ }>`
213
+ background-color: var(--color-red-4);
214
+ color: var(--color-white);
215
+ border: 1px solid var(--color-red-4);
216
+
217
+ &:hover {
218
+ border: 1px solid var(--color-red-3);
219
+ background-color: var(--color-red-3);
220
+ }
221
+
222
+ &:active {
223
+ border: 1px solid var(--color-red-2);
224
+ background-color: var(--color-red-2);
225
+ }
226
+
227
+ ${base}
228
+ ${Styles.flex}
229
+ ${Styles.padding}
230
+ `;
231
+
232
+ const Text = styled(Box)<{
233
+ $roundness: ButtonShape;
234
+ }>`
235
+ background-color: transparent;
236
+ border: 1px solid transparent;
237
+ color: var(--color-primary-blue-2);
238
+
239
+ &:hover {
240
+ color: var(--color-primary-blue-1);
241
+ }
242
+
243
+ &:active {
244
+ color: var(--color-primary-blue-0);
245
+ }
246
+
247
+ &:disabled {
248
+ background-color: transparent !important;
249
+ border: 1px solid transparent !important;
250
+ }
251
+
252
+ ${base}
253
+ ${Styles.flex}
254
+ ${Styles.padding}
255
+ `;
256
+
257
+ const Raised = styled(Box)<{
258
+ $roundness: ButtonShape;
259
+ }>`
260
+ background-color: var(--color-white);
261
+ color: var(--color-grey-3);
262
+ border: 1px solid var(--color-white);
263
+ box-shadow: var(--elevation-1);
264
+
265
+ &:hover {
266
+ background-color: var(--color-grey-9);
267
+ border: 1px solid var(--color-grey-9);
268
+ }
269
+
270
+ &:active {
271
+ background-color: var(--color-grey-8);
272
+ border: 1px solid var(--color-grey-8);
273
+ }
274
+
275
+ &:disabled {
276
+ border: 1px solid var(--color-grey-9) !important;
277
+ }
278
+
279
+ ${base}
280
+ ${Styles.flex}
281
+ ${Styles.padding}
282
+ `;
283
+
284
+ const Special = styled(Box)<{
285
+ $roundness: ButtonShape;
286
+ }>`
287
+ background-color: transparent;
288
+ border: 1px solid transparent;
289
+ color: var(--color-primary-grey-3);
290
+
291
+ &:hover {
292
+ color: var(--color-grey-3);
293
+ }
294
+
295
+ &:active {
296
+ background-color: var(--color-grey-9);
297
+ }
298
+
299
+ &:disabled {
300
+ background-color: transparent !important;
301
+ border: 1px solid transparent !important;
302
+ }
303
+
304
+ ${base}
305
+ ${Styles.flex}
306
+ ${Styles.padding}
307
+ `;
@@ -0,0 +1,2 @@
1
+ export { Button } from './button';
2
+ export type { ButtonProps } from './button';
@@ -0,0 +1,2 @@
1
+ export { Button } from './button';
2
+ export type { ButtonProps } from './button';
@@ -1,3 +1,5 @@
1
+ export { Button } from './actions';
2
+ export type { ButtonProps } from './actions';
1
3
  export { Box, Display, H, P, Typography } from './atoms';
2
4
  export type {
3
5
  BoxProps,
@@ -8,3 +10,5 @@ export type {
8
10
  } from './atoms';
9
11
  export { Avatar, Icon } from './iconography';
10
12
  export type { AvatarGroupProps, AvatarProps, IconProps } from './iconography';
13
+ export { Modal } from './surfaces';
14
+ export type { ModalContentProps, ModalProps } from './surfaces';
@@ -0,0 +1,2 @@
1
+ export { Modal } from './modal';
2
+ export type { ModalContentProps, ModalProps } from './modal';
@@ -0,0 +1,2 @@
1
+ export { Modal } from './modal';
2
+ export type { ModalProps, ModalContentProps } from './modal';
@@ -0,0 +1,179 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+ import { Button } from 'components';
4
+ import { Close } from 'icons';
5
+
6
+ const callAll =
7
+ (...fns: ((...args: unknown[]) => unknown)[]) =>
8
+ (...args: any) =>
9
+ fns.forEach((fn) => fn && fn(...args));
10
+
11
+ const ModalContext = React.createContext<
12
+ [boolean, React.Dispatch<React.SetStateAction<boolean>>]
13
+ >([false, (() => undefined) as React.Dispatch<React.SetStateAction<boolean>>]);
14
+
15
+ export interface ModalProps extends React.PropsWithChildren {
16
+ /**
17
+ * This is to make the Modal a controlled component,
18
+ * instead of it managing its own state
19
+ */
20
+ controlledOpen?: boolean;
21
+ }
22
+
23
+ const Modal = ({ controlledOpen, ...props }: ModalProps) => {
24
+ const [open, setOpen] = React.useState(controlledOpen || false);
25
+
26
+ React.useEffect(() => {
27
+ if (controlledOpen !== undefined) {
28
+ setOpen(controlledOpen);
29
+ }
30
+ }, [controlledOpen]);
31
+
32
+ return <ModalContext.Provider value={[open, setOpen]} {...props} />;
33
+ };
34
+
35
+ const ModalTrigger = ({
36
+ children: child,
37
+ }: {
38
+ children: React.ReactElement;
39
+ }) => {
40
+ const [, setOpen] = React.useContext(ModalContext);
41
+ return (
42
+ child &&
43
+ React.cloneElement(child, {
44
+ onClick: callAll(() => setOpen(true), child.props.onClick),
45
+ })
46
+ );
47
+ };
48
+
49
+ ModalTrigger.displayName = 'Modal.Trigger';
50
+ Modal.Trigger = ModalTrigger;
51
+
52
+ const ModalDismiss = ({
53
+ children: child,
54
+ setClosed,
55
+ }: {
56
+ children: React.ReactElement;
57
+ setClosed?: () => void;
58
+ }) => {
59
+ const [, setOpen] = React.useContext(ModalContext);
60
+ return (
61
+ child &&
62
+ React.cloneElement(child, {
63
+ onClick: callAll(
64
+ () => setOpen(false),
65
+ child.props.onClick,
66
+ () => setClosed && setClosed()
67
+ ),
68
+ })
69
+ );
70
+ };
71
+
72
+ ModalDismiss.displayName = 'Modal.Dismiss';
73
+ Modal.Dismiss = ModalDismiss;
74
+
75
+ export interface ModalContentProps extends React.PropsWithChildren {
76
+ backgroundDark?: boolean;
77
+ footer?: React.ReactElement;
78
+ header?: React.ReactElement;
79
+ setClosed?: () => void;
80
+ }
81
+
82
+ const ModalContent = ({
83
+ backgroundDark = true,
84
+ children,
85
+ footer,
86
+ header,
87
+ setClosed,
88
+ ...props
89
+ }: ModalContentProps) => {
90
+ const [open, setOpen] = React.useContext(ModalContext);
91
+
92
+ const handleOutsideClick = (event: React.MouseEvent) => {
93
+ if (event.currentTarget != event.target) return;
94
+ setClosed ? setClosed() : setOpen(false);
95
+ };
96
+
97
+ return (
98
+ <Wrapper
99
+ $backgroundDark={backgroundDark}
100
+ $open={open}
101
+ onClick={handleOutsideClick}
102
+ >
103
+ <Content {...props}>
104
+ {header && (
105
+ <div className="header">
106
+ <div>{header}</div>
107
+ <Modal.Dismiss setClosed={setClosed}>
108
+ <Button icon={<Close />} type="special" />
109
+ </Modal.Dismiss>
110
+ </div>
111
+ )}
112
+ {children}
113
+ {footer && <div className="footer">{footer}</div>}
114
+ </Content>
115
+ </Wrapper>
116
+ );
117
+ };
118
+
119
+ ModalContent.displayName = 'Modal.Content';
120
+ Modal.Content = ModalContent;
121
+
122
+ export { Modal };
123
+
124
+ const Wrapper = styled.div<{
125
+ $open: boolean;
126
+ $backgroundDark: boolean;
127
+ }>`
128
+ ${({ $open }) =>
129
+ $open
130
+ ? `display: flex;
131
+ flex-direction: column;
132
+ align-items: center;
133
+ justify-content: center;`
134
+ : 'display: none;'}
135
+ ${({ $backgroundDark }) =>
136
+ $backgroundDark
137
+ ? `background: radial-gradient(
138
+ 79.02% 79.02% at 50% 0%,
139
+ rgba(0, 27, 58, 0.8) 0%,
140
+ rgba(0, 0, 0, 0.8) 100%
141
+ );
142
+ backdrop-filter: blur(5px);
143
+ cursor: pointer;`
144
+ : ''}
145
+ position: fixed;
146
+ top: 0;
147
+ left: 0;
148
+ z-index: 100;
149
+ width: 100vw;
150
+ height: 100vh;
151
+ padding: 0px;
152
+ margin: 0px;
153
+ overflow: hidden;
154
+ `;
155
+
156
+ const Content = styled.div`
157
+ position: absolute;
158
+ z-index: 101;
159
+ background-color: var(--color-white);
160
+ box-shadow: var(--elevation-2);
161
+ border-radius: var(--small);
162
+ cursor: initial;
163
+
164
+ [class~='header'] {
165
+ display: flex;
166
+ align-items: center;
167
+ padding: 16px;
168
+ border-bottom: 1px solid var(--color-grey-8);
169
+ > *:first-child {
170
+ flex: 1;
171
+ display: block;
172
+ }
173
+ }
174
+
175
+ [class~='footer'] {
176
+ padding: 16px;
177
+ border-top: 1px solid var(--color-grey-8);
178
+ }
179
+ `;
@@ -67,13 +67,12 @@ export { Menu } from './menu';
67
67
  export { MenuCircle } from './menu_circle';
68
68
  export { MenuDots } from './menu_dots';
69
69
  export { Minimize } from './minimize';
70
- export { Microphone } from './microphone';
71
70
  export { MicrophoneSlash } from './microphone_slash';
72
71
  export { Minus } from './minus';
73
72
  export { MinusCircle } from './minus_circle';
74
73
  export { New } from './new';
75
74
  export { Newspaper } from './newspaper';
76
- export { Note } from './note';
75
+ export { NotePad } from './note_pad';
77
76
  export { Options } from './options';
78
77
  export { PaintBrush } from './paint_brush';
79
78
  export { Paperclip } from './paperclip';
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { Icon, IconProps } from 'components';
3
3
 
4
- export const Note = (props: IconProps) => {
4
+ export const NotePad = (props: IconProps) => {
5
5
  return (
6
6
  <Icon {...props}>
7
7
  <path
@@ -1,13 +1,20 @@
1
+ export * from './arrow';
2
+ export * from './audio_video';
1
3
  export * from './basic';
2
4
  export * from './data';
3
5
  export * from './email';
4
- export * from './finance';
5
6
  export * from './file';
7
+ export * from './finance';
6
8
  export * from './layout';
7
9
  export * from './maps';
8
10
  export * from './message';
11
+ export * from './misc';
9
12
  export * from './notifications';
10
13
  export * from './people';
14
+ export * from './phone';
11
15
  export * from './security';
16
+ export * from './shopping';
12
17
  export * from './symbols';
18
+ export * from './technology';
19
+ export * from './text';
13
20
  export * from './time';
@@ -15,7 +15,7 @@ export { Lightbulb } from './light_bulb';
15
15
  export { Moon } from './moon';
16
16
  export { Nut } from './nut';
17
17
  export { Planet } from './planet';
18
- export { Plus } from './plus';
18
+ export { PlusThick } from './plus_thick';
19
19
  export { Pocket } from './pocket';
20
20
  export { Rocket } from './rocket';
21
21
  export { Soup } from './soup';
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { Icon, IconProps } from 'components';
3
3
 
4
- export const Plus = (props: IconProps) => {
4
+ export const PlusThick = (props: IconProps) => {
5
5
  return (
6
6
  <Icon {...props}>
7
7
  <path
package/src/index.ts CHANGED
@@ -1 +1,2 @@
1
- export { Avatar, Box, Icon, Display, H, P } from './components';
1
+ export * from './components';
2
+ export * as Icons from './icons';
@@ -1,14 +0,0 @@
1
- import React from 'react';
2
- import { Icon, IconProps } from 'components';
3
-
4
- export const Microphone = (props: IconProps) => {
5
- return (
6
- <Icon {...props}>
7
- <path
8
- fillRule="evenodd"
9
- clipRule="evenodd"
10
- d="M7.99935 0.666687C9.47211 0.666687 10.666 1.86059 10.666 3.33335V8.00002C10.666 9.47278 9.47211 10.6667 7.99935 10.6667C6.52659 10.6667 5.33268 9.47278 5.33268 8.00002V3.33335C5.33268 1.86059 6.52659 0.666687 7.99935 0.666687ZM8.66602 13.2921V14H10.666V15.3334H5.33268V14H7.33268V13.2921C4.70181 12.964 2.66602 10.7198 2.66602 8.00002V6.66669H3.99935V8.00002C3.99935 10.2092 5.79021 12 7.99935 12C10.2085 12 11.9993 10.2092 11.9993 8.00002V6.66669H13.3327V8.00002C13.3327 10.7198 11.2969 12.964 8.66602 13.2921ZM6.66602 3.33335C6.66602 2.59697 7.26297 2.00002 7.99935 2.00002C8.73573 2.00002 9.33268 2.59697 9.33268 3.33335V8.00002C9.33268 8.7364 8.73573 9.33335 7.99935 9.33335C7.26297 9.33335 6.66602 8.7364 6.66602 8.00002V3.33335Z"
11
- />
12
- </Icon>
13
- );
14
- };