Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(theme/Button): implement new DS theming #10315

Merged
merged 9 commits into from
Jun 30, 2023
183 changes: 91 additions & 92 deletions src/@chakra-ui/gatsby-plugin/components/Button.ts
Original file line number Diff line number Diff line change
@@ -1,101 +1,82 @@
import { defineStyle, defineStyleConfig } from "@chakra-ui/react"
import { buttonDefaultTheme, defineMergeStyles } from "./components.utils"

const {
baseStyle: defaultBaseStyle,
sizes: defaultSizes,
variants: defaultVariants,
defaultProps,
} = buttonDefaultTheme
/**
* This selector over the more specific `& .chakra-button__icon` accounts
* for icons used both as a singleton (in IconButton) and as aside element
* with text. The mention classname is not used for the singleton.
*
* And because the icons `fontSize` is different than the text, the icon size
* needs to stay the same when a singleton.
*/
const ICON_SELECTOR = "& svg"
pettinarip marked this conversation as resolved.
Show resolved Hide resolved

const baseStyle = defineMergeStyles(defaultBaseStyle, {
fontWeight: "normal",
const getBaseColor = (isSecondary: boolean) =>
!isSecondary ? "primary.base" : "body.base"

const baseStyle = defineStyle((props) => ({
borderRadius: "base",
_hover: {
textDecoration: "none",
boxShadow: "primary",
_disabled: {
boxShadow: "none",
},
border: "1px",
color: getBaseColor(props.isSecondary),
lineHeight: "1.6",
transitionProperty: "common",
transitionDuration: "normal",
whiteSpace: "normal",
_focusVisible: {
outline: "4px solid",
outlineColor: "primary.hover",
outlineOffset: -1,
},
_focus: {
boxShadow: "outline",
outline: 0,
_disabled: {
color: "disabled",
pointerEvents: "none",
},
})

const disabledStylesSolid = defineStyle({
bg: "disabled",
opacity: 1,
})

const disabledStylesOutline = defineStyle({
color: "disabled",
borderColor: "disabled",
opacity: 1,
})
_hover: {
color: "primary.hover",
},
}))

const commonOutline = defineStyle({
border: "1px",
color: "text",
bg: "transparent",
borderColor: "text",
const variantSolid = defineStyle({
color: "background.base",
bg: "primary.base",
_hover: {
color: "primary.base",
bg: "background.base",
borderColor: "primary.base",
_disabled: {
...disabledStylesOutline,
},
color: "background.base",
bg: "primary.hover",
boxShadow: "buttonHover",
},
_active: {
color: "primary.base",
bg: "primary.light",
borderColor: "primary.base",
boxShadow: "none",
},
_focus: {
color: "primary.base",
borderColor: "background.base",
_disabled: {
...disabledStylesOutline,
},
})

const variantOutline = defineStyle({
_hover: {
boxShadow: "buttonHover",
},
_disabled: {
...disabledStylesOutline,
_active: {
boxShadow: "none",
},
})

const variantSolid = defineStyle((props) =>
defineMergeStyles(defaultVariants?.solid(props), {
color: "buttonColor",
bg: "primary.base",
border: 0,
_hover: {
bg: "primary.base",
opacity: 0.8,
_disabled: {
...disabledStylesSolid,
},
},
_active: {
bg: "primary.hover",
},
_disabled: {
...disabledStylesSolid,
},
})
)
const variantGhost = {
borderColor: "transparent",
}

const variantOutline = defineStyle((props) =>
defineMergeStyles(defaultVariants?.outline(props), commonOutline)
)

const variantOutlineColor = defineStyle({
...commonOutline,
const variantLink = defineStyle({
borderColor: "transparent",
color: "primary.base",
borderColor: "primary.base",
fontWeight: 700,
textDecor: "underline",
py: 0,
px: 1,
_active: {
color: "primary.base",
},
})

/**
* @deprecated This is no longer needed. Styling for just the icon is not
* unique compared to the variants used for text (as of the new DS)
*/
const variantIcon = defineStyle({
TylerAPfledderer marked this conversation as resolved.
Show resolved Hide resolved
appearance: "none",
background: "inherit",
Expand All @@ -109,20 +90,38 @@ const variantIcon = defineStyle({
},
})

const sizes = {
md: {
py: "2 !important",
px: "4 !important",
pettinarip marked this conversation as resolved.
Show resolved Hide resolved
[ICON_SELECTOR]: {
fontSize: "2xl",
},
},
sm: {
fontSize: "xs",
py: "1.5 !important",
px: "2 !important",
[ICON_SELECTOR]: {
fontSize: "md",
},
},
}

const variants = {
solid: variantSolid,
outline: variantOutline,
ghost: variantGhost,
link: variantLink,
icon: variantIcon,
}

export const Button = defineStyleConfig({
baseStyle,
sizes: defineMergeStyles(defaultSizes, {
md: {
h: 10.5,
},
}),
variants: {
...buttonDefaultTheme.variants,
// solid is the default variant used by chakra
solid: variantSolid,
outline: variantOutline,
"outline-color": variantOutlineColor,
icon: variantIcon,
sizes,
variants,
defaultProps: {
size: "md",
variant: "solid",
},
defaultProps,
})
2 changes: 0 additions & 2 deletions src/@chakra-ui/gatsby-plugin/components/components.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ const {
Avatar: avatarDefaultTheme,
Badge: badgeDefaultTheme,
Breadcrumb: breadcrumbDefaultTheme,
Button: buttonDefaultTheme,
Checkbox: checkboxDefaultTheme,
CloseButton: closeButtonDefaultTheme,
Code: codeDefaultTheme,
Expand Down Expand Up @@ -34,7 +33,6 @@ export {
avatarDefaultTheme,
badgeDefaultTheme,
breadcrumbDefaultTheme,
buttonDefaultTheme,
pettinarip marked this conversation as resolved.
Show resolved Hide resolved
checkboxDefaultTheme,
closeButtonDefaultTheme,
codeDefaultTheme,
Expand Down
2 changes: 1 addition & 1 deletion src/@chakra-ui/gatsby-plugin/foundations/colors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const colors = {
300: "#ffb991",
500: "#ff7324",
600: "#c95d20",
800: "#6a3301",
800: "#352313",
},
red: {
100: "#f7c8c8",
Expand Down
3 changes: 2 additions & 1 deletion src/@chakra-ui/gatsby-plugin/foundations/shadows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ const shadows = {
gridBlueBowShadow: "8px 8px 0px 0px var(--eth-colors-gridBlue)",

// * Part of new DS
// TODO: From current theme. Rename to 'buttonHover'
// TODO: From current theme. Deprecate for 'buttonHover'
primary: "4px 4px 0px 0px var(--eth-colors-primary-light)",
buttonHover: "4px 4px 0 0 var(--eth-colors-primary-lowContrast)",
tooltip: "0 0 16px var(--eth-colors-tooltipShadow)",
}

Expand Down
112 changes: 97 additions & 15 deletions src/components/Button/Button.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,115 @@
import * as React from "react"
import { HStack, IconButton, ThemingProps, VStack } from "@chakra-ui/react"
import { getThemingArgTypes } from "@chakra-ui/storybook-addon"
import { Meta, StoryObj } from "@storybook/react"
import { MdExpandMore, MdChevronRight } from "react-icons/md"
import Button from "."
import theme from "../../@chakra-ui/gatsby-plugin/theme"

export default {
component: Button,
} as Meta<typeof Button>
type ButtonType = typeof Button

export const Solid: StoryObj<typeof Button> = {
const meta: Meta<ButtonType> = {
title: "Atoms / Form / Buttons",
component: Button,
args: {
children: "What is Ethereum?",
},
argTypes: {
isSecondary: {
defaultValue: false,
type: "boolean",
name: "Is a secondary color?",
if: { arg: "variant", neq: "solid" },
},
},
}

export const Outline: StoryObj<typeof Button> = {
args: {
children: "More on digital money",
variant: "outline",
export default meta

type Story = StoryObj<ButtonType>

const variants: ThemingProps<"Button">["variant"][] = [
"solid",
"outline",
"ghost",
"link",
]

export const StyleVariants: Story = {
argTypes: {
size: {
//@ts-expect-error
...getThemingArgTypes(theme, "Button")?.size,
defaultValue: "md",
},
},
render: (args) => (
<VStack spacing={4}>
{variants.map((variant, idx) => {
if (args.isSecondary && variant === "solid") return
return <Button key={idx} variant={variant} {...args} />
})}
</VStack>
),
}

export const OutlineColor: StoryObj<typeof Button> = {
args: {
children: "More on digital money",
variant: "outline-color",
export const IconVariants: Story = {
argTypes: {
variant: {
control: "radio",
options: ["solid", "outline", "ghost", "link"],
},
},
render: (args) => (
<HStack>
<VStack>
<Button {...args} />
<Button size="sm" {...args} />
</VStack>
<VStack>
<Button leftIcon={<MdExpandMore />} {...args} />
<Button leftIcon={<MdExpandMore />} size="sm" {...args} />
</VStack>
<VStack>
<Button rightIcon={<MdChevronRight />} {...args} />
<Button rightIcon={<MdChevronRight />} size="sm" {...args} />
</VStack>
<VStack>
<IconButton aria-label="next" icon={<MdChevronRight />} {...args} />
<IconButton
aria-label="next"
icon={<MdChevronRight />}
size="sm"
{...args}
/>
</VStack>
</HStack>
),
}

export const Disabled: StoryObj<typeof Button> = {
export const MultiLineText: Story = {
args: {
children: "I am disabled",
isDisabled: true,
children: "Button label can have two lines",
},
render: (args) => (
<HStack>
<VStack maxW="171px">
<Button variant="outline" isSecondary {...args} />
<Button variant="outline" size="sm" isSecondary {...args} />
</VStack>
<VStack maxW="171px">
<Button {...args} />
<Button size="sm" isSecondary {...args} />
</VStack>
<VStack maxW="209px">
<Button rightIcon={<MdChevronRight />} {...args} />
<Button
rightIcon={<MdChevronRight />}
size="sm"
isSecondary
{...args}
/>
</VStack>
</HStack>
),
}
Loading