@bitrise/bitkit 10.16.4 → 10.17.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bitrise/bitkit",
3
3
  "description": "Bitrise React component library",
4
- "version": "10.16.4",
4
+ "version": "10.17.1",
5
5
  "repository": "git@github.com:bitrise-io/bitkit.git",
6
6
  "main": "src/index.ts",
7
7
  "license": "UNLICENSED",
@@ -1,13 +1,13 @@
1
1
  import { ComponentMeta, ComponentStoryFn } from '@storybook/react';
2
2
  import { action } from '@storybook/addon-actions';
3
- import Notification, { NotificationText, NotificationTitle } from './Notification';
3
+ import Link from '../Link/Link';
4
+ import Notification from './Notification';
4
5
 
5
6
  export default {
6
7
  title: 'Components/Notification',
7
8
  component: Notification,
8
9
  argTypes: {
9
- title: { type: 'string', defaultValue: 'title' },
10
- description: { type: 'string', defaultValue: 'description' },
10
+ children: { type: 'string', defaultValue: 'text' },
11
11
  action: {
12
12
  control: 'inline-radio',
13
13
  options: ['unset', 'link', 'action'],
@@ -31,12 +31,7 @@ export default {
31
31
  },
32
32
  } as ComponentMeta<typeof Notification>;
33
33
 
34
- const Template: ComponentStoryFn<typeof Notification> = ({ title, description, ...props }) => (
35
- <Notification {...props}>
36
- <NotificationTitle>{title}</NotificationTitle>
37
- <NotificationText>{description}</NotificationText>
38
- </Notification>
39
- );
34
+ const Template: ComponentStoryFn<typeof Notification> = (props) => <Notification {...props} />;
40
35
 
41
36
  export const Default: ComponentStoryFn<typeof Notification> = (props) => <Template {...props} />;
42
37
  Default.args = {
@@ -64,3 +59,26 @@ WithAction.args = {
64
59
  label: 'Upgrade',
65
60
  },
66
61
  };
62
+
63
+ export const WithActionAfterContent: ComponentStoryFn<typeof Notification> = (props) => <Template {...props} />;
64
+ WithActionAfterContent.storyName = 'With action after content';
65
+ WithActionAfterContent.args = {
66
+ action: {
67
+ label: 'Upgrade',
68
+ placement: 'after-content',
69
+ },
70
+ };
71
+
72
+ export const WithLink: ComponentStoryFn<typeof Notification> = (props) => <Template {...props} />;
73
+ WithLink.storyName = 'With link';
74
+ WithLink.args = {
75
+ children: (
76
+ <>
77
+ Unable to send build status back to your git host. Please check{' '}
78
+ <Link href="#/" isUnderlined>
79
+ our guide
80
+ </Link>
81
+ .
82
+ </>
83
+ ),
84
+ };
@@ -1,13 +1,5 @@
1
1
  import { cloneElement, createContext, ReactElement, useContext, useMemo } from 'react';
2
- import {
3
- Alert as ChakraAlert,
4
- AlertTitle as NotificationTitle,
5
- AlertProps,
6
- forwardRef,
7
- AlertDescription as NotificationText,
8
- Spinner,
9
- chakra,
10
- } from '@chakra-ui/react';
2
+ import { Alert as ChakraAlert, AlertProps, forwardRef, Spinner } from '@chakra-ui/react';
11
3
 
12
4
  import { ColorScheme } from '../../Foundations/Colors/Colors';
13
5
  import Box from '../Box/Box';
@@ -25,9 +17,9 @@ const STATUSES: Record<NotificationStatus, { colorScheme: ColorScheme; defaultIc
25
17
  progress: {
26
18
  colorScheme: 'purple',
27
19
  defaultIcon: (
28
- <chakra.span w="24" h="24" p="2">
29
- <Spinner w="100" h="100" />
30
- </chakra.span>
20
+ <Box width={24} height={24} padding={2}>
21
+ <Spinner width={20} height={20} />
22
+ </Box>
31
23
  ),
32
24
  },
33
25
  } as const;
@@ -36,6 +28,7 @@ export type ActionProps = {
36
28
  label: string;
37
29
  href?: string;
38
30
  onClick?: () => void;
31
+ placement?: 'end' | 'after-content';
39
32
  } & Omit<ColorButtonProps, 'as' | 'onClick' | 'colorScheme'>;
40
33
  export interface NotificationProps extends Omit<AlertProps, 'status' | 'colorScheme' | 'onClose'> {
41
34
  status: NotificationStatus;
@@ -70,6 +63,7 @@ const Notification = forwardRef<NotificationProps, 'div'>((props, ref) => {
70
63
  const { colorScheme, defaultIcon } = STATUSES[status];
71
64
  const icon = iconName ? <Icon name={iconName} /> : defaultIcon;
72
65
  let actionButton;
66
+ const actionPlacement = action?.placement ?? 'end';
73
67
  if (action) {
74
68
  actionButton = <NotificationAction marginRight="12" {...action} alignSelf="center" />;
75
69
  }
@@ -81,12 +75,18 @@ const Notification = forwardRef<NotificationProps, 'div'>((props, ref) => {
81
75
  <ChakraAlert ref={ref} {...rest} colorScheme={colorScheme}>
82
76
  <ActionContext.Provider value={actionContext}>
83
77
  {showIcon && cloneElement(icon, { flexShrink: 0, marginTop })}
84
- <Box wordBreak="break-word" display="flex" flexDirection="column" flexGrow={1} marginTop={marginTop}>
78
+ <Box wordBreak="break-word" flexGrow={actionPlacement === 'end' ? 1 : undefined} marginTop={marginTop}>
85
79
  {children}
86
80
  </Box>
87
81
  {actionButton}
88
82
  {onClose && (
89
- <CloseButton flexShrink={0} colorScheme={colorScheme} onClick={onClose}>
83
+ <CloseButton
84
+ flexShrink={0}
85
+ marginLeft="auto"
86
+ marginTop={marginTop}
87
+ colorScheme={colorScheme}
88
+ onClick={onClose}
89
+ >
90
90
  <Icon name="CloseSmall" />
91
91
  </CloseButton>
92
92
  )}
@@ -95,5 +95,5 @@ const Notification = forwardRef<NotificationProps, 'div'>((props, ref) => {
95
95
  );
96
96
  });
97
97
 
98
- export { NotificationTitle, NotificationText, NotificationAction };
98
+ export { NotificationAction };
99
99
  export default Notification;
@@ -1,4 +1,4 @@
1
- import React, { isValidElement, ReactElement, useEffect, useState } from 'react';
1
+ import React, { isValidElement, ReactElement, useState } from 'react';
2
2
  import { Tabs as ChakraTabs, TabsProps as ChakraTabsProps, forwardRef } from '@chakra-ui/react';
3
3
  import { useHistory } from '../../hooks';
4
4
 
@@ -15,6 +15,25 @@ const getTabIds = (props: TabsProps): string[] => {
15
15
  return tabs.filter((item) => isValidElement(item)).map((item) => item.props.id);
16
16
  };
17
17
 
18
+ const getTabIndexFromSearchParams = (tabIds: string[], defaultIndex?: number) => {
19
+ if (typeof window === 'undefined') {
20
+ return undefined;
21
+ }
22
+
23
+ const searchParams = new URLSearchParams(window.location.search);
24
+ const tabName = searchParams.get('tab');
25
+ if (!tabName) {
26
+ return undefined;
27
+ }
28
+
29
+ const index = tabIds.indexOf(tabName);
30
+ if (index === -1) {
31
+ return defaultIndex;
32
+ }
33
+
34
+ return index;
35
+ };
36
+
18
37
  /**
19
38
  * An accessible tabs component that provides keyboard interactions and ARIA attributes described in the WAI-ARIA Tabs Design Pattern.
20
39
  */
@@ -23,21 +42,16 @@ const Tabs = forwardRef<TabsProps, 'div'>((props, ref) => {
23
42
  const tabIds = getTabIds(props);
24
43
  const defaultIndex = tabIds.indexOf(defaultTab) > -1 ? tabIds.indexOf(defaultTab) : 0;
25
44
 
26
- const { searchParams, replace } = useHistory();
27
- const [actualIndex, setActualIndex] = useState(defaultIndex);
28
-
29
- useEffect(() => {
30
- if (withHistory && searchParams.get('tab')) {
31
- const tabName = searchParams.get('tab') || '';
32
- const index = tabIds.indexOf(tabName) > -1 ? tabIds.indexOf(tabName) : defaultIndex;
33
- setActualIndex(index);
34
- }
35
- }, []);
45
+ const { replace } = useHistory();
46
+ const [actualIndex, setActualIndex] = useState(
47
+ withHistory ? getTabIndexFromSearchParams(tabIds, defaultIndex) : defaultIndex,
48
+ );
36
49
 
37
50
  const onTabChange = (index: number) => {
38
51
  const tabId = tabIds[index];
39
52
  setActualIndex(index);
40
53
  if (withHistory) {
54
+ const searchParams = new URLSearchParams(window.location.search);
41
55
  if (tabId) {
42
56
  searchParams.set('tab', tabId);
43
57
  } else {
@@ -1,12 +1,7 @@
1
- import { useToast as useChakraToast, UseToastOptions } from '@chakra-ui/react';
1
+ import { useToast as useChakraToast, UseToastOptions, AlertTitle, AlertDescription } from '@chakra-ui/react';
2
2
  import { DateTime } from 'luxon';
3
- import Notification, {
4
- ActionProps,
5
- NotificationAction,
6
- NotificationProps,
7
- NotificationText,
8
- NotificationTitle,
9
- } from '../Notification/Notification';
3
+ import Box from '../Box/Box';
4
+ import Notification, { ActionProps, NotificationAction, NotificationProps } from '../Notification/Notification';
10
5
 
11
6
  export interface ToastOptions {
12
7
  title: string;
@@ -37,10 +32,12 @@ const useToast = () => {
37
32
  status={opts.status}
38
33
  onClose={opts.isClosable ? onClose : undefined}
39
34
  >
40
- <NotificationTitle>{opts.title}</NotificationTitle>
41
- <NotificationText>{opts.description}</NotificationText>
42
- {!opts.action && timestamp && <NotificationText marginTop="8">{timestamp}</NotificationText>}
43
- {opts.action && <NotificationAction alignSelf="start" marginTop="8" marginBottom="4" {...opts.action} />}
35
+ <Box display="flex" flexDirection="column">
36
+ <AlertTitle>{opts.title}</AlertTitle>
37
+ <AlertDescription>{opts.description}</AlertDescription>
38
+ {!opts.action && timestamp && <AlertDescription marginTop="8">{timestamp}</AlertDescription>}
39
+ {opts.action && <NotificationAction alignSelf="start" marginTop="8" marginBottom="4" {...opts.action} />}
40
+ </Box>
44
41
  </Notification>
45
42
  ),
46
43
  });