Skip to content

Commit

Permalink
feat: new outline button components (#1068)
Browse files Browse the repository at this point in the history
Introduces a new OutlineButton component,
along with an OutlineDropdownButton.

Closes D2IQ-99363
  • Loading branch information
nataliepina authored Oct 20, 2023
1 parent 85e7be2 commit 8546cc3
Show file tree
Hide file tree
Showing 10 changed files with 369 additions and 4 deletions.
1 change: 1 addition & 0 deletions packages/button/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ There are several types of buttons to choose from based on the intended action:
| --------------- | ------------------------------------------------------------------------------- |
| Primary | Used for the most important call-to-action on a page, such as Save or Deploy. |
| Secondary | Used primarily for a call-to-action that is a link. |
| Outline | Used as an alternative secondary button with an outline/ghost style. |
| Warning | Used to advise caution. |
| Danger | Used to highlight something dangerous that can't be undone, such as "Delete". |
| Icon only | Use when an icon is enough to represent the action, such as "Create a Service". |
Expand Down
3 changes: 2 additions & 1 deletion packages/button/components/ButtonBase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ export enum ButtonAppearances {
Standard = "standard",
Danger = "danger",
Success = "success",
Warning = "warning"
Warning = "warning",
Outline = "outline"
}

export interface ButtonProps extends LinkProps {
Expand Down
16 changes: 16 additions & 0 deletions packages/button/components/OutlineButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import * as React from "react";
import {
default as ButtonBase,
ButtonProps,
ButtonAppearances
} from "./ButtonBase";

const OutlineButton = (props: ButtonProps) => (
<ButtonBase
appearance={ButtonAppearances.Outline}
data-cy={props["data-cy"] ?? "outlineButton"}
{...props}
/>
);

export default OutlineButton;
14 changes: 14 additions & 0 deletions packages/button/components/OutlineDropdownButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import * as React from "react";
import OutlineButton from "./OutlineButton";
import { ButtonProps } from "./ButtonBase";
import { SystemIcons } from "../../icons/dist/system-icons-enum";

const OutlineDropdownButton = (props: ButtonProps) => (
<OutlineButton
iconEnd={SystemIcons.TriangleDown}
data-cy={props["data-cy"] ?? "outlineDropdownButton"}
{...props}
/>
);

export default OutlineDropdownButton;
2 changes: 2 additions & 0 deletions packages/button/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ export { default as StandardButton } from "./components/StandardButton";
export { default as SuccessButton } from "./components/SuccessButton";
export { default as DangerButton } from "./components/DangerButton";
export { default as WarningButton } from "./components/WarningButton";
export { default as OutlineButton } from "./components/OutlineButton";

export { default as PrimaryDropdownButton } from "./components/PrimaryDropdownButton";
export { default as SecondaryDropdownButton } from "./components/SecondaryDropdownButton";
export { default as StandardDropdownButton } from "./components/StandardDropdownButton";
export { default as SuccessDropdownButton } from "./components/SuccessDropdownButton";
export { default as WarningDropdownButton } from "./components/WarningDropdownButton";
export { default as DangerDropdownButton } from "./components/DangerDropdownButton";
export { default as OutlineDropdownButton } from "./components/OutlineDropdownButton";

export { default as ResetButton } from "./components/ResetButton";
8 changes: 7 additions & 1 deletion packages/button/stories/DefaultButton.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import {
StandardButton,
SuccessButton,
DangerButton,
WarningButton
WarningButton,
OutlineButton
} from "../..";
import { action } from "@storybook/addon-actions";
import { SystemIcons } from "../../icons/dist/system-icons-enum";
Expand All @@ -17,6 +18,7 @@ export default {
component: StandardButton,
subComponents: {
PrimaryButton,
OutlineButton,
SecondaryButton,
SuccessButton,
DangerButton,
Expand Down Expand Up @@ -59,6 +61,10 @@ export const _SecondaryButton = {
render: args => <SecondaryButton {...args}>{args.children}</SecondaryButton>
};

export const _OutlineButton = {
render: args => <OutlineButton {...args}>{args.children}</OutlineButton>
};

export const _SuccessButton = {
render: args => <SuccessButton {...args}>{args.children}</SuccessButton>
};
Expand Down
9 changes: 8 additions & 1 deletion packages/button/stories/DropdownButton.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import {
StandardDropdownButton,
SuccessDropdownButton,
WarningDropdownButton,
DangerDropdownButton
DangerDropdownButton,
OutlineDropdownButton
} from "../../index";
import { SystemIcons } from "../../icons/dist/system-icons-enum";

Expand Down Expand Up @@ -49,6 +50,12 @@ export const _SecondaryDropdownButton = {
)
};

export const _OutlineDropdownButton = {
render: args => (
<OutlineDropdownButton {...args}>{args.children}</OutlineDropdownButton>
)
};

export const _SuccessDropdownButton = {
render: args => (
<SuccessDropdownButton {...args}>{args.children}</SuccessDropdownButton>
Expand Down
72 changes: 71 additions & 1 deletion packages/button/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ import {
themeErrorInverted,
themeTextColorDisabledInverted,
themeWarningInverted,
themeWarning
themeWarning,
purpleLighten5,
purpleLighten4,
themeBgPrimary
} from "../design-tokens/build/js/designTokens";
import { darken, getTextColor } from "../shared/styles/color";
import { ButtonAppearances } from "./components/ButtonBase";
Expand Down Expand Up @@ -70,6 +73,7 @@ export const filledButton = (

const mutedButton = css`
${tintContent(themeTextColorDisabled)};
border-color: ${themeBgDisabled};
cursor: default;
pointer-events: none;
Expand Down Expand Up @@ -196,6 +200,26 @@ export const focusStyleByAppearance = (appearance, isInverse) => {
return isInverse
? focusStyles(getHoverColor(getCSSVarValue(themeWarningInverted)))
: focusStyles(getHoverColor(getCSSVarValue(themeWarning)));
case "outline":
return css`
${(isInverse
? focusStyles(
getCSSVarValue(themeBgPrimary),
getHoverColor(getCSSVarValue(themeTextColorInteractiveInverted))
)
: getCSSVarValue(themeBgPrimary),
focusStyles(getHoverColor(getCSSVarValue(themeTextColorInteractive))))};
&:focus {
background-color: ${purpleLighten5};
&:after {
bottom: -4px;
left: -4px;
right: -4px;
top: -4px;
}
}
`;
default:
return "";
}
Expand Down Expand Up @@ -251,6 +275,32 @@ export const button = appearance => {
getHoverColor(getCSSVarValue(themeWarning)),
getActiveColor(getCSSVarValue(themeWarning))
);
case "outline":
return css`
border: 1px solid ${getCSSVarValue(themeTextColorInteractive)};
border-radius: ${borderRadiusDefault};
padding: ${buttonPadding.vert} ${buttonPadding.horiz};
${tintContent(themeTextColorInteractive)};
&:hover {
background-color: ${purpleLighten5};
${tintContent(
getHoverColor(getCSSVarValue(themeTextColorInteractive))
)};
}
&:active {
background-color: ${purpleLighten4};
${tintContent(
getActiveColor(getCSSVarValue(themeTextColorInteractive))
)};
}
&[href],
&[href]:visited {
background-color: ${purpleLighten4};
${tintContent(themeTextColorInteractive)};
}
`;
default:
return "";
}
Expand Down Expand Up @@ -306,6 +356,26 @@ export const buttonInverse = appearance => {
getHoverColor(getCSSVarValue(themeWarningInverted)),
getActiveColor(getCSSVarValue(themeWarningInverted))
);
case "outline":
return css`
border: 1px solid ${getCSSVarValue(themeTextColorInteractiveInverted)};
${tintContent(themeTextColorInteractiveInverted)};
&:hover {
${tintContent(
getHoverColor(getCSSVarValue(themeTextColorInteractiveInverted))
)};
}
&:active {
${tintContent(
getActiveColor(getCSSVarValue(themeTextColorInteractiveInverted))
)};
}
&[href],
&[href]:visited {
${tintContent(themeTextColorInteractiveInverted)};
}
`;
default:
return "";
}
Expand Down
Loading

0 comments on commit 8546cc3

Please sign in to comment.