@spothero/ui 15.9.6 → 15.10.6

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": "@spothero/ui",
3
- "version": "15.9.6",
3
+ "version": "15.10.6",
4
4
  "description": "SpotHero's React component UI library.",
5
5
  "main": "v2/index.js",
6
6
  "repository": "https://github.com/spothero/fe-monorepo",
@@ -164,4 +164,4 @@
164
164
  "react-redux": ">=7.0.0",
165
165
  "redux": ">=4.0.0"
166
166
  }
167
- }
167
+ }
@@ -0,0 +1,120 @@
1
+ import {
2
+ Alert as ChakraAlert,
3
+ AlertTitle,
4
+ AlertDescription,
5
+ VStack,
6
+ Flex,
7
+ useStyleConfig,
8
+ } from '@chakra-ui/react';
9
+ import PropTypes from 'prop-types';
10
+ import IconX from '@spothero/icons/times';
11
+ import IconInfo from '@spothero/icons/filled-info-circle';
12
+ import IconExclamation from '@spothero/icons/filled-exclamation-circle';
13
+ import IconCheck from '@spothero/icons/filled-check-circle';
14
+ import Button from 'v2/components/Button/Button';
15
+ import Icon from 'v2/components/Icon/Icon';
16
+
17
+ export const STATUSES = {
18
+ NEUTRAL: 'neutral',
19
+ ERROR: 'error',
20
+ WARNING: 'warning',
21
+ SUCCESS: 'success',
22
+ };
23
+
24
+ const statusIconMapping = {
25
+ [STATUSES.WARNING]: IconExclamation,
26
+ [STATUSES.SUCCESS]: IconCheck,
27
+ [STATUSES.ERROR]: IconExclamation,
28
+ [STATUSES.NEUTRAL]: IconInfo,
29
+ };
30
+
31
+ const Alert = ({
32
+ status,
33
+ title,
34
+ buttonProps,
35
+ buttonText,
36
+ buttonOnBottom,
37
+ showDismiss,
38
+ onDismissClick,
39
+ showIcon,
40
+ description,
41
+ ...props
42
+ }) => {
43
+ const style = useStyleConfig('Alert', {'data-status': status});
44
+ const IconVariant = statusIconMapping[status];
45
+
46
+ return (
47
+ <ChakraAlert data-status={status} {...props}>
48
+ {showIcon ? <Icon sx={style.icon} as={IconVariant} /> : null}
49
+ <VStack spacing={0} alignItems="flex-start">
50
+ {title ? <AlertTitle>{title}</AlertTitle> : null}
51
+ {description ? (
52
+ <AlertDescription>{description}</AlertDescription>
53
+ ) : null}
54
+ {buttonOnBottom && buttonText && buttonProps ? (
55
+ <Button
56
+ sx={style.actionButton}
57
+ variant="tertiary"
58
+ {...buttonProps}
59
+ >
60
+ {buttonText}
61
+ </Button>
62
+ ) : null}
63
+ </VStack>
64
+ <Flex alignItems="center" marginLeft="auto">
65
+ {!buttonOnBottom && buttonText && buttonProps ? (
66
+ <Button
67
+ sx={style.actionButton}
68
+ variant="tertiary"
69
+ {...buttonProps}
70
+ >
71
+ {buttonText}
72
+ </Button>
73
+ ) : null}
74
+ {showDismiss ? (
75
+ <Button sx={style.dismissButton} onClick={onDismissClick}>
76
+ <Icon width={3} height="auto" as={IconX} />
77
+ </Button>
78
+ ) : null}
79
+ </Flex>
80
+ </ChakraAlert>
81
+ );
82
+ };
83
+
84
+ Alert.propTypes = {
85
+ /** Status. One of: success, neutral, warning, or error */
86
+ status: PropTypes.oneOf(['neutral', 'success', 'warning', 'error']),
87
+ /** Title Text. Will not display title if empty */
88
+ title: PropTypes.string,
89
+ /** Props to pass to button (like onClick). Will not display button if this or buttonText empty */
90
+ buttonProps: PropTypes.object,
91
+ /** Text of button. Will not display button if this or buttonProps empty */
92
+ buttonText: PropTypes.string,
93
+ /** Whether action button should be under description (as opposed to on right) */
94
+ buttonOnBottom: PropTypes.bool,
95
+ /** Whether or not to show X dismiss button */
96
+ showDismiss: PropTypes.bool,
97
+ /** Callback when X clicked */
98
+ onDismissClick: PropTypes.func,
99
+ /** Whether or not to show the icon */
100
+ showIcon: PropTypes.bool,
101
+ /** Description text. Will not display description if empty */
102
+ description: PropTypes.string,
103
+ /** Size of the text */
104
+ size: PropTypes.oneOf(['sm', 'md', 'lg']),
105
+ };
106
+
107
+ Alert.defaultProps = {
108
+ status: 'neutral',
109
+ title: null,
110
+ buttonProps: null,
111
+ buttonText: null,
112
+ buttonOnBottom: false,
113
+ showDismiss: false,
114
+ onDismissClick: null,
115
+ showIcon: true,
116
+ description: null,
117
+ size: 'md',
118
+ };
119
+
120
+ export default Alert;
@@ -0,0 +1,50 @@
1
+ import React from 'react';
2
+ import {VStack, Text} from '@chakra-ui/react';
3
+ import {createSelectControl} from 'storybook/utils/create-control';
4
+ import disableArgs from 'storybook/utils/disable-args';
5
+
6
+ import Component from './Alert';
7
+
8
+ export default {
9
+ title: 'v2/Alert',
10
+ component: Component,
11
+ parameters: {
12
+ removeBaseHtmlClass: true,
13
+ },
14
+ };
15
+
16
+ const AlertTemplate = props => (
17
+ <VStack alignItems="flex-start">
18
+ <Text>Status: Success</Text>
19
+ <Component status="success" {...props} />
20
+ <Text>Status: Error</Text>
21
+ <Component status="error" {...props} />
22
+ <Text>Status: Warning</Text>
23
+ <Component status="warning" {...props} />
24
+ <Text>Status: Neutral</Text>
25
+ <Component status="neutral" {...props} />
26
+ </VStack>
27
+ );
28
+
29
+ AlertTemplate.propTypes = {};
30
+
31
+ export const Alert = AlertTemplate.bind({});
32
+
33
+ Alert.argTypes = {
34
+ ...createSelectControl('size', ['sm', 'md', 'lg']),
35
+ ...disableArgs(['buttonProps', 'onDismissClick', 'status']),
36
+ };
37
+
38
+ Alert.args = {
39
+ title: 'Hello',
40
+ buttonOnBottom: false,
41
+ buttonText: 'Action',
42
+ description: 'This is an alert.',
43
+ buttonProps: {
44
+ onClick: () => console.log('Action clicked'),
45
+ },
46
+ showDismiss: true,
47
+ onDismissClick: () => console.log('dismissed'),
48
+ showIcon: true,
49
+ size: 'md',
50
+ };
@@ -0,0 +1 @@
1
+ export {default} from './Alert';
@@ -0,0 +1,166 @@
1
+ import merge from 'lodash/merge';
2
+ import chakraDefaultTheme from '@chakra-ui/theme';
3
+ import {STATUSES} from '../Alert';
4
+
5
+ const baseStyle = {
6
+ container: {
7
+ paddingY: 2,
8
+ borderRadius: 'base',
9
+ },
10
+ actionButton: {
11
+ fontSize: 'sm',
12
+ height: 'fit-content',
13
+ lineHeight: '1.4',
14
+ color: 'primary.600',
15
+ _hover: {
16
+ color: 'primary.700',
17
+ },
18
+ },
19
+ dismissButton: {
20
+ color: 'gray.600',
21
+ borderColor: 'transparent',
22
+ borderWidth: '2px',
23
+ padding: 0,
24
+ width: 10,
25
+ height: 10,
26
+ backgroundColor: 'transparent',
27
+ borderRadius: 'base',
28
+ marginLeft: 2,
29
+ _hover: {
30
+ color: 'gray.700',
31
+ },
32
+ _focus: {
33
+ color: 'gray.700',
34
+ borderColor: 'white',
35
+ boxShadow: 'outline',
36
+ },
37
+ },
38
+ icon: {
39
+ width: 6,
40
+ marginRight: 2,
41
+ height: 'auto',
42
+ },
43
+ description: {
44
+ lineHeight: 1.4,
45
+ },
46
+ title: {
47
+ lineHeight: 1.4,
48
+ },
49
+ };
50
+
51
+ const statusStyles = status => {
52
+ switch (status) {
53
+ case STATUSES.NEUTRAL:
54
+ return {
55
+ container: {
56
+ background: 'gray.light',
57
+ },
58
+ icon: {
59
+ color: 'gray.dark',
60
+ },
61
+ dismissButton: {
62
+ _hover: {
63
+ background: 'gray.200',
64
+ },
65
+ _focus: {
66
+ background: 'gray.200',
67
+ },
68
+ },
69
+ };
70
+ case STATUSES.WARNING:
71
+ return {
72
+ container: {
73
+ background: 'yellow.100',
74
+ },
75
+ icon: {
76
+ color: 'yellow.500',
77
+ },
78
+ dismissButton: {
79
+ _hover: {
80
+ background: 'yellow.200',
81
+ },
82
+ _focus: {
83
+ background: 'yellow.200',
84
+ },
85
+ },
86
+ };
87
+ case STATUSES.ERROR:
88
+ return {
89
+ container: {
90
+ background: 'red.100',
91
+ },
92
+ icon: {
93
+ color: 'red.700',
94
+ },
95
+ dismissButton: {
96
+ _hover: {
97
+ background: 'red.200',
98
+ },
99
+ _focus: {
100
+ background: 'red.200',
101
+ },
102
+ },
103
+ };
104
+ case STATUSES.SUCCESS:
105
+ return {
106
+ container: {
107
+ background: 'green.100',
108
+ },
109
+ icon: {
110
+ color: 'green.700',
111
+ },
112
+ dismissButton: {
113
+ _hover: {
114
+ background: 'green.200',
115
+ },
116
+ _focus: {
117
+ background: 'green.200',
118
+ },
119
+ },
120
+ };
121
+
122
+ default:
123
+ return {};
124
+ }
125
+ };
126
+
127
+ const overrides = {
128
+ baseStyle: props => {
129
+ return merge(
130
+ {
131
+ ...chakraDefaultTheme.components.Alert.baseStyle,
132
+ },
133
+ baseStyle,
134
+ statusStyles(props['data-status'])
135
+ );
136
+ },
137
+ variants: {},
138
+ sizes: {
139
+ sm: {
140
+ title: {
141
+ fontSize: 'xs',
142
+ },
143
+ description: {
144
+ fontSize: 'xs',
145
+ },
146
+ },
147
+ md: {
148
+ title: {
149
+ fontSize: 'sm',
150
+ },
151
+ description: {
152
+ fontSize: 'sm',
153
+ },
154
+ },
155
+ lg: {
156
+ title: {
157
+ fontSize: 'base',
158
+ },
159
+ description: {
160
+ fontSize: 'base',
161
+ },
162
+ },
163
+ },
164
+ };
165
+
166
+ export default {...chakraDefaultTheme.components.Alert, ...overrides};
@@ -5,6 +5,7 @@ const baseStyle = {
5
5
  px: 8,
6
6
  py: 3,
7
7
  fontSize: 'base',
8
+ fontFamily: 'body',
8
9
  lineHeight: 0.875,
9
10
  fontWeight: 'semibold',
10
11
  borderWidth: '1px',
@@ -1,18 +1,20 @@
1
1
  import React, {forwardRef} from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import {Divider as ChakraDivider} from '@chakra-ui/react';
4
- import {baseStyles, colorScheme} from './Divider.styles';
4
+ import {colorScheme} from './Divider.styles';
5
5
 
6
- const Divider = forwardRef(({variant, colorScheme: borderColor, ...props}, ref) => {
7
- return (
8
- <ChakraDivider
9
- {...baseStyles}
10
- {...colorScheme[borderColor]}
11
- variant={variant}
12
- {...props}
13
- ref={ref}
14
- />
15
- )});
6
+ const Divider = forwardRef(
7
+ ({variant, colorScheme: borderColor, ...props}, ref) => {
8
+ return (
9
+ <ChakraDivider
10
+ {...colorScheme[borderColor]}
11
+ variant={variant}
12
+ {...props}
13
+ ref={ref}
14
+ />
15
+ );
16
+ }
17
+ );
16
18
 
17
19
  Divider.propTypes = {
18
20
  /** Color scheme used */
@@ -25,11 +25,10 @@ export default {
25
25
  },
26
26
  };
27
27
 
28
-
29
28
  const Template = props => (
30
29
  <Box>
31
30
  <Text>Over HowdyHowdyHowdy</Text>
32
- <Component {...props}/>
31
+ <Component {...props} />
33
32
  <Text>Under HowdyHowdyHowdy</Text>
34
33
  </Box>
35
34
  );
@@ -3,10 +3,10 @@ import chakraDefaultTheme from '@chakra-ui/theme';
3
3
 
4
4
  export const colorScheme = {
5
5
  low: {
6
- borderColor: 'gray.100'
6
+ borderColor: 'gray.100',
7
7
  },
8
8
  medium: {
9
- borderColor: 'gray.200'
9
+ borderColor: 'gray.200',
10
10
  },
11
11
  };
12
12
 
@@ -5,6 +5,7 @@ export {
5
5
  AccordionButton,
6
6
  default as Accordion,
7
7
  } from './Accordion';
8
+ export {default as Alert} from './Alert';
8
9
  export * from './Button';
9
10
  export * from './Table';
10
11
  export * from './Skeleton';
@@ -11,6 +11,7 @@ export {default as Divider} from './Divider/Divider.styles';
11
11
  export {default as Tabs} from './Tabs/styles';
12
12
  export {default as Select} from './Select/styles';
13
13
  export {default as Checkbox} from './Checkbox/styles';
14
+ export {default as Alert} from './Alert/styles';
14
15
  export {default as Switch} from './Switch/styles';
15
16
  export {default as Popover} from './Popover/styles';
16
17
  export {default as Input} from './Input/styles';