@bitrise/bitkit 12.6.2 → 12.7.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": "12.6.2",
4
+ "version": "12.7.0",
5
5
  "repository": "git@github.com:bitrise-io/bitkit.git",
6
6
  "main": "src/index.ts",
7
7
  "license": "UNLICENSED",
@@ -143,7 +143,7 @@ function useDropdown<T>({
143
143
  optionsRef,
144
144
  defaultValue,
145
145
  dropdownWidth = 'match',
146
- placement,
146
+ placement = 'bottom-start',
147
147
  ref,
148
148
  children,
149
149
  readOnly,
@@ -0,0 +1,12 @@
1
+ import { SystemStyleObject } from '@chakra-ui/styled-system';
2
+
3
+ const SidebarTheme = {
4
+ baseStyle: {
5
+ container: {
6
+ display: 'flex',
7
+ flexDirection: 'column',
8
+ } as SystemStyleObject,
9
+ },
10
+ };
11
+
12
+ export default SidebarTheme;
@@ -0,0 +1,84 @@
1
+ import { createContext, ReactNode, useContext } from 'react';
2
+ import { BoxProps, createStylesContext, SpaceProps, useMultiStyleConfig } from '@chakra-ui/react';
3
+ import Box from '../Box/Box';
4
+ import Text from '../Text/Text';
5
+ import Divider from '../Divider/Divider';
6
+ import Icon from '../Icon/Icon';
7
+
8
+ const [SidebarContext, useSidebarStyle] = createStylesContext('Sidebar');
9
+
10
+ const SidebarContainer = ({ children }: { children: ReactNode }) => {
11
+ const { container } = useSidebarStyle();
12
+ return <Box sx={container}>{children}</Box>;
13
+ };
14
+
15
+ const SidebarHeader = ({ title }: { title?: string }) => {
16
+ if (!title) {
17
+ return <Box h="24" w="100%" />;
18
+ }
19
+ return (
20
+ <Text lineHeight="var(--sizes-40)" size={['6', '4']} fontWeight="bold" px="32" py="16">
21
+ {title}
22
+ </Text>
23
+ );
24
+ };
25
+
26
+ const FooterContext = createContext(false);
27
+
28
+ const SidebarDivider = () => {
29
+ const isInFooter = useContext(FooterContext);
30
+ const margins: SpaceProps = isInFooter ? { marginTop: '12' } : { mx: '32', my: '24' };
31
+ return <Divider {...margins} w="auto" />;
32
+ };
33
+
34
+ const SidebarGroupHeader = ({ label }: { label: string }) => {
35
+ return (
36
+ <Box marginTop="24" marginBottom="12" display="flex" mx="32" alignItems="center" gap="16">
37
+ <Text size="1" fontWeight="bold" textColor="neutral.60">
38
+ {label}
39
+ </Text>
40
+ <Divider w="auto" flexGrow="1" />
41
+ </Box>
42
+ );
43
+ };
44
+
45
+ const SidebarFooter = ({ children }: { children: ReactNode }) => {
46
+ const { container } = useSidebarStyle();
47
+ return (
48
+ <FooterContext.Provider value>
49
+ <Box marginTop="auto" sx={container}>
50
+ {children}
51
+ </Box>
52
+ </FooterContext.Provider>
53
+ );
54
+ };
55
+
56
+ export type SidebarProps = { children: ReactNode; title?: string } & Omit<
57
+ BoxProps,
58
+ 'display' | 'd' | 'flexDirection' | 'flexDir' | 'as'
59
+ >;
60
+ const Sidebar = ({ children, title, ...boxProps }: SidebarProps) => {
61
+ const theme = useMultiStyleConfig('Sidebar');
62
+ return (
63
+ <SidebarContext value={theme}>
64
+ <Box as="nav" display="flex" flexDirection="column" {...boxProps}>
65
+ <SidebarHeader title={title} />
66
+ {children}
67
+ </Box>
68
+ </SidebarContext>
69
+ );
70
+ };
71
+
72
+ const SidebarButton = ({ onClick, title }: Pick<BoxProps, 'onClick'> & { title: string }) => {
73
+ return (
74
+ <Box as="button" onClick={onClick} h="56" display="flex" alignItems="center" gap="4" paddingLeft="16">
75
+ <Icon size="24" name="ChevronLeft" />
76
+ <Text as="span" lineHeight="var(--space-24)">
77
+ {title}
78
+ </Text>
79
+ </Box>
80
+ );
81
+ };
82
+
83
+ export default Sidebar;
84
+ export { SidebarDivider, SidebarGroupHeader, SidebarContainer, SidebarFooter, SidebarButton };
@@ -0,0 +1,53 @@
1
+ import { createMultiStyleConfigHelpers } from '@chakra-ui/styled-system';
2
+
3
+ const itemHelpers = createMultiStyleConfigHelpers(['cell', 'link']);
4
+
5
+ const SidebarItemTheme = itemHelpers.defineMultiStyleConfig({
6
+ baseStyle: {
7
+ link: {
8
+ userSelect: 'none',
9
+ color: 'purple.10',
10
+ display: 'flex',
11
+ flexShrink: '0',
12
+ alignItems: 'center',
13
+ _hover: {
14
+ bg: 'neutral.95',
15
+ },
16
+ _active: {
17
+ bg: 'neutral.93',
18
+ },
19
+ },
20
+ icon: {
21
+ marginLeft: '32',
22
+ marginRight: '16',
23
+ },
24
+ },
25
+ variants: {
26
+ selected: {
27
+ link: {
28
+ fontWeight: 'demiBold',
29
+ bg: 'purple.95',
30
+ _hover: {
31
+ bg: 'purple.93',
32
+ },
33
+ _active: {
34
+ bg: 'purple.93',
35
+ },
36
+ '&::after': {
37
+ display: 'block',
38
+ content: "''",
39
+ width: '2px',
40
+ height: '100%',
41
+ right: '0px',
42
+ position: 'absolute',
43
+ top: 'calc(50% - var(--sizes-48)/2)',
44
+ background: 'purple.50',
45
+ borderRadius: '0px 2px 2px 0px',
46
+ transform: 'matrix(-1, 0, 0, 1, 0, 0)',
47
+ },
48
+ },
49
+ },
50
+ },
51
+ });
52
+
53
+ export default SidebarItemTheme;
@@ -0,0 +1,61 @@
1
+ import { ReactNode } from 'react';
2
+ import { chakra, ChakraProps, createStylesContext, useMultiStyleConfig } from '@chakra-ui/react';
3
+ import { DateTime } from 'luxon';
4
+ import Text from '../Text/Text';
5
+ import Icon, { TypeIconName } from '../Icon/Icon';
6
+
7
+ type SidebarItemProps = {
8
+ children: ReactNode;
9
+ selected?: boolean;
10
+ onClick?: () => void;
11
+ href?: string;
12
+ };
13
+
14
+ const [SidebarItemStyleProvider, useSidebarItemStyle] = createStylesContext('SidebarItem');
15
+
16
+ const SidebarItem = ({ children, selected, href, onClick }: SidebarItemProps) => {
17
+ const style = useMultiStyleConfig('SidebarItem', { variant: selected ? 'selected' : undefined });
18
+ const shared = {
19
+ onClick,
20
+ position: 'relative',
21
+ href,
22
+ children: <SidebarItemStyleProvider value={style}>{children}</SidebarItemStyleProvider>,
23
+ sx: style.link,
24
+ height: '48',
25
+ } as ChakraProps;
26
+ if (onClick) {
27
+ return <chakra.button {...shared} />;
28
+ }
29
+ return <chakra.a {...shared} />;
30
+ };
31
+
32
+ const SidebarItemIcon = ({ name }: { name: TypeIconName }) => {
33
+ const { icon } = useSidebarItemStyle();
34
+ return <Icon sx={icon} name={name} size="24" />;
35
+ };
36
+
37
+ const SidebarItemLabel = ({ children }: { children: ReactNode }) => (
38
+ <Text as="span" textAlign="left" flexGrow="1">
39
+ {children}
40
+ </Text>
41
+ );
42
+ const SidebarItemDateExtra = ({ date }: { date: Date | DateTime }) => {
43
+ const dateTime = DateTime.isDateTime(date) ? date : DateTime.fromJSDate(date);
44
+ return (
45
+ <Text
46
+ as="time"
47
+ minWidth="5rem"
48
+ dateTime={dateTime.toFormat('yyyy-LL-dd')}
49
+ textAlign="left"
50
+ whiteSpace="nowrap"
51
+ fontWeight="normal"
52
+ textColor="text.secondary"
53
+ paddingEnd="24"
54
+ >
55
+ {dateTime.toFormat('LLL d')}
56
+ </Text>
57
+ );
58
+ };
59
+
60
+ export default SidebarItem;
61
+ export { SidebarItemIcon, SidebarItemLabel, SidebarItemDateExtra };
package/src/index.ts CHANGED
@@ -243,3 +243,15 @@ export { default as SearchInput } from './Components/SearchInput/SearchInput';
243
243
 
244
244
  export type { CloseButtonProps } from './Components/CloseButton/CloseButton';
245
245
  export { default as CloseButton } from './Components/CloseButton/CloseButton';
246
+
247
+ export type { SidebarProps } from './Components/Sidebar/Sidebar';
248
+ export { default as Sidebar } from './Components/Sidebar/Sidebar';
249
+ export {
250
+ SidebarDivider,
251
+ SidebarGroupHeader,
252
+ SidebarContainer,
253
+ SidebarFooter,
254
+ SidebarButton,
255
+ } from './Components/Sidebar/Sidebar';
256
+ export { default as SidebarItem } from './Components/Sidebar/SidebarItem';
257
+ export { SidebarItemIcon, SidebarItemLabel, SidebarItemDateExtra } from './Components/Sidebar/SidebarItem';
package/src/theme.ts CHANGED
@@ -30,6 +30,8 @@ import DatePickerDay from './Components/DatePicker/DatePickerDay.theme';
30
30
  import NumberInput from './Components/NumberInput/NumberInput.theme';
31
31
  import Skeleton from './Components/Skeleton/Skeleton.theme';
32
32
  import ProgressBar from './Components/ProgressBar/ProgressBar.theme';
33
+ import Sidebar from './Components/Sidebar/Sidebar.theme';
34
+ import SidebarItem from './Components/Sidebar/SidebarItem.theme';
33
35
 
34
36
  import breakpoints from './Foundations/Breakpoints/Breakpoints';
35
37
  import colors from './Foundations/Colors/Colors';
@@ -106,6 +108,8 @@ const theme = {
106
108
  DatePickerDay,
107
109
  NumberInput,
108
110
  Skeleton,
111
+ Sidebar,
112
+ SidebarItem,
109
113
  Progress: ProgressBar,
110
114
  },
111
115
  };