@mailstep/design-system 0.0.0

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.
Files changed (51) hide show
  1. package/.eslintrc.cjs +16 -0
  2. package/.storybook/main.ts +17 -0
  3. package/.storybook/preview.ts +20 -0
  4. package/.storybook/withRouter.tsx +12 -0
  5. package/.storybook/withTheme.tsx +23 -0
  6. package/README.md +0 -0
  7. package/package.json +52 -0
  8. package/public/vite.svg +1 -0
  9. package/src/packages/ui/Elements/Button/Button.d.ts +4 -0
  10. package/src/packages/ui/Elements/Button/Button.tsx +42 -0
  11. package/src/packages/ui/Elements/Button/index.d.ts +6 -0
  12. package/src/packages/ui/Elements/Button/index.ts +5 -0
  13. package/src/packages/ui/Elements/Button/stories/Button.stories.ts +84 -0
  14. package/src/packages/ui/Elements/Button/styles.ts +289 -0
  15. package/src/packages/ui/Elements/Button/types.ts +31 -0
  16. package/src/packages/ui/Elements/Icon/BadgeIcon.tsx +45 -0
  17. package/src/packages/ui/Elements/Icon/Icon.tsx +288 -0
  18. package/src/packages/ui/Elements/Icon/icons/FlagCZ.tsx +10 -0
  19. package/src/packages/ui/Elements/Icon/icons/FlagUSA.tsx +27 -0
  20. package/src/packages/ui/Elements/Icon/icons/index.ts +2 -0
  21. package/src/packages/ui/Elements/Icon/index.d.ts +9 -0
  22. package/src/packages/ui/Elements/Icon/index.ts +6 -0
  23. package/src/packages/ui/Elements/Icon/stories/BadgeIcon.stories.tsx +27 -0
  24. package/src/packages/ui/Elements/Icon/stories/Icon.stories.tsx +60 -0
  25. package/src/packages/ui/Elements/Icon/types.ts +26 -0
  26. package/src/packages/ui/Elements/Spinner/README.md +9 -0
  27. package/src/packages/ui/Elements/Spinner/Spinner.tsx +36 -0
  28. package/src/packages/ui/Elements/Spinner/index.d.ts +5 -0
  29. package/src/packages/ui/Elements/Spinner/index.ts +3 -0
  30. package/src/packages/ui/Elements/Spinner/stories/Spinner.stories.ts +70 -0
  31. package/src/packages/ui/Elements/Spinner/styles.ts +38 -0
  32. package/src/packages/ui/Elements/Spinner/types.ts +8 -0
  33. package/src/packages/ui/Elements/Spinner/yarn.lock +4 -0
  34. package/src/packages/ui/ThemeProvider/README.md +0 -0
  35. package/src/packages/ui/ThemeProvider/ThemeProvider.d.ts +3 -0
  36. package/src/packages/ui/ThemeProvider/ThemeProvider.tsx +14 -0
  37. package/src/packages/ui/ThemeProvider/index.d.ts +8 -0
  38. package/src/packages/ui/ThemeProvider/index.ts +6 -0
  39. package/src/packages/ui/ThemeProvider/themes/default.ts +144 -0
  40. package/src/packages/ui/ThemeProvider/themes/index.ts +11 -0
  41. package/src/packages/ui/ThemeProvider/themes/light.ts +10 -0
  42. package/src/packages/ui/ThemeProvider/themes/mailwise.ts +215 -0
  43. package/src/packages/ui/ThemeProvider/types.ts +54 -0
  44. package/src/packages/ui/ThemeProvider/yarn.lock +4 -0
  45. package/src/stories/themes/default.ts +144 -0
  46. package/src/stories/themes/index.ts +11 -0
  47. package/src/stories/themes/light.ts +10 -0
  48. package/src/stories/themes/mailwise.ts +215 -0
  49. package/tsconfig.json +25 -0
  50. package/tsconfig.node.json +10 -0
  51. package/vite.config.ts +7 -0
