-
Notifications
You must be signed in to change notification settings - Fork 331
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(components): styled button (#5803)
* feat(components): add backwards compatible button * cleanup the story
- Loading branch information
1 parent
374fac4
commit e8afaa8
Showing
7 changed files
with
288 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import React, { ReactNode, Ref } from "react"; | ||
import { | ||
Button as AriaButton, | ||
ButtonProps as AriaButtonProps, | ||
} from "react-aria-components"; | ||
|
||
import { SizingProps, VarianceProps } from "@phoenix/components/types"; | ||
|
||
import { buttonCSS } from "./styles"; | ||
|
||
interface ButtonProps extends AriaButtonProps, SizingProps, VarianceProps { | ||
/** | ||
* An optional prefixed icon for the button | ||
*/ | ||
icon?: ReactNode; | ||
} | ||
|
||
function Button(props: ButtonProps, ref: Ref<HTMLButtonElement>) { | ||
const { | ||
size = "M", | ||
variant = "default", | ||
icon, | ||
children, | ||
...otherProps | ||
} = props; | ||
return ( | ||
<AriaButton | ||
{...otherProps} | ||
ref={ref} | ||
data-size={size} | ||
data-variant={variant} | ||
data-childless={!children} | ||
css={buttonCSS} | ||
> | ||
{icon} | ||
<>{children}</> | ||
</AriaButton> | ||
); | ||
} | ||
|
||
const _Button = React.forwardRef(Button); | ||
export { _Button as Button, ButtonProps }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import { css } from "@emotion/react"; | ||
|
||
export const buttonCSS = css` | ||
border: 1px solid var(--ac-global-border-color-default); | ||
font-size: var(--ac-global-dimension-static-font-size-100); | ||
line-height: 20px; // TODO(mikeldking): move this into a consistent variable | ||
margin: 0; | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
box-sizing: border-box; | ||
border-radius: var(--ac-global-rounding-small); | ||
color: var(--ac-global-text-color-900); | ||
cursor: pointer; | ||
/* Disable outline since there are other mechanisms to show focus */ | ||
outline: none; | ||
&:not([disabled]) { | ||
transition: all 0.2s ease-in-out; | ||
} | ||
&[disabled] { | ||
cursor: default; | ||
opacity: 0.6; | ||
} | ||
&[data-size="M"][data-childless="false"] { | ||
padding: var(--ac-global-dimension-static-size-100) | ||
var(--ac-global-dimension-static-size-200); | ||
} | ||
&[data-size="S"][data-childless="false"] { | ||
padding: var(--ac-global-dimension-static-size-50) | ||
var(--ac-global-dimension-static-size-100); | ||
} | ||
&[data-size="M"][data-childless="true"] { | ||
padding: var(--ac-global-dimension-static-size-100) | ||
var(--ac-global-dimension-static-size-100); | ||
} | ||
&[data-size="S"][data-childless="true"] { | ||
padding: var(--ac-global-dimension-static-size-50) | ||
var(--ac-global-dimension-static-size-50); | ||
} | ||
&[data-variant="primary"] { | ||
background-color: var(--ac-global-button-primary-background-color); | ||
border-color: var(--ac-global-button-primary-border-color); | ||
color: var(--ac-global-static-color-white-900); | ||
&:hover:not([disabled]) { | ||
background-color: var(--ac-global-button-primary-background-color-hover); | ||
} | ||
} | ||
&[data-variant="danger"] { | ||
background-color: var(--ac-global-button-danger-background-color); | ||
border-color: var(--ac-global-button-danger-border-color); | ||
color: var(--ac-global-static-color-white-900); | ||
&:hover:not([disabled]) { | ||
background-color: var(--ac-global-button-danger-background-color-hover); | ||
} | ||
} | ||
&[data-variant="success"] { | ||
background-color: var(--ac-global-button-success-background-color); | ||
border-color: var(--ac-global-button-success-border-color); | ||
color: var(--ac-global-static-color-white-900); | ||
color: var(--ac-global-static-color-white-900); | ||
&:hover:not([disabled]) { | ||
background-color: var(--ac-global-button-success-background-color-hover); | ||
} | ||
} | ||
&[data-variant="default"] { | ||
background-color: var(--ac-global-input-field-background-color); | ||
border-color: var(--ac-global-input-field-border-color); | ||
&:hover:not([disabled]) { | ||
background-color: var(--ac-global-input-field-border-color-hover); | ||
} | ||
} | ||
&[data-variant="quiet"] { | ||
background-color: transparent; | ||
border-color: transparent; | ||
&:hover:not([disabled]) { | ||
border-color: transparent; | ||
background-color: var(--ac-global-input-field-background-color-active); | ||
} | ||
} | ||
&[data-childless="false"] > i, | ||
& > .ac-spinner { | ||
margin-right: var(--ac-global-dimension-static-size-50); | ||
} | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
export * from "./sizing"; | ||
export * from "./variance"; |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
export type BaseVariant = "primary" | "default"; | ||
export type LevelVariant = "success" | "danger" | "info"; | ||
|
||
export type Variant = BaseVariant | LevelVariant; | ||
|
||
export interface VarianceProps { | ||
/** | ||
* The variant of the component | ||
* @default 'default' | ||
*/ | ||
variant?: Variant; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
import React from "react"; | ||
import { Meta, StoryFn } from "@storybook/react"; | ||
import { css } from "@emotion/react"; | ||
|
||
import { Button as LegacyButton, Icon, Icons } from "@arizeai/components"; | ||
|
||
import { Button, ButtonProps } from "@phoenix/components/button/Button"; | ||
|
||
import { ThemeWrapper } from "./components/ThemeWrapper"; | ||
|
||
const meta: Meta = { | ||
title: "Button", | ||
component: Button, | ||
argTypes: { | ||
label: { | ||
control: { | ||
type: "text", | ||
default: "Label", | ||
}, | ||
}, | ||
isDisabled: { | ||
type: "boolean", | ||
}, | ||
description: { | ||
type: "string", | ||
control: { | ||
type: "text", | ||
}, | ||
}, | ||
errorMessage: { | ||
type: "string", | ||
control: { | ||
type: "text", | ||
}, | ||
}, | ||
isInvalid: { | ||
control: { | ||
type: "boolean", | ||
}, | ||
}, | ||
isRequired: { | ||
control: { | ||
type: "boolean", | ||
}, | ||
}, | ||
menuTrigger: { | ||
options: ["manual", "input", "focus"], | ||
control: { | ||
type: "radio", | ||
}, | ||
}, | ||
}, | ||
|
||
parameters: { | ||
controls: { expanded: true }, | ||
}, | ||
}; | ||
|
||
export default meta; | ||
|
||
const Template: StoryFn<ButtonProps> = (args) => ( | ||
<ThemeWrapper> | ||
<Button {...args} /> | ||
</ThemeWrapper> | ||
); | ||
|
||
export const Default = Template.bind({}); | ||
|
||
Default.args = { | ||
children: "Button", | ||
}; | ||
|
||
const liCSS = css` | ||
display: flex; | ||
flex-direction: row; | ||
gap: 8px; | ||
align-items: center; | ||
`; | ||
|
||
export const Migration = () => { | ||
return ( | ||
<> | ||
<ThemeWrapper> | ||
<ul | ||
css={css` | ||
display: flex; | ||
flex-direction: column; | ||
gap: 4px; | ||
`} | ||
> | ||
<li css={liCSS}> | ||
<Button key="new" icon={<Icon svg={<Icons.PlusCircleOutline />} />}> | ||
Button | ||
</Button> | ||
<LegacyButton | ||
variant="default" | ||
key="old" | ||
icon={<Icon svg={<Icons.PlusCircleOutline />} />} | ||
> | ||
Legacy | ||
</LegacyButton> | ||
<Button key="new-s" size="S"> | ||
Button | ||
</Button> | ||
<LegacyButton variant="default" key="old-s" size="compact"> | ||
Legacy | ||
</LegacyButton> | ||
</li> | ||
<li css={liCSS}> | ||
<Button key="new" variant="primary"> | ||
Button | ||
</Button> | ||
<LegacyButton variant="primary" key="old"> | ||
Legacy | ||
</LegacyButton> | ||
</li> | ||
<li css={liCSS}> | ||
<Button key="new" variant="danger"> | ||
Button | ||
</Button> | ||
<LegacyButton variant="danger" key="old"> | ||
Legacy | ||
</LegacyButton> | ||
</li> | ||
<li css={liCSS}> | ||
<Button key="new" variant="success"> | ||
Button | ||
</Button> | ||
<LegacyButton variant="success" key="old"> | ||
Legacy | ||
</LegacyButton> | ||
</li> | ||
</ul> | ||
</ThemeWrapper> | ||
</> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters