braid-design-system 31.2.2 → 31.4.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 (36) hide show
  1. package/.changeset/README.md +2 -2
  2. package/.eslintrc +1 -1
  3. package/CHANGELOG.md +42 -0
  4. package/README.md +5 -5
  5. package/codemod/dist/index.js +249 -249
  6. package/codemod/dist/wrapper.js +14655 -16120
  7. package/color-mode/index.ts +10 -6
  8. package/css/index.ts +2 -0
  9. package/css/vars.docs.tsx +39 -2
  10. package/lib/components/Accordion/Accordion.docs.tsx +40 -1
  11. package/lib/components/Accordion/Accordion.gallery.tsx +25 -0
  12. package/lib/components/Accordion/Accordion.screenshots.tsx +17 -1
  13. package/lib/components/Accordion/Accordion.snippets.tsx +16 -0
  14. package/lib/components/Accordion/AccordionItem.tsx +27 -4
  15. package/lib/components/Autosuggest/Autosuggest.tsx +13 -0
  16. package/lib/components/Badge/Badge.playroom.tsx +2 -0
  17. package/lib/components/Badge/Badge.tsx +2 -0
  18. package/lib/components/Button/Button.docs.tsx +2 -2
  19. package/lib/components/MenuItem/MenuItem.docs.tsx +3 -3
  20. package/lib/components/MenuItemCheckbox/MenuItemCheckbox.docs.tsx +2 -2
  21. package/lib/components/MenuItemCheckbox/MenuItemCheckbox.gallery.tsx +1 -1
  22. package/lib/components/MenuItemDivider/MenuItemDivider.docs.tsx +2 -2
  23. package/lib/components/MenuItemDivider/MenuItemDivider.gallery.tsx +1 -1
  24. package/lib/components/MenuRenderer/MenuRenderer.css.ts +0 -5
  25. package/lib/components/MenuRenderer/MenuRenderer.docs.tsx +65 -55
  26. package/lib/components/MenuRenderer/MenuRenderer.gallery.tsx +57 -50
  27. package/lib/components/MenuRenderer/MenuRenderer.screenshots.tsx +64 -0
  28. package/lib/components/MenuRenderer/MenuRenderer.tsx +3 -6
  29. package/lib/components/MonthPicker/MonthPicker.docs.tsx +2 -2
  30. package/lib/components/OverflowMenu/OverflowMenu.docs.tsx +3 -3
  31. package/lib/components/OverflowMenu/OverflowMenu.gallery.tsx +1 -1
  32. package/lib/components/OverflowMenu/OverflowMenu.screenshots.tsx +1 -1
  33. package/lib/components/OverflowMenu/OverflowMenu.tsx +5 -1
  34. package/lib/components/Tabs/Tab.tsx +3 -2
  35. package/package.json +23 -27
  36. package/tsconfig.json +2 -4
@@ -1,9 +1,13 @@
1
1
  import { darkMode } from '../lib/css/atoms/sprinkles.css';
2
- const flag = '_bdsdm=1';
2
+ const flag = '_bdsdm';
3
+ // VALUES
4
+ // 0 = light mode
5
+ // 1 = dark mode
6
+ // 2 = OS Preference
3
7
  // TODO: COLORMODE RELEASE
4
8
  // Finalise import contract