package/.eslintrc.cjs ADDED
@@ -0,0 +1,16 @@
1
+ module.exports = {
2
+ root: true,
3
+ env: {
4
+ browser: true,
5
+ es2020: true
6
+ },
7
+ extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'plugin:react-hooks/recommended', 'plugin:storybook/recommended'],
8
+ ignorePatterns: ['dist', '.eslintrc.cjs'],
9
+ parser: '@typescript-eslint/parser',
10
+ plugins: ['react-refresh'],
11
+ rules: {
12
+ 'react-refresh/only-export-components': ['warn', {
13
+ allowConstantExport: true
14
+ }]
15
+ }
16
+ };
@@ -0,0 +1,17 @@
1
+ import type { StorybookConfig } from "@storybook/react-vite";
2
+ const config: StorybookConfig = {
3
+ stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
4
+ addons: [
5
+ "@storybook/addon-links",
6
+ "@storybook/addon-essentials",
7
+ "@storybook/addon-interactions",
8
+ ],
9
+ framework: {
10
+ name: "@storybook/react-vite",
11
+ options: {},
12
+ },
13
+ docs: {
14
+ autodocs: "tag",
15
+ },
16
+ };
17
+ export default config;
@@ -0,0 +1,20 @@
1
+ import withTheme from './withTheme'
2
+ import withRouter from './withRouter'
3
+
4
+ import type { Preview } from "@storybook/react";
5
+
6
+ const preview: Preview = {
7
+ parameters: {
8
+ actions: { argTypesRegex: "^on[A-Z].*" },
9
+ controls: {
10
+ matchers: {
11
+ color: /(background|color)$/i,
12
+ date: /Date$/,
13
+ },
14
+ },
15
+ },
16
+ };
17
+
18
+ export const decorators = [withTheme, withRouter];
19
+
20
+ export default preview;
@@ -0,0 +1,12 @@
1
+ import React from 'react'
2
+ import { MemoryRouter } from 'react-router-dom'
3
+
4
+ const withProvider = (Story: React.FC): JSX.Element => (
5
+ <>
6
+ <MemoryRouter>
7
+ <Story />
8
+ </MemoryRouter>
9
+ </>
10
+ )
11
+
12
+ export default withProvider
@@ -0,0 +1,23 @@
1
+ import React from 'react'
2
+ import { ThemeProvider } from '@xstyled/styled-components'
3
+ import { createGlobalStyle } from 'styled-components'
4
+ import themes from '../src/packages/ui/ThemeProvider/themes'
5
+
6
+ const GlobalStyle = createGlobalStyle`
7
+ @import url('${themes.default.fontLinks?.[0]}');
8
+ body {
9
+ font-family: ${themes.default.fonts?.primary}
10
+ }
11
+
12
+ `
13
+
14
+ const withTheme = (Story: React.FC): JSX.Element => {
15
+ return (
16
+ <ThemeProvider theme={themes.default}>
17
+ <GlobalStyle />
18
+ <Story />
19
+ </ThemeProvider>
20
+ )
21
+ }
22
+
23
+ export default withTheme
package/README.md ADDED
File without changes
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@mailstep/design-system",
3
+ "version": "0.0.0",
4
+ "type": "module",
5
+ "scripts": {
6
+ "dev": "storybook dev -p 6006",
7
+ "build": "tsc && vite build",
8
+ "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
9
+ "publish": "npm publish --access public",
10
+ "preview": "vite preview",
11
+ "build-storybook": "storybook build"
12
+ },
13
+ "dependencies": {
14
+ "@fortawesome/fontawesome-svg-core": "^6.3.0",
15
+ "@fortawesome/free-brands-svg-icons": "^6.1.1",
16
+ "@fortawesome/pro-duotone-svg-icons": "^6.0.0",
17
+ "@fortawesome/pro-light-svg-icons": "^6.0.0",
18
+ "@fortawesome/pro-regular-svg-icons": "^6.0.0",
19
+ "@fortawesome/pro-solid-svg-icons": "^6.3.0",
20
+ "@fortawesome/react-fontawesome": "^0.2.0",
21
+ "@xstyled/styled-components": "^3.8.0",
22
+ "react": "^18.2.0",
23
+ "react-dom": "^18.2.0",
24
+ "react-router-dom": "^6.17.0",
25
+ "styled-components": "^5.3.10"
26
+ },
27
+ "devDependencies": {
28
+ "@storybook/addon-essentials": "^7.5.2",
29
+ "@storybook/addon-interactions": "^7.5.2",
30
+ "@storybook/addon-links": "^7.5.2",
31
+ "@storybook/blocks": "^7.5.2",
32
+ "@storybook/react": "^7.5.2",
33
+ "@storybook/react-vite": "^7.5.2",
34
+ "@storybook/testing-library": "^0.0.14-next.2",
35
+ "@types/react": "^18.2.15",
36
+ "@types/react-dom": "^18.2.7",
37
+ "@typescript-eslint/eslint-plugin": "^6.0.0",
38
+ "@typescript-eslint/parser": "^6.0.0",
39
+ "@vitejs/plugin-react-swc": "^3.3.2",
40
+ "eslint": "^8.45.0",
41
+ "eslint-plugin-react-hooks": "^4.6.0",
42
+ "eslint-plugin-react-refresh": "^0.4.3",
43
+ "eslint-plugin-storybook": "^0.6.15",
44
+ "prop-types": "^15.8.1",
45
+ "storybook": "^7.5.2",
46
+ "typescript": "^5.0.2",
47
+ "vite": "^4.4.5"
48
+ },
49
+ "resolutions": {
50
+ "jackspeak": "2.1.1"
51
+ }
52
+ }
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
@@ -0,0 +1,4 @@
1
+ import { Props } from './types'
2
+ declare interface Button {
3
+ (props: Props): JSX.Element
4
+ }
@@ -0,0 +1,42 @@
1
+ import { StyledButton, LoadingIconWrapper, StyledIcon, StyledWrapper } from './styles'
2
+ import { Props } from './types'
3
+ import Spinner from '../Spinner'
4
+
5
+ const Button = ({
6
+ isLoading,
7
+ loadingText,
8
+ icon,
9
+ appearance = 'primary',
10
+ disabled = false,
11
+ sizing = 'normal',
12
+ buttonRef,
13
+ onClick,
14
+ fullWidth = false,
15
+ ...props
16
+ }: Props): JSX.Element => (
17
+ <StyledButton
18
+ {...props}
19
+ onClick={!disabled && !isLoading ? onClick : undefined}
20
+ data-appearance={appearance}
21
+ data-sizing={sizing}
22
+ disabled={disabled}
23
+ ref={buttonRef}
24
+ fullWidth={fullWidth}
25
+ >
26
+ <StyledWrapper>
27
+ {icon && (typeof icon === 'string' ? <StyledIcon $addMargin={!!props.children} icon={icon} /> : icon)}
28
+ {isLoading ? (
29
+ <>
30
+ <LoadingIconWrapper $addMargin={!!loadingText || !!props.children}>
31
+ <Spinner variant="sm" />
32
+ </LoadingIconWrapper>
33
+ {loadingText || loadingText === '' ? loadingText : 'Loading'}
34
+ </>
35
+ ) : (
36
+ props.children
37
+ )}
38
+ </StyledWrapper>
39
+ </StyledButton>
40
+ )
41
+
42
+ export default Button
@@ -0,0 +1,6 @@
1
+ import { Props, AppearanceValue } from './types'
2
+
3
+ declare const Button: (props: Props) => JSX.Element
4
+
5
+ export default Button
6
+ export { AppearanceValue, Props }
@@ -0,0 +1,5 @@
1
+ import Button from './Button'
2
+ import { AppearanceValue } from './types'
3
+
4
+ export default Button
5
+ export type { AppearanceValue }
@@ -0,0 +1,84 @@
1
+ import type { Meta, StoryObj } from '@storybook/react'
2
+ import Button from '../'
3
+
4
+ const meta = {
5
+ title: 'Elements/Button',
6
+ component: Button,
7
+ tags: ['autodocs'],
8
+ argTypes: {},
9
+ } satisfies Meta<typeof Button>
10
+
11
+ export default meta
12
+ type Story = StoryObj<typeof meta>
13
+
14
+ export const Primary: Story = {
15
+ args: {
16
+ children: 'Primary',
17
+ },
18
+ }
19
+
20
+ export const PrimaryLight: Story = {
21
+ args: {
22
+ children: 'Primary Light',
23
+ appearance: 'primaryLight',
24
+ },
25
+ }
26
+
27
+ export const Secondary: Story = {
28
+ args: {
29
+ children: 'Secondary',
30
+ appearance: 'secondary',
31
+ },
32
+ }
33
+
34
+ export const Success: Story = {
35
+ args: {
36
+ children: 'Success',
37
+ appearance: 'success',
38
+ },
39
+ }
40
+
41
+ export const Large: Story = {
42
+ args: {
43
+ children: 'Large',
44
+ sizing: 'large',
45
+ },
46
+ }
47
+
48
+ export const Small: Story = {
49
+ args: {
50
+ children: 'Small',
51
+ sizing: 'normal',
52
+ },
53
+ }
54
+
55
+ export const DisabledPrimary: Story = {
56
+ args: {
57
+ children: 'Disabled',
58
+ disabled: true,
59
+ },
60
+ }
61
+
62
+ export const DisabledSecondary: Story = {
63
+ args: {
64
+ children: 'Disabled',
65
+ disabled: true,
66
+ appearance: 'secondary',
67
+ },
68
+ }
69
+
70
+ export const Loading: Story = {
71
+ args: {
72
+ appearance: 'secondary',
73
+ loadingText: 'Loading...',
74
+ isLoading: true,
75
+ },
76
+ }
77
+
78
+ export const WithIcon: Story = {
79
+ args: {
80
+ label: 'Button',
81
+ children: 'Small',
82
+ icon: 'coffee',
83
+ },
84
+ }
@@ -0,0 +1,289 @@
1
+ import { th } from '@xstyled/styled-components'
2
+ import styled from '@xstyled/styled-components'
3
+ import Icon from '../Icon'
4
+
5
+ export const StyledWrapper = styled.span`
6
+ display: flex;
7
+ justify-content: center;
8
+ align-items: center;
9
+ `
10
+
11
+ export const LoadingIconWrapper = styled.div<{
12
+ $addMargin: boolean
13
+ }>`
14
+ & svg {
15
+ margin-right: ${({ $addMargin }: { $addMargin: boolean }): string => ($addMargin ? '0.5em' : '0')};
16
+ }
17
+ `
18
+
19
+ export const StyledIcon = styled(Icon)<{
20
+ $addMargin: boolean
21
+ }>`
22
+ & svg {
23
+ height: 1em;
24
+ margin-right: ${({ $addMargin }): string => ($addMargin ? '0.5em' : '0')};
25
+ }
26
+ `
27
+
28
+ export const StyledButton = styled.button<{
29
+ disabled: boolean
30
+ columnAlign?: boolean
31
+ children?: any
32
+ onClick?: React.MouseEventHandler<HTMLButtonElement> | undefined
33
+ fullWidth: boolean
34
+ mt?: string | number
35
+ mr?: string | number
36
+ mb?: string | number
37
+ ml?: string | number
38
+ }>`
39
+ width: ${({ fullWidth }) => (fullWidth ? '100%' : 'initial')};
40
+ margin-top: ${({ mt }) => (mt ? mt : 0)};
41
+ margin-right: ${({ mr }) => (mr ? mr : 0)};
42
+ margin-bottom: ${({ mb }) => (mb ? mb : 0)};
43
+ margin-left: ${({ ml }) => (ml ? ml : 0)};
44
+ height: 2.5em;
45
+ border: slim;
46
+ text-align: center;
47
+ text-decoration: none;
48
+ display: ${({ columnAlign }) => (columnAlign ? 'flex' : 'inline-flex')};
49
+ flex-direction: ${({ columnAlign }) => (columnAlign ? 'column' : 'auto')};
50
+ align-items: ${({ columnAlign }) => (columnAlign ? 'center' : 'auto')};
51
+ font-family: ${th('fonts.primary')};
52
+ font-weight: semiBold;
53
+ border-radius: lg;
54
+ cursor: pointer;
55
+ transition-duration: 0.1s;
56
+ align-items: center;
57
+ justify-content: center;
58
+ transition: all 300ms ease-out;
59
+ pointer-events: ${({ disabled }) => (disabled ? 'none' : 'auto')};
60
+ opacity: ${({ disabled }) => (disabled ? '0.6' : '1')};
61
+
62
+ :disabled {
63
+ color: lightGray5;
64
+ }
65
+
66
+ :focus {
67
+ outline: none;
68
+ }
69
+
70
+ &[data-appearance='primary'] {
71
+ background-color: red1;
72
+ color: white;
73
+ border-color: red1;
74
+
75
+ @media (hover: hover) {
76
+ &:hover {
77
+ background-color: white;
78
+ color: red1;
79
+ border-color: red1;
80
+ }
81
+ }
82
+
83
+ :active {
84
+ background-color: red1;
85
+ color: red1;
86
+ border: none;
87
+ }
88
+
89
+ :disabled {
90
+ background-color: bgLightGray;
91
+ border-color: lightGray5;
92
+ color: gray3;
93
+ }
94
+ }
95
+
96
+ &[data-appearance='primaryLight'] {
97
+ color: red1;
98
+ background-color: red20;
99
+ border-color: red20;
100
+
101
+ @media (hover: hover) {
102
+ &:hover {
103
+ background-color: red1;
104
+ color: white;
105
+ border-color: red1;
106
+ }
107
+ }
108
+
109
+ :active {
110
+ background-color: red1;
111
+ color: white;
112
+ border-color: red1;
113
+ }
114
+
115
+ :disabled {
116
+ background-color: bgLightGray;
117
+ border-color: lightGray5;
118
+ color: gray3;
119
+ }
120
+ }
121
+
122
+ &[data-appearance='success'] {
123
+ background-color: successColor;
124
+ color: white;
125
+ border-color: successColor;
126
+
127
+ @media (hover: hover) {
128
+ &:hover {
129
+ background-color: white;
130
+ color: successColor;
131
+ }
132
+ }
133
+
134
+ :active {
135
+ background-color: white;
136
+ color: successColor;
137
+ }
138
+
139
+ :disabled {
140
+ background-color: bgLightGray;
141
+ border-color: lightGray5;
142
+ color: gray3;
143
+ }
144
+ }
145
+
146
+ &[data-appearance='secondary'] {
147
+ background-color: white;
148
+ color: red1;
149
+ border-color: red1;
150
+
151
+ @media (hover: hover) {
152
+ &:hover {
153
+ background-color: red1;
154
+ color: white;
155
+ border-color: red1;
156
+ }
157
+ }
158
+
159
+ :active {
160
+ background-color: red1;
161
+ color: red1;
162
+ border-color: red1;
163
+ }
164
+
165
+ :disabled {
166
+ background-color: white;
167
+ border-color: lightGray7;
168
+ }
169
+ }
170
+
171
+ &[data-appearance='secondaryLg'] {
172
+ background-color: white;
173
+ color: typoPrimary;
174
+ border-color: blue2;
175
+
176
+ @media (hover: hover) {
177
+ &:hover {
178
+ background-color: blue2;
179
+ color: white;
180
+ border-color: blue2;
181
+ }
182
+ }
183
+
184
+ :active {
185
+ background-color: gray;
186
+ color: white;
187
+ border: none;
188
+ }
189
+
190
+ :disabled {
191
+ background-color: white;
192
+ border-color: bgLightGray1;
193
+ }
194
+ }
195
+
196
+ &[data-appearance='primaryLg'] {
197
+ background-color: blue2;
198
+ color: white;
199
+ border-color: blue2;
200
+
201
+ @media (hover: hover) {
202
+ &:hover {
203
+ background-color: white;
204
+ color: typoPrimary;
205
+ border-color: blue2;
206
+ }
207
+ }
208
+
209
+ :active {
210
+ background-color: gray;
211
+ color: white;
212
+ border: none;
213
+ }
214
+
215
+ :disabled {
216
+ background-color: bgLightGray1;
217
+ border-color: bgLightGray1;
218
+ }
219
+ }
220
+
221
+ &[data-appearance='minimal'] {
222
+ background-color: transparent;
223
+ border: none !important;
224
+ color: blue2;
225
+
226
+ :disabled {
227
+ color: blue2;
228
+ }
229
+ }
230
+
231
+ &[data-appearance='minimalRed'] {
232
+ background-color: transparent;
233
+ border: none !important;
234
+ color: red1;
235
+
236
+ @media (hover: hover) {
237
+ &:hover {
238
+ color: red3;
239
+ svg {
240
+ fill: red3 !important;
241
+ }
242
+ }
243
+ }
244
+
245
+ :disabled,
246
+ :active {
247
+ color: red3;
248
+ svg {
249
+ fill: red3 !important;
250
+ }
251
+ }
252
+ }
253
+
254
+ &[data-sizing='icon'] {
255
+ aspect-ratio: 4 / 3;
256
+ padding: 0.5em 0.875em;
257
+ }
258
+
259
+ &[data-sizing='iconLg'] {
260
+ min-width: 42px;
261
+ min-height: 38px;
262
+ padding: 0.5em 0.875em;
263
+ svg {
264
+ height: 16px;
265
+ }
266
+ }
267
+
268
+ &[data-sizing='normal'] {
269
+ min-width: 7rem;
270
+ padding: 12px 18px;
271
+ min-height: 38px;
272
+ line-height: 14px;
273
+ font-size: 14px;
274
+ }
275
+
276
+ &[data-sizing='large'] {
277
+ min-width: 12rem;
278
+ padding: 0.75em 1.5em;
279
+ min-height: 34px;
280
+ font-size: 12px;
281
+ }
282
+
283
+ &[data-sizing='grid'] {
284
+ min-width: 5rem;
285
+ padding: 0.5em 1.25em;
286
+ font-size: 10px;
287
+ border-radius: 5px;
288
+ }
289
+ `
@@ -0,0 +1,31 @@
1
+ export type SizingValue = 'icon' | 'iconLg' | 'normal' | 'large' | 'grid'
2
+
3
+ export type AppearanceValue =
4
+ | 'primary'
5
+ | 'primaryLight'
6
+ | 'secondary'
7
+ | 'primaryLg'
8
+ | 'secondaryLg'
9
+ | 'minimal'
10
+ | 'minimalRed'
11
+ | 'success'
12
+
13
+ export type Props = React.HTMLProps<HTMLButtonElement> & {
14
+ children?: React.ReactNode
15
+ disabled?: boolean
16
+ appearance?: AppearanceValue
17
+ buttonRef?: any
18
+ sizing?: SizingValue
19
+ isLoading?: boolean
20
+ name?: string
21
+ as?: string | React.ComponentType
22
+ loadingText?: string | JSX.Element
23
+ columnAlign?: boolean
24
+ icon?: string | JSX.Element
25
+ type?: 'button' | 'submit' | 'reset'
26
+ fullWidth?: boolean
27
+ mt?: string | number
28
+ mr?: string | number
29
+ mb?: string | number
30
+ ml?: string | number
31
+ }
@@ -0,0 +1,45 @@
1
+ import { useMemo } from 'react'
2
+ import styled from '@xstyled/styled-components'
3
+ import Icon from './Icon'
4
+ import { IconProps } from './types'
5
+
6
+ type Props = {
7
+ badge: 'warning'
8
+ } & IconProps
9
+
10
+ const Badge = styled(Icon)`
11
+ display: inline-table;
12
+ vertical-align: middle;
13
+ position: absolute;
14
+ top: -10%;
15
+ right: -10%;
16
+ font-size: 60%;
17
+ `
18
+
19
+ const RelativeWrap = styled.div<{ width?: string | number }>`
20
+ position: relative;
21
+ `
22
+
23
+ // TODO expad to accet numerical badges
24
+
25
+ export const BadgeIcon = ({ badge, ...iconProps }: Props): JSX.Element => {
26
+ const badgeProps = useMemo(() => {
27
+ if (badge == 'warning') {
28
+ return {
29
+ icon: 'warningDual',
30
+ fill: 'black',
31
+ secondaryColor: 'yellow2',
32
+ }
33
+ }
34
+ return {} as IconProps
35
+ }, [badge])
36
+
37
+ return (
38
+ <RelativeWrap>
39
+ <Badge {...badgeProps} />
40
+ <Icon {...iconProps} />
41
+ </RelativeWrap>
42
+ )
43
+ }
44
+
45
+ export default BadgeIcon