Skip to content

Commit 2c6e080

Browse files
author
Kurt Doherty
authored
feat: add code connect for BottomBar, ButtonGroup, ChipSelect and CompactSelectNative (#783)
1 parent a05a3a2 commit 2c6e080

18 files changed

Lines changed: 259 additions & 106 deletions

figma.config.json

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"codeConnect": {
33
"include": [
4-
"src/core/{accordion,avatar,badge,breadcrumbs,button,chip,chip-group,features,link,tag,tag-group}/**/*.{tsx,jsx}"
4+
"src/core/{accordion,avatar,badge,bottom-bar,breadcrumbs,button,button-group,chip,chip-group,chip-select,compact-select-native,features,link,tag,tag-group}/**/*.{tsx,jsx}"
55
],
66
"importPaths": {
77
"src/core/*": "@reapit/elements/core/*",
@@ -15,17 +15,23 @@
1515
"<AVATAR_CIRCLE_URL>": "https://www.figma.com/design/6CaivqdlTX0UkFYJkpBKDu/Reapit-DS?node-id=52-880",
1616
"<AVATAR_SQUARE_URL>": "https://www.figma.com/design/6CaivqdlTX0UkFYJkpBKDu/Reapit-DS?node-id=1077-7569",
1717
"<BADGE_URL>": "https://www.figma.com/design/6CaivqdlTX0UkFYJkpBKDu/Reapit-DS?node-id=1454-7529",
18+
"<BOTTOM_BAR_ITEM_URL>": "https://www.figma.com/design/6CaivqdlTX0UkFYJkpBKDu/Reapit-DS?node-id=12148-34925",
19+
"<BOTTOM_BAR_URL>": "https://www.figma.com/design/6CaivqdlTX0UkFYJkpBKDu/Reapit-DS?node-id=12148-35532",
1820
"<BREADCRUMB_ITEM_URL>": "https://www.figma.com/design/6CaivqdlTX0UkFYJkpBKDu/Reapit-DS?node-id=6903-9696",
1921
"<BREADCRUMB_LINK_URL>": "https://www.figma.com/design/6CaivqdlTX0UkFYJkpBKDu/Reapit-DS?node-id=6903-9655",
2022
"<BREADCRUMBS_URL>": "https://www.figma.com/design/6CaivqdlTX0UkFYJkpBKDu/Reapit-DS?node-id=6909-7884",
23+
"<BUTTON_GROUP_URL>": "https://www.figma.com/design/6CaivqdlTX0UkFYJkpBKDu/Reapit-DS?node-id=7205-7990",
2124
"<BUTTON_URL>": "https://www.figma.com/design/6CaivqdlTX0UkFYJkpBKDu/Reapit-DS?node-id=13904-19759",
22-
"<CHIP_URL>": "https://www.figma.com/design/6CaivqdlTX0UkFYJkpBKDu/Reapit-DS?node-id=7051-11054",
2325
"<CHIP_GROUP_URL>": "https://www.figma.com/design/6CaivqdlTX0UkFYJkpBKDu/Reapit-DS?node-id=7130-7091",
26+
"<CHIP_SELECT_OPTION_URL>": "https://www.figma.com/design/6CaivqdlTX0UkFYJkpBKDu/Reapit-DS?node-id=12386-27991",
27+
"<CHIP_SELECT_URL>": "https://www.figma.com/design/6CaivqdlTX0UkFYJkpBKDu/Reapit-DS?node-id=12386-28584",
28+
"<CHIP_URL>": "https://www.figma.com/design/6CaivqdlTX0UkFYJkpBKDu/Reapit-DS?node-id=7051-11054",
29+
"<COMPACT_SELECT_NAVTIVE_URL>": "https://www.figma.com/design/6CaivqdlTX0UkFYJkpBKDu/Reapit-DS?node-id=14083-70317",
2430
"<FEATURE_ITEM_URL>": "https://www.figma.com/design/6CaivqdlTX0UkFYJkpBKDu/Reapit-DS?node-id=12955-37788",
2531
"<FEATURES_URL>": "https://www.figma.com/design/6CaivqdlTX0UkFYJkpBKDu/Reapit-DS?node-id=2355-9645",
2632
"<LINK_URL>": "https://www.figma.com/design/6CaivqdlTX0UkFYJkpBKDu/Reapit-DS?node-id=11867-66681",
27-
"<TAG_URL>": "https://www.figma.com/design/6CaivqdlTX0UkFYJkpBKDu/Reapit-DS?node-id=55-982",
28-
"<TAG_GROUP_URL>": "https://www.figma.com/design/6CaivqdlTX0UkFYJkpBKDu/Reapit-DS?node-id=118-6272"
33+
"<TAG_GROUP_URL>": "https://www.figma.com/design/6CaivqdlTX0UkFYJkpBKDu/Reapit-DS?node-id=118-6272",
34+
"<TAG_URL>": "https://www.figma.com/design/6CaivqdlTX0UkFYJkpBKDu/Reapit-DS?node-id=55-982"
2935
}
3036
}
3137
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { BottomBar } from './bottom-bar'
2+
import figma from '@figma/code-connect'
3+
4+
const ref = { current: null }
5+
6+
figma.connect(BottomBar, '<BOTTOM_BAR_URL>', {
7+
props: {
8+
children: figma.children('*'),
9+
},
10+
example: (props) => (
11+
<BottomBar scrollContainerRef={ref}>
12+
<BottomBar.MenuList>{props.children}</BottomBar.MenuList>
13+
</BottomBar>
14+
),
15+
})
16+
17+
figma.connect(BottomBar, '<BOTTOM_BAR_URL>', {
18+
variant: { Items: '6+' },
19+
props: {
20+
children: figma.children('Item*'),
21+
moreButton: figma.nestedProps('More button', {
22+
hasBadge: figma.boolean('Badge'),
23+
icon: figma.instance('Icon'),
24+
label: figma.string('Label'),
25+
}),
26+
},
27+
example: (props) => (
28+
<BottomBar scrollContainerRef={ref}>
29+
<BottomBar.MenuList>
30+
{props.children}
31+
<BottomBar.MenuItem
32+
hasBadge={props.moreButton.hasBadge}
33+
icon={props.moreButton.icon}
34+
label={props.moreButton.label}
35+
>
36+
TODO: Add menu items
37+
</BottomBar.MenuItem>
38+
</BottomBar.MenuList>
39+
</BottomBar>
40+
),
41+
})
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { BottomBar } from '../bottom-bar'
2+
import figma from '@figma/code-connect'
3+
4+
figma.connect(BottomBar.MenuItem, '<BOTTOM_BAR_ITEM_URL>', {
5+
props: {
6+
children: figma.string('Label'),
7+
hasBadge: figma.boolean('Badge'),
8+
icon: figma.instance('Icon'),
9+
},
10+
example: (props) => (
11+
<BottomBar.Item aria-current={false} hasBadge={props.hasBadge} href="#replace-me" icon={props.icon}>
12+
{props.children}
13+
</BottomBar.Item>
14+
),
15+
})

src/core/bottom-bar/menu-list/menu-list-item.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,5 @@ export function BottomBarListItem({ children, ...props }: BottomBarListItem.Prop
2020
</ElBottomBarMenuListItem>
2121
)
2222
}
23+
24+
BottomBarListItem.displayName = 'BottomBar.Item'