5
- export const __experimentalDarkMode__ = `
6
- <script>
7
- ((l,p)=>{try{r=new RegExp(\`[\?&]\${p}\`);if(r.test(l.search)){history.replaceState(null,null,l.pathname+l.search.replace(r,'').replace(/^&/,'?')+l.hash);if(matchMedia('(prefers-color-scheme:dark)').matches)document.documentElement.classList.add('${darkMode}')}}catch(e){}})(location,'${flag}')
8
- </script>
9
- `;
9
+ export const __experimentalDarkMode__ = [
10
+ '<script>',
11
+ `((l)=>{try{r=/[?&]${flag}=(\\d)/;[,s]=l.search.match(r)||[];if(s){history.replaceState(null,'',l.pathname+l.search.replace(r,'').replace(/^&/,'?')+l.hash);if(s==1||(s==2&&matchMedia('(prefers-color-scheme:dark)').matches))document.documentElement.classList.add('${darkMode}')}}catch(e){}})(location)`,
12
+ '</script>',
13
+ ].join('');
package/css/index.ts CHANGED
@@ -10,6 +10,7 @@ const {
10
10
  grid,
11
11
  space,
12
12
  touchableSize,
13
+ contentWidth,
13
14
  // TODO: COLORMODE RELEASE
14
15
  // Release new backgrounds
15
16
  backgroundColor: { surfaceDark: _, bodyDark: __, ...backgroundColor },
@@ -24,6 +25,7 @@ const vars = {
24
25
  grid,
25
26
  space,
26
27
  touchableSize,
28
+ contentWidth,
27
29
  backgroundColor,
28
30
  foregroundColor,
29
31
  textWeight,
package/css/vars.docs.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import React, { ReactNode } from 'react';
1
+ import React, { ReactNode, useEffect, useRef, useState } from 'react';
2
2
  import { vars } from '.';
3
3
  import {
4
4
  Text,
@@ -13,7 +13,7 @@ import {
13
13
  } from '../lib/components';
14
14
  import { ReactNodeNoStrings } from '../lib/components/private/ReactNodeNoStrings';
15
15
  import Code from '../site/src/App/Code/Code';
16
- import { ThemedExample } from '../site/src/App/ThemeSetting';
16
+ import { ThemedExample, useThemeSettings } from '../site/src/App/ThemeSetting';
17
17
  import { CssDoc } from '../site/src/types';
18
18
  import { VanillaMigrationBanner } from './VanillaMigrationBanner';
19
19
 
@@ -43,6 +43,32 @@ const Row = ({
43
43
  </Columns>
44
44
  );
45
45
 
46
+ const ContentWidthValue = ({ var: varName }: { var: string }) => {
47
+ const [size, setSize] = useState(0);
48
+ const { themeKey } = useThemeSettings();
49
+ const ref = useRef<HTMLDivElement | null>(null);
50
+
51
+ useEffect(() => {
52
+ if (ref.current && themeKey) {
53
+ setSize(ref.current.offsetWidth);
54
+ }
55
+ }, [themeKey]);
56
+
57
+ return (
58
+ <>
59
+ <Box
60
+ component="span"
61
+ position="absolute"
62
+ pointerEvents="none"
63
+ opacity={0}
64
+ ref={ref}
65
+ style={{ width: varName }}
66
+ />
67
+ {size > 0 ? `${size}px` : '&nbsp;'}
68
+ </>
69
+ );
70
+ };
71
+
46
72
  const varDocs: Record<keyof typeof vars, ReactNodeNoStrings> = {
47
73
  grid: (
48
74
  <Row name="grid">
@@ -67,6 +93,17 @@ const varDocs: Record<keyof typeof vars, ReactNodeNoStrings> = {
67
93
  />
68
94
  </Row>
69
95
  ),
96
+ contentWidth: (
97
+ <Stack space="medium" dividers>
98
+ {Object.entries(vars.contentWidth).map(([widthName, widthVar]) => (
99
+ <Row key={widthName} group="contentWidth" name={widthName}>
100
+ <Text>
101
+ <ContentWidthValue var={widthVar} />
102
+ </Text>
103
+ </Row>
104
+ ))}
105
+ </Stack>
106
+ ),
70
107
  space: (
71
108
  <Stack space="medium" dividers>
72
109
  {Object.entries(vars.space).map(([spaceName, spaceVar]) => (
@@ -1,7 +1,15 @@
1
1
  import React from 'react';
2
2
  import { ComponentDocs } from '../../../site/src/types';
3
3
  import source from '../../utils/source.macro';
4
- import { Accordion, AccordionItem, Card, Text, TextLink, Strong } from '../';
4
+ import {
5
+ Accordion,
6
+ AccordionItem,
7
+ Badge,
8
+ Card,
9
+ Text,
10
+ TextLink,
11
+ Strong,
12
+ } from '../';
5
13
  import { Placeholder } from '../../playroom/components';
6
14
  import { validSpaceValues } from './Accordion';
7
15
 
@@ -97,6 +105,37 @@ const docs: ComponentDocs = {
97
105
  </Card>,
98
106
  ),
99
107
  },
108
+ {
109
+ label: 'Badge support',
110
+ description: (
111
+ <Text>
112
+ Add a <TextLink href="/components/Badge">Badge</TextLink> alongside
113
+ the label of the AccordionItem using the <Strong>badge</Strong> prop.
114
+ </Text>
115
+ ),
116
+ Example: ({ id }) =>
117
+ source(
118
+ <Accordion>
119
+ <AccordionItem label="Accordion item 1" id={`${id}_1`}>
120
+ <Placeholder height={80} />
121
+ </AccordionItem>
122
+ <AccordionItem
123
+ label="Accordion item 2"
124
+ id={`${id}_2`}
125
+ badge={
126
+ <Badge tone="promote" weight="strong">
127
+ Badge
128
+ </Badge>
129
+ }
130
+ >
131
+ <Placeholder height={80} />
132
+ </AccordionItem>
133
+ <AccordionItem label="Accordion item 3" id={`${id}_3`}>
134
+ <Placeholder height={80} />
135
+ </AccordionItem>
136
+ </Accordion>,
137
+ ),
138
+ },
100
139
  {
101
140
  label: 'Managing state',
102
141
  description: (
@@ -4,6 +4,7 @@ import source from '../../utils/source.macro';
4
4
  import {
5
5
  Accordion,
6
6
  AccordionItem,
7
+ Badge,
7
8
  Placeholder,
8
9
  } from '../../playroom/components';
9
10
  import { ComponentExample } from '../../../site/src/types';
@@ -43,4 +44,28 @@ export const galleryItems: ComponentExample[] = [
43
44
  </Accordion>,
44
45
  ),
45
46
  },
47
+ {
48
+ label: 'With a Badge',
49
+ Example: () =>
50
+ source(
51
+ <Accordion size="standard" dividers={false}>
52
+ <AccordionItem label="Item 1">
53
+ <Placeholder height={100} />
54
+ </AccordionItem>
55
+ <AccordionItem
56
+ label="Item 2"
57
+ badge={
58
+ <Badge tone="promote" weight="strong">
59
+ Badge
60
+ </Badge>
61
+ }
62
+ >
63
+ <Placeholder height={100} />
64
+ </AccordionItem>
65
+ <AccordionItem label="Item 3">
66
+ <Placeholder height={100} />
67
+ </AccordionItem>
68
+ </Accordion>,
69
+ ),
70
+ },
46
71
  ];
@@ -1,6 +1,6 @@
1
1
  import React, { useState } from 'react';
2
2
  import { ComponentScreenshot } from '../../../site/src/types';
3
- import { AccordionItem, Accordion, Text } from '../../components';
3
+ import { AccordionItem, Accordion, Badge, Text } from '../../components';
4
4
  import { Placeholder } from '../../playroom/components';
5
5
 
6
6
  export const screenshots: ComponentScreenshot = {
@@ -355,5 +355,21 @@ export const screenshots: ComponentScreenshot = {
355
355
  </AccordionItem>
356
356
  ),
357
357
  },
358
+ {
359
+ label: 'AccordionItem with a badge',
360
+ Example: ({ id }) => (
361
+ <AccordionItem
362
+ label="Label"
363
+ id={id}
364
+ badge={
365
+ <Badge tone="promote" weight="strong">
366
+ Badge
367
+ </Badge>
368
+ }
369
+ >
370
+ <Text size="small">Content</Text>
371
+ </AccordionItem>
372
+ ),
373
+ },
358
374
  ],
359
375
  };
@@ -2,6 +2,7 @@ import React from 'react';
2
2
  import {
3
3
  AccordionItem,
4
4
  Accordion,
5
+ Badge,
5
6
  Placeholder,
6
7
  } from '../../playroom/components';
7
8
  import source from '../../utils/source.macro';
@@ -88,4 +89,19 @@ export const snippets: Snippets = [
88
89
  </AccordionItem>,
89
90
  ),
90
91
  },
92
+ {
93
+ name: 'Standalone item with a badge',
94
+ code: source(
95
+ <AccordionItem
96
+ label="Label"
97
+ badge={
98
+ <Badge tone="promote" weight="strong">
99
+ Badge
100
+ </Badge>
101
+ }
102
+ >
103
+ <Placeholder height={100} />
104
+ </AccordionItem>,
105
+ ),
106
+ },
91
107
  ];
@@ -1,9 +1,16 @@
1
- import React, { ReactNode, useContext } from 'react';
1
+ import React, {
2
+ cloneElement,
3
+ ReactElement,
4
+ ReactNode,
5
+ useContext,
6
+ } from 'react';
2
7
  import assert from 'assert';
3
8
  import { Box } from '../Box/Box';
4
9
  import { Text, TextProps } from '../Text/Text';
5
10
  import { Columns } from '../Columns/Columns';
6
11
  import { Column } from '../Column/Column';
12
+ import { Inline } from '../Inline/Inline';
13
+ import { BadgeProps } from '../Badge/Badge';
7
14
  import { IconChevron } from '../icons';
8
15
  import {
9
16
  useDisclosure,
@@ -37,6 +44,7 @@ export type AccordionItemBaseProps = {
37
44
  size?: TextProps['size'];
38
45
  tone?: AccordionContextValue['tone'];
39
46
  data?: DataAttributeMap;
47
+ badge?: ReactElement<BadgeProps>;
40
48
  };
41
49
 
42
50
  export type AccordionItemProps = AccordionItemBaseProps & UseDisclosureProps;
@@ -46,6 +54,7 @@ export const AccordionItem = ({
46
54
  id,
47
55
  label,
48
56
  children,
57
+ badge,
49
58
  size: sizeProp,
50
59
  tone: toneProp,
51
60
  data,
@@ -69,6 +78,17 @@ export const AccordionItem = ({
69
78
  .join(', ')}`,
70
79
  );
71
80
 
81
+ assert(
82
+ // @ts-expect-error
83
+ !badge || badge.type.__isBadge__,
84
+ `AccordionItem badge prop can only be an instance of Badge. e.g. <AccordionItem badge={<Badge>New</Badge>}>`,
85
+ );
86
+
87
+ assert(
88
+ !badge || badge.props.bleedY === undefined,
89
+ "Badge elements cannot set the 'bleedY' prop when passed to an AccordionItem component",
90
+ );
91
+
72
92
  const size = accordionContext?.size ?? sizeProp ?? 'large';
73
93
  const tone = accordionContext?.tone ?? toneProp ?? 'neutral';
74
94
  const weight = 'medium';
@@ -111,9 +131,12 @@ export const AccordionItem = ({
111
131
  <Box position="relative">
112
132
  <Columns space={itemSpace}>
113
133
  <Column>
114
- <Text size={size} weight={weight} tone={tone} component="div">
115
- {label}
116
- </Text>
134
+ <Inline space="small" alignY="center">
135
+ <Text size={size} weight={weight} tone={tone} component="div">
136
+ {label}
137
+ </Text>
138
+ {badge ? cloneElement(badge, { bleedY: true }) : null}
139
+ </Inline>
117
140
  </Column>
118
141
  <Column width="content">
119
142
  <Text
@@ -496,6 +496,19 @@ export const Autosuggest = forwardRef(function <Value>(
496
496
  tablet: false,
497
497
  });
498
498
 
499
+ useEffect(() => {
500
+ if (menuRef.current && isOpen && !isMobile) {
501
+ const { bottom: menuBottom } = menuRef.current.getBoundingClientRect();
502
+ const viewportHeight = document.documentElement.clientHeight;
503
+
504
+ if (menuBottom > viewportHeight) {
505
+ menuRef.current.scrollIntoView(false);
506
+ }
507
+ }
508
+ // re-running this effect if the suggestionCount changes
509
+ // to ensure asychronous updates aren't left out of view.
510
+ }, [isOpen, isMobile, suggestionCount]);
511
+
499
512
  const inputProps = {
500
513
  value: previewValue ? previewValue.text : value.text,
501
514
  type: type === 'search' ? type : 'text',
@@ -7,3 +7,5 @@ export const Badge = ({ tone, ...restProps }: BadgeProps) => (
7
7
  {...restProps}
8
8
  />
9
9
  );
10
+
11
+ Badge.__isBadge__ = true;
@@ -105,3 +105,5 @@ export const Badge = forwardRef<HTMLDivElement, BadgeProps>(
105
105
  );
106
106
 
107
107
  Badge.displayName = 'Badge';
108
+ // @ts-expect-error
109
+ Badge.__isBadge__ = true;
@@ -215,8 +215,8 @@ const docs: ComponentDocs = {
215
215
  description: (
216
216
  <>
217
217
  <Text>
218
- For cases where actions need may need to be de-emphasized, you can
219
- set the button’s <Strong>tone</Strong> to <Strong>neutral.</Strong>
218
+ For cases where actions need to be de-emphasized, the{' '}
219
+ <Strong>tone</Strong> can be set to <Strong>neutral.</Strong>
220
220
  </Text>
221
221
  <Text>
222
222
  This makes the button follow the default text colour, including{' '}
@@ -22,7 +22,7 @@ const docs: ComponentDocs = {
22
22
  subComponents: ['MenuItemLink'],
23
23
  Example: () =>
24
24
  source(
25
- <Box paddingLeft="xxlarge">
25
+ <Box style={{ maxWidth: '100px' }}>
26
26
  <OverflowMenu label="Options">
27
27
  <MenuItem onClick={() => {}}>Button</MenuItem>
28
28
  <MenuItemLink onClick={() => {}} href="#">
@@ -42,7 +42,7 @@ const docs: ComponentDocs = {
42
42
  accessibility: (
43
43
  <Text>
44
44
  Follows the{' '}
45
- <TextLink href="https://www.w3.org/TR/wai-aria-practices-1.1/#menu">
45
+ <TextLink href="https://www.w3.org/TR/wai-aria-practices-1.2/#menu">
46
46
  WAI-ARIA Menu Pattern.
47
47
  </TextLink>
48
48
  </Text>
@@ -89,7 +89,7 @@ const docs: ComponentDocs = {
89
89
  Example: ({ id, getState, toggleState, showToast }) =>
90
90
  source(
91
91
  <>
92
- <Box paddingLeft="xxlarge">
92
+ <Box style={{ maxWidth: '100px' }}>
93
93
  <OverflowMenu label="Options">
94
94
  <MenuItem
95
95
  onClick={() => toggleState('confirm')}
@@ -7,7 +7,7 @@ const docs: ComponentDocs = {
7
7
  category: 'Content',
8
8
  Example: ({ getState, setState }) =>
9
9
  source(
10
- <Box style={{ paddingLeft: 200 }}>
10
+ <Box style={{ maxWidth: '150px' }}>
11
11
  <OverflowMenu label="Checklist">
12
12
  <MenuItemCheckbox
13
13
  checked={getState('checked1')}
@@ -40,7 +40,7 @@ const docs: ComponentDocs = {
40
40
  accessibility: (
41
41
  <Text>
42
42
  Follows the{' '}
43
- <TextLink href="https://www.w3.org/TR/wai-aria-practices-1.1/#menu">
43
+ <TextLink href="https://www.w3.org/TR/wai-aria-practices-1.2/#menu">
44
44
  WAI-ARIA Menu Pattern.
45
45
  </TextLink>
46
46
  </Text>
@@ -12,7 +12,7 @@ export const galleryItems: ComponentExample[] = [
12
12
  {setDefaultState('checked1', false)}
13
13
  {setDefaultState('checked2', false)}
14
14
  {setDefaultState('checked3', false)}
15
- <Box style={{ paddingLeft: 200 }}>
15
+ <Box style={{ maxWidth: '120px' }}>
16
16
  <OverflowMenu label="Checklist">
17
17
  <MenuItemCheckbox
18
18
  checked={getState('checked1')}
@@ -17,7 +17,7 @@ const docs: ComponentDocs = {
17
17
  category: 'Content',
18
18
  Example: ({ getState, setState }) =>
19
19
  source(
20
- <Box style={{ paddingLeft: 200 }}>
20
+ <Box style={{ maxWidth: '150px' }}>
21
21
  <OverflowMenu label="Options">
22
22
  <MenuItem onClick={() => {}}>Button</MenuItem>
23
23
  <MenuItemLink href="#" onClick={() => {}}>
@@ -55,7 +55,7 @@ const docs: ComponentDocs = {
55
55
  accessibility: (
56
56
  <Text>
57
57
  Follows the{' '}
58
- <TextLink href="https://www.w3.org/TR/wai-aria-practices-1.1/#menu">
58
+ <TextLink href="https://www.w3.org/TR/wai-aria-practices-1.2/#menu">
59
59
  WAI-ARIA Menu Pattern.
60
60
  </TextLink>
61
61
  </Text>
@@ -20,7 +20,7 @@ export const galleryItems: ComponentExample[] = [
20
20
  {setDefaultState('checked2', false)}
21
21
  {setDefaultState('checked3', false)}
22
22
 
23
- <Box style={{ paddingLeft: 200 }}>
23
+ <Box style={{ maxWidth: '120px' }}>
24
24
  <OverflowMenu label="Options">
25
25
  <MenuItem onClick={handler}>Button</MenuItem>
26
26
  <MenuItemLink href="#" onClick={handler}>
@@ -2,11 +2,6 @@ import { style } from '@vanilla-extract/css';
2
2
  import { calc } from '@vanilla-extract/css-utils';
3
3
  import { vars } from '../../themes/vars.css';
4
4
 
5
- export const root = style({
6
- padding: '0.05px',
7
- lineHeight: 0,
8
- });
9
-
10
5
  export const backdrop = style({
11
6
  width: '100vw',
12
7
  height: '100vh',
@@ -15,29 +15,32 @@ import {
15
15
  Button,
16
16
  Dialog,
17
17
  IconDelete,
18
+ Inline,
18
19
  } from '..';
19
20
 
20
21
  const docs: ComponentDocs = {
21
22
  category: 'Content',
22
23
  Example: () =>
23
24
  source(
24
- <MenuRenderer
25
- offsetSpace="small"
26
- trigger={(triggerProps, { open }) => (
27
- <Box userSelect="none" cursor="pointer" {...triggerProps}>
28
- <Text>
29
- Menu{' '}
30
- <IconChevron
31
- direction={open ? 'up' : 'down'}
32
- alignY="lowercase"
33
- />
34
- </Text>
35
- </Box>
36
- )}
37
- >
38
- <MenuItem onClick={() => {}}>Button</MenuItem>
39
- <MenuItemLink href="#">Link</MenuItemLink>
40
- </MenuRenderer>,
25
+ <Inline space="none">
26
+ <MenuRenderer
27
+ offsetSpace="small"
28
+ trigger={(triggerProps, { open }) => (
29
+ <Box userSelect="none" cursor="pointer" {...triggerProps}>
30
+ <Text>
31
+ Menu{' '}
32
+ <IconChevron
33
+ direction={open ? 'up' : 'down'}
34
+ alignY="lowercase"
35
+ />
36
+ </Text>
37
+ </Box>
38
+ )}
39
+ >
40
+ <MenuItem onClick={() => {}}>Button</MenuItem>
41
+ <MenuItemLink href="#">Link</MenuItemLink>
42
+ </MenuRenderer>
43
+ </Inline>,
41
44
  ),
42
45
  description: (
43
46
  <Stack space="large">
@@ -53,7 +56,7 @@ const docs: ComponentDocs = {
53
56
  accessibility: (
54
57
  <Text>
55
58
  Follows the{' '}
56
- <TextLink href="https://www.w3.org/TR/wai-aria-practices-1.1/#menu">
59
+ <TextLink href="https://www.w3.org/TR/wai-aria-practices-1.2/#menu">
57
60
  WAI-ARIA Menu Pattern.
58
61
  </TextLink>
59
62
  </Text>
@@ -75,7 +78,7 @@ const docs: ComponentDocs = {
75
78
  ),
76
79
  Example: () =>
77
80
  source(
78
- <Box style={{ paddingLeft: '40px', maxWidth: '220px' }}>
81
+ <Inline space="none">
79
82
  <MenuRenderer
80
83
  align="right"
81
84
  offsetSpace="small"
@@ -94,7 +97,7 @@ const docs: ComponentDocs = {
94
97
  <MenuItem onClick={() => {}}>Button</MenuItem>
95
98
  <MenuItemLink href="#">Link</MenuItemLink>
96
99
  </MenuRenderer>
97
- </Box>,
100
+ </Inline>,
98
101
  ),
99
102
  },
100
103
  {
@@ -111,23 +114,25 @@ const docs: ComponentDocs = {
111
114
  ),
112
115
  Example: () =>
113
116
  source(
114
- <MenuRenderer
115
- offsetSpace={{ mobile: 'xsmall', tablet: 'small' }}
116
- trigger={(triggerProps, { open }) => (
117
- <Box userSelect="none" cursor="pointer" {...triggerProps}>
118
- <Text>
119
- Custom space{' '}
120
- <IconChevron
121
- direction={open ? 'up' : 'down'}
122
- alignY="lowercase"
123
- />
124
- </Text>
125
- </Box>
126
- )}
127
- >
128
- <MenuItem onClick={() => {}}>Button</MenuItem>
129
- <MenuItemLink href="#">Link</MenuItemLink>
130
- </MenuRenderer>,
117
+ <Inline space="none">
118
+ <MenuRenderer
119
+ offsetSpace={{ mobile: 'xsmall', tablet: 'small' }}
120
+ trigger={(triggerProps, { open }) => (
121
+ <Box userSelect="none" cursor="pointer" {...triggerProps}>
122
+ <Text>
123
+ Custom space{' '}
124
+ <IconChevron
125
+ direction={open ? 'up' : 'down'}
126
+ alignY="lowercase"
127
+ />
128
+ </Text>
129
+ </Box>
130
+ )}
131
+ >
132
+ <MenuItem onClick={() => {}}>Button</MenuItem>
133
+ <MenuItemLink href="#">Link</MenuItemLink>
134
+ </MenuRenderer>
135
+ </Inline>,
131
136
  ),
132
137
  },
133
138
  {
@@ -143,24 +148,29 @@ const docs: ComponentDocs = {
143
148
  Example: ({ id, getState, toggleState, showToast }) =>
144
149
  source(
145
150
  <>
146
- <MenuRenderer
147
- offsetSpace="small"
148
- trigger={(triggerProps, { open }) => (
149
- <Box userSelect="none" cursor="pointer" {...triggerProps}>
150
- <Text>
151
- Menu{' '}
152
- <IconChevron
153
- direction={open ? 'up' : 'down'}
154
- alignY="lowercase"
155
- />
156
- </Text>
157
- </Box>
158
- )}
159
- >
160
- <MenuItem onClick={() => toggleState('confirm')} tone="critical">
161
- Delete
162
- </MenuItem>
163
- </MenuRenderer>
151
+ <Inline space="none">
152
+ <MenuRenderer
153
+ offsetSpace="small"
154
+ trigger={(triggerProps, { open }) => (
155
+ <Box userSelect="none" cursor="pointer" {...triggerProps}>
156
+ <Text>
157
+ Menu{' '}
158
+ <IconChevron
159
+ direction={open ? 'up' : 'down'}
160
+ alignY="lowercase"
161
+ />
162
+ </Text>
163
+ </Box>
164
+ )}
165
+ >
166
+ <MenuItem
167
+ onClick={() => toggleState('confirm')}
168
+ tone="critical"
169
+ >
170
+ Delete
171
+ </MenuItem>
172
+ </MenuRenderer>
173
+ </Inline>
164
174
  <Dialog
165
175
  id={id}
166
176
  width="content"