Skip to content

Commit 77c5277

Browse files
authored
Merge pull request #11047 from TylerAPfledderer/feat/ButtonTwoLines
feat(components): add `ButtonTwoLines` component
2 parents 461d78b + 9f1b459 commit 77c5277

File tree

2 files changed

+140
-0
lines changed

2 files changed

+140
-0
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import * as React from "react"
2+
import { Meta, StoryObj } from "@storybook/react"
3+
import { BiCircle } from "react-icons/bi"
4+
import { Stack } from "@chakra-ui/react"
5+
import ButtonTwoLinesComponent from "."
6+
7+
type ComponentType = typeof ButtonTwoLinesComponent
8+
9+
const meta = {
10+
title: "Atoms / Form / Buttons / ButtonTwoLines",
11+
component: ButtonTwoLinesComponent,
12+
} satisfies Meta<ComponentType>
13+
14+
export default meta
15+
16+
type Story = StoryObj<typeof meta>
17+
18+
export const ButtonTwoLines: Story = {
19+
args: {
20+
icon: BiCircle,
21+
mainText: "Main Text",
22+
helperText: "Helper Text",
23+
w: "300px",
24+
},
25+
render: (args) => (
26+
<Stack spacing="8">
27+
<ButtonTwoLinesComponent {...args} />
28+
<ButtonTwoLinesComponent
29+
{...args}
30+
iconAlignment="right"
31+
size="sm"
32+
reverseTextOrder
33+
/>
34+
</Stack>
35+
),
36+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import * as React from "react"
2+
import { Icon, Stack, Text } from "@chakra-ui/react"
3+
import type { IconType } from "react-icons/lib"
4+
import Button, { type IProps as ButtonProps } from "../Button"
5+
import ButtonLink, { type IProps as ButtonLinkProps } from "../ButtonLink"
6+
7+
type CommonProps = {
8+
icon: IconType | typeof Icon
9+
iconAlignment?: "left" | "right"
10+
/**
11+
* Reduced choices of the button variant.
12+
*
13+
* This component only accepts the `solid` or `outline` variant
14+
*/
15+
variant?: "solid" | "outline"
16+
/**
17+
* Reduced choices of the button size
18+
*
19+
* This component only accepts the `md` or `sm` sizes
20+
*/
21+
size?: "md" | "sm"
22+
mainText: string
23+
helperText: string
24+
/**
25+
* Should the main text be below the helper text instead of ab?
26+
*/
27+
reverseTextOrder?: boolean
28+
}
29+
30+
type OmittedTypes = "variant" | "size"
31+
32+
type ButtonTypeProps = CommonProps &
33+
Omit<ButtonProps, OmittedTypes> & {
34+
href?: never
35+
}
36+
37+
type ButtonLinkTypeProps = CommonProps &
38+
Omit<ButtonLinkProps, OmittedTypes> & {
39+
toId?: never
40+
}
41+
42+
type ButtonTwoLinesProps = ButtonTypeProps | ButtonLinkTypeProps
43+
44+
const hasHref = (props: ButtonTwoLinesProps): props is ButtonLinkTypeProps => {
45+
return "href" in props
46+
}
47+
48+
const ButtonTwoLines = (props: ButtonTwoLinesProps) => {
49+
const {
50+
icon: Icon,
51+
iconAlignment = "left",
52+
mainText,
53+
helperText,
54+
reverseTextOrder = false,
55+
size = "md",
56+
...rest
57+
} = props
58+
59+
const isIconLeft = iconAlignment === "left"
60+
61+
const vertPadding: ButtonTwoLinesProps["py"] = size === "md" ? "4" : "2"
62+
63+
const buttonStyles: ButtonProps = {
64+
[isIconLeft ? "leftIcon" : "rightIcon"]: <Icon />,
65+
textAlign: isIconLeft ? "start" : "end",
66+
justifyContent: isIconLeft ? "flex-start" : "flex-end",
67+
}
68+
69+
const Component = hasHref(props) ? ButtonLink : Button
70+
71+
return (
72+
<Component
73+
{...buttonStyles}
74+
size={size}
75+
py={vertPadding}
76+
{...rest}
77+
sx={{
78+
".chakra-button__icon svg": {
79+
// Force icon to be the same size for both button sizes
80+
fontSize: "2xl",
81+
},
82+
}}
83+
>
84+
<Stack
85+
spacing={0}
86+
flexDir={reverseTextOrder ? "column-reverse" : "column"}
87+
>
88+
<Text
89+
as="span"
90+
fontSize="md"
91+
fontWeight={size === "md" ? "bold" : "normal"}
92+
>
93+
{mainText}
94+
</Text>
95+
{/* TODO: use `size='xs'` instead when the Text theme is added */}
96+
<Text as="span" fontSize="xs">
97+
{helperText}
98+
</Text>
99+
</Stack>
100+
</Component>
101+
)
102+
}
103+
104+
export default ButtonTwoLines

0 commit comments

Comments
 (0)