src/core/bottom-bar/menu-list/menu-list-menu-item.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import type { ButtonHTMLAttributes, ReactNode } from 'react'
1010
export namespace BottomBarMenuListItem {
1111
export interface Props extends ButtonHTMLAttributes<HTMLButtonElement> {
1212
children: ReactNode
13+
hasBadge?: boolean
1314
icon?: ReactNode
1415
label?: string
1516
maxWidth?: `--size-${string}`
@@ -25,6 +26,7 @@ export namespace BottomBarMenuListItem {
2526
*/
2627
export function BottomBarMenuListItem({
2728
children,
29+
hasBadge,
2830
icon = <MoreIcon />,
2931
id,
3032
label = 'More',
@@ -60,6 +62,7 @@ export function BottomBarMenuListItem({
6062
<BottomBarItemButton
6163
{...rest}
6264
{...Menu.getTriggerProps({ id: triggerId, popoverTarget: menuId, popoverTargetAction: 'toggle' })}
65+
hasBadge={hasBadge}
6366
icon={icon}
6467
>
6568
{label}
@@ -70,3 +73,5 @@ export function BottomBarMenuListItem({
7073
</ElBottomBarMenuListItem>
7174
)
7275
}
76+
77+
BottomBarMenuListItem.displayName = 'BottomBar.MenuItem'

src/core/bottom-bar/menu-list/menu-list.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,7 @@ export function BottomBarMenuList({ children, ...rest }: BottomBarMenuList.Props
2121
return <ElBottomBarMenuList {...rest}>{children}</ElBottomBarMenuList>
2222
}
2323

24+
BottomBarMenuList.displayName = 'BottomBar.MenuList'
25+
2426
BottomBarMenuList.Item = BottomBarListItem
2527
BottomBarMenuList.MenuItem = BottomBarMenuListItem
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { ButtonGroup } from './button-group'
2+
import figma from '@figma/code-connect'
3+
4+
figma.connect(ButtonGroup, '<BUTTON_GROUP_URL>', {
5+
props: {
6+
children: figma.children('*'),
7+
},
8+
example: (props) => <ButtonGroup>{props.children}</ButtonGroup>,
9+
})

src/core/button-group/button-group.mdx

Lines changed: 0 additions & 37 deletions
This file was deleted.
Lines changed: 74 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,89 @@
1+
import { Button } from '#src/core/button'
12
import { ButtonGroup } from './button-group'
2-
import { DeprecatedButton } from '../../deprecated/button'
3-
import { Meta } from '@storybook/react-vite'
4-
import { figmaDesignUrls } from '../../storybook/figma'
5-
import { DeprecatedIcon } from '../../deprecated/icon'
63

7-
const meta: Meta<typeof ButtonGroup> = {
4+
import type { Meta, StoryObj } from '@storybook/react-vite'
5+
6+
const meta = {
87
title: 'Core/ButtonGroup',
98
component: ButtonGroup,
10-
}
9+
argTypes: {
10+
children: {
11+
control: 'radio',
12+
options: ['Secondary', 'Primary action', 'Mixed buttons'],
13+
mapping: {
14+
Secondary: (
15+
<>
16+
<Button size="medium" variant="secondary">
17+
Button 1
18+
</Button>
19+
<Button size="medium" variant="secondary">
20+
Button 2
21+
</Button>
22+
<Button size="medium" variant="secondary">
23+
Button 3
24+
</Button>
25+
</>
26+
),
27+
'Primary action': (
28+
<>
29+
<Button size="medium" variant="secondary">
30+
Button 1
31+
</Button>
32+
<Button size="medium" variant="secondary">
33+
Button 2
34+
</Button>
35+
<Button size="medium" variant="primary">
36+
Button 3
37+
</Button>
38+
</>
39+
),
40+
'Mixed buttons': (
41+
<>
42+
<Button size="medium" variant="tertiary">
43+
Button 1
44+
</Button>
45+
<Button size="medium" variant="secondary">
46+
Button 2
47+
</Button>
48+
<Button size="medium" variant="primary">
49+
Button 3
50+
</Button>
51+
</>
52+
),
53+
},
54+
},
55+
},
56+
} satisfies Meta<typeof ButtonGroup>
1157

1258
export default meta
59+
type Story = StoryObj<typeof ButtonGroup>
1360

14-
export const Default = {
15-
render: ({}) => (
16-
<ButtonGroup>
17-
<DeprecatedButton>Button 1</DeprecatedButton>
18-
<DeprecatedButton>Button 2</DeprecatedButton>
19-
<DeprecatedButton>Button 3</DeprecatedButton>
20-
<DeprecatedButton>Button 4</DeprecatedButton>
21-
<DeprecatedButton>Button 5</DeprecatedButton>
22-
</ButtonGroup>
23-
),
24-
parameters: {
25-
design: {
26-
type: 'figma',
27-
url: figmaDesignUrls.buttonGroup,
28-
allowFullscreen: true,
29-
},
61+
/**
62+
* Quite often, all buttons within the button group will be the same variant, but this is not strictly
63+
* required. What is strictly required is that button groups have at least one button, and all buttons
64+
* with the group share the same size.
65+
*/
66+
export const Example: Story = {
67+
args: {
68+
children: 'Secondary',
3069
},
3170
}
3271

33-
export const WithPrimaryButton = {
34-
render: ({}) => (
35-
<ButtonGroup>
36-
<DeprecatedButton>Button 1</DeprecatedButton>
37-
<DeprecatedButton>Button 2</DeprecatedButton>
38-
<DeprecatedButton>Button 3</DeprecatedButton>
39-
<DeprecatedButton>Button 4</DeprecatedButton>
40-
<DeprecatedButton variant="primary">Button 5</DeprecatedButton>
41-
</ButtonGroup>
42-
),
43-
parameters: {
44-
design: {
45-
type: 'figma',
46-
url: figmaDesignUrls.buttonGroup,
47-
allowFullscreen: true,
48-
},
72+
/**
73+
* It is common for one button to be a primary action. This is often the case with button groups used in
74+
* forms and dialogs.
75+
*/
76+
export const Primary = {
77+
args: {
78+
children: 'Primary action',
4979
},
5080
}
5181

52-
export const WithIconOnlyButton = {
53-
render: ({}) => (
54-
<ButtonGroup>
55-
<DeprecatedButton>Button 1</DeprecatedButton>
56-
<DeprecatedButton>Button 2</DeprecatedButton>
57-
<DeprecatedButton>Button 3</DeprecatedButton>
58-
<DeprecatedButton>Button 4</DeprecatedButton>
59-
<DeprecatedButton iconLeft={<DeprecatedIcon icon="more" fontSize="1rem" />} />
60-
</ButtonGroup>
61-
),
62-
parameters: {
63-
design: {
64-
type: 'figma',
65-
url: figmaDesignUrls.buttonGroup,
66-
allowFullscreen: true,
67-
},
82+
/**
83+
* Of course, where appropriate, any valid button variant can be used within a button group.
84+
*/
85+
export const Mixed = {
86+
args: {
87+
children: 'Mixed buttons',
6888
},
6989
}
Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
1-
import { FC, HTMLAttributes, ReactNode } from 'react'
21
import { ElButtonGroup } from './styles'
2+
import type { HTMLAttributes, ReactNode } from 'react'
33

44
export namespace ButtonGroup {
55
export interface Props extends HTMLAttributes<HTMLDivElement> {
6+
/** The buttons in the button group. */
67
children: ReactNode
78
}
89
}
910

10-
export const ButtonGroup: FC<ButtonGroup.Props> = ({ children, ...rest }) => {
11+
/**
12+
* A button group gives users access to frequently performed, related actions. While the button group
13+
* is flexible enough to allow for any button size to be used, all buttons should use the same size.
14+
*/
15+
export function ButtonGroup({ children, ...rest }: ButtonGroup.Props) {
1116
return <ElButtonGroup {...rest}>{children}</ElButtonGroup>
1217
}

0 commit comments

Comments
 (0)