@bitrise/bitkit 13.120.0 → 13.122.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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bitrise/bitkit",
3
3
  "description": "Bitrise React component library",
4
- "version": "13.120.0",
4
+ "version": "13.122.0",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+ssh://git@github.com/bitrise-io/bitkit.git"
@@ -13,6 +13,9 @@ const ChipInput = defineStyleConfig({
13
13
  padding: '0.6875rem',
14
14
  transition: '200ms',
15
15
  width: '100%',
16
+ _readOnly: {
17
+ background: 'background.disabled',
18
+ },
16
19
  },
17
20
  });
18
21
 
@@ -25,12 +25,14 @@ export interface TagsInputProps extends UsedFormControlProps {
25
25
  invalidValues?: string[];
26
26
  errorText?: ReactNode;
27
27
  helperText?: ReactNode;
28
+ isReadOnly?: boolean;
28
29
  }
29
30
 
30
31
  const TagsInput = ({
31
32
  errorText,
32
33
  helperText,
33
34
  invalidValues = [],
35
+ isReadOnly,
34
36
  label,
35
37
  maxCount,
36
38
  onNewValues,
@@ -74,7 +76,7 @@ const TagsInput = ({
74
76
  const isInvalid = rest.isInvalid || (maxCount && value.length > maxCount) || Boolean(errorText);
75
77
  const id = useId();
76
78
  return (
77
- <FormControl {...rest} isInvalid={isInvalid}>
79
+ <FormControl {...rest} isInvalid={isInvalid} isReadOnly={isReadOnly}>
78
80
  <Box alignItems="center" display={label || maxCount ? 'flex' : 'none'} gap="4" marginBlockEnd="4">
79
81
  {label && (
80
82
  <FormLabel
@@ -110,12 +112,13 @@ const TagsInput = ({
110
112
  gap="4"
111
113
  paddingRight={isInvalid ? '42px' : undefined}
112
114
  position="relative"
115
+ data-readonly={isReadOnly}
113
116
  >
114
117
  {value.map((item, idx) => (
115
118
  <Tag
116
119
  key={item}
117
120
  colorScheme={invalidValues.includes(item) || (maxCount && idx > maxCount - 1) ? 'red' : undefined}
118
- onClose={() => removeItem(item)}
121
+ onClose={isReadOnly ? undefined : () => removeItem(item)}
119
122
  size="sm"
120
123
  >
121
124
  {item}
@@ -130,6 +133,10 @@ const TagsInput = ({
130
133
  onKeyDown={keydownHandler}
131
134
  onPaste={pasteEventHandler}
132
135
  placeholder={value.length === 0 ? placeholder : undefined}
136
+ readOnly={isReadOnly}
137
+ _readOnly={{
138
+ backgroundColor: 'background/disabled',
139
+ }}
133
140
  />
134
141
  {isInvalid && <Icon color="icon.negative" name="ErrorCircleFilled" position="absolute" right="16" />}
135
142
  </Box>
@@ -10,7 +10,10 @@ import ProgressSpinner from '../ProgressSpinner/ProgressSpinner';
10
10
 
11
11
  type NotificationStatus = 'info' | 'error' | 'success' | 'warning' | 'progress';
12
12
 
13
- const STATUSES: Record<NotificationStatus, { colorScheme: ColorScheme; defaultIcon: ReactElement }> = {
13
+ export const NOTIFICATION_STATUSES: Record<
14
+ NotificationStatus,
15
+ { colorScheme: ColorScheme; defaultIcon: ReactElement }
16
+ > = {
14
17
  error: { colorScheme: 'red', defaultIcon: <Icon name="ErrorCircleFilled" /> },
15
18
  info: { colorScheme: 'blue', defaultIcon: <Icon name="InfoCircle" /> },
16
19
  progress: {
@@ -62,7 +65,7 @@ const NotificationAction = ({ href, label, ...rest }: ActionProps) => {
62
65
 
63
66
  const Notification = forwardRef<NotificationProps, 'div'>((props, ref) => {
64
67
  const { action, children, iconName, onClose, showIcon = true, status, ...rest } = props;
65
- const { colorScheme, defaultIcon } = STATUSES[status];
68
+ const { colorScheme, defaultIcon } = NOTIFICATION_STATUSES[status];
66
69
  const icon = iconName ? <Icon name={iconName} /> : defaultIcon;
67
70
  let actionButton;
68
71
  const actionPlacement = action?.placement ?? 'end';
@@ -1,3 +1,4 @@
1
+ import NotificationCard from '../Patterns/NotificationCard/NotificationCard.theme';
1
2
  import Alert from './Alert/Alert.theme';
2
3
  import Accordion from './Accordion/Accordion.theme';
3
4
  import Avatar from './Avatar/Avatar.theme';
@@ -81,6 +82,7 @@ const components = {
81
82
  Menu,
82
83
  Modal: Dialog,
83
84
  Note,
85
+ NotificationCard,
84
86
  NumberInput,
85
87
  Popover,
86
88
  Progress: ProgressBar,
@@ -0,0 +1,75 @@
1
+ import { createMultiStyleConfigHelpers } from '@chakra-ui/styled-system';
2
+ import { ColorScheme } from 'src/types/bitkit';
3
+
4
+ const { defineMultiStyleConfig } = createMultiStyleConfigHelpers(['card', 'icon']);
5
+
6
+ const colorSchemeToStatus = (colorScheme: ColorScheme) => {
7
+ switch (colorScheme) {
8
+ case 'blue':
9
+ return 'info';
10
+ case 'green':
11
+ return 'success';
12
+ case 'yellow':
13
+ return 'warning';
14
+ case 'red':
15
+ return 'critical';
16
+ case 'purple':
17
+ return 'progress';
18
+ }
19
+ };
20
+
21
+ const getIconColor = ({ colorScheme }: { colorScheme: ColorScheme }) => {
22
+ switch (colorScheme) {
23
+ case 'blue':
24
+ return 'sys/info/base';
25
+ case 'green':
26
+ return 'icon/positive';
27
+ case 'yellow':
28
+ return 'sys/warning/base';
29
+ case 'red':
30
+ return 'icon/negative';
31
+ case 'purple':
32
+ return 'purple.40';
33
+ }
34
+ };
35
+
36
+ const getBackgroundColor = ({ colorScheme }: { colorScheme: ColorScheme }) => {
37
+ return `status/${colorSchemeToStatus(colorScheme)}/bg`;
38
+ };
39
+
40
+ const getBorderColor = ({ colorScheme }: { colorScheme: ColorScheme }) => {
41
+ return `status/${colorSchemeToStatus(colorScheme)}/border`;
42
+ };
43
+
44
+ const getTextColor = ({ colorScheme }: { colorScheme: ColorScheme }) => {
45
+ switch (colorScheme) {
46
+ case 'blue':
47
+ return 'text/primary';
48
+ case 'green':
49
+ return 'text/positive';
50
+ case 'yellow':
51
+ return 'text/primary';
52
+ case 'red':
53
+ return 'text/negative';
54
+ case 'purple':
55
+ return 'text/secondary';
56
+ }
57
+ };
58
+
59
+ const NotificationTheme = defineMultiStyleConfig({
60
+ baseStyle: ({ colorScheme }: { colorScheme: string }) => {
61
+ const cs = colorScheme as ColorScheme;
62
+ return {
63
+ card: {
64
+ bg: getBackgroundColor({ colorScheme: cs }),
65
+ borderColor: getBorderColor({ colorScheme: cs }),
66
+ color: getTextColor({ colorScheme: cs }),
67
+ },
68
+ icon: {
69
+ color: getIconColor({ colorScheme: cs }),
70
+ },
71
+ };
72
+ },
73
+ });
74
+
75
+ export default NotificationTheme;
@@ -0,0 +1,78 @@
1
+ import { BoxProps, CardProps, TextProps, useMultiStyleConfig, useStyleConfig } from '@chakra-ui/react';
2
+ import { NOTIFICATION_STATUSES, NotificationProps } from '../../Components/Notification/Notification';
3
+ import Card from '../../Components/Card/Card';
4
+ import Box from '../../Components/Box/Box';
5
+ import Text from '../../Components/Text/Text';
6
+ import Button from '../../Components/Button/Button';
7
+
8
+ export type ActionProps = {
9
+ href?: string;
10
+ label: string;
11
+ onClick?: () => void;
12
+ target?: string;
13
+ };
14
+
15
+ export type NotificationCardProps = {
16
+ action?: ActionProps;
17
+ message: string;
18
+ status: NotificationProps['status'];
19
+ title?: string;
20
+ };
21
+
22
+ const NotificationCardAction = ({ href, label, ...rest }: ActionProps) => {
23
+ return (
24
+ <Button as={(href ? 'a' : 'button') as any} variant="tertiary" size="md" href={href} {...rest}>
25
+ {label}
26
+ </Button>
27
+ );
28
+ };
29
+
30
+ const NotificationCard = ({ action, status, message: description, title }: NotificationCardProps) => {
31
+ const { colorScheme, defaultIcon } = NOTIFICATION_STATUSES[status || 'info'];
32
+
33
+ const style = useMultiStyleConfig('NotificationCard', { colorScheme });
34
+ const { borderColor, bg, color } = style.card;
35
+ const { borderRadius } = useStyleConfig('Card', { colorScheme });
36
+
37
+ let actionButton;
38
+ if (action) {
39
+ actionButton = <NotificationCardAction {...action} />;
40
+ }
41
+
42
+ return (
43
+ <Card borderColor={borderColor as BoxProps['borderColor']} display="flex" flexDirection="row" variant="outline">
44
+ <Box
45
+ alignItems="stretch"
46
+ borderLeftRadius={borderRadius as CardProps['borderRadius']}
47
+ bg={bg as BoxProps['backgroundColor']}
48
+ display="flex"
49
+ paddingInline="8"
50
+ paddingBlock="12"
51
+ sx={style.icon}
52
+ >
53
+ {defaultIcon}
54
+ </Box>
55
+ <Box
56
+ flex="1"
57
+ padding="12"
58
+ paddingInlineEnd="16"
59
+ display="flex"
60
+ gap="12"
61
+ justifyContent="space-between"
62
+ alignItems="center"
63
+ >
64
+ <Box display="flex" flexDir="column">
65
+ <Text color={color as TextProps['color']} textStyle="body/lg/semibold">
66
+ {title}
67
+ </Text>
68
+ <Text textStyle="body/md/regular" color={title ? '' : (color as TextProps['color'])}>
69
+ {description}
70
+ </Text>
71
+ </Box>
72
+ {actionButton}
73
+ </Box>
74
+ </Card>
75
+ );
76
+ };
77
+
78
+ export default NotificationCard;
package/src/index.ts CHANGED
@@ -157,6 +157,9 @@ export {
157
157
  export type { NotificationProps } from './Components/Notification/Notification';
158
158
  export { default as Notification } from './Components/Notification/Notification';
159
159
 
160
+ export type { NotificationCardProps } from './Patterns/NotificationCard/NotificationCard';
161
+ export { default as NotificationCard } from './Patterns/NotificationCard/NotificationCard';
162
+
160
163
  export type { AccordionProps } from './Components/Accordion/Accordion';
161
164
  export { default as Accordion } from './Components/Accordion/Accordion';
162
165