Skip to content

Commit

Permalink
Initial attempt at docs
Browse files Browse the repository at this point in the history
  • Loading branch information
joshwooding committed Jul 25, 2024
1 parent 897bd16 commit 32157c3
Show file tree
Hide file tree
Showing 13 changed files with 250 additions and 115 deletions.
28 changes: 9 additions & 19 deletions .changeset/button-changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,15 @@
"@salt-ds/core": minor
---

Added `color` and `appearance` prop for Button.
Added `color` and `appearance` props for Button. These props replace the `variant` prop.

```tsx
<Button color="accent" appearance="solid">
Send <SendIcon aria-hidden />
</Button>
<Button color="accent" appearance="outline">
Send <SendIcon aria-hidden />
</Button>
<Button color="accent" appearance="transparent">
Send <SendIcon aria-hidden />
</Button>
<Button color="neutral" appearance="solid">
Send <SendIcon aria-hidden />
</Button>
<Button color="neutral" appearance="outline">
Send <SendIcon aria-hidden />
</Button>
<Button color="neutral" appearance="transparent">
Send <SendIcon aria-hidden />
</Button>
<Button color="accent" appearance="solid" />
<Button color="accent" appearance="outline" />
<Button color="accent" appearance="transparent" />
<Button color="neutral" appearance="solid" />
<Button color="neutral" appearance="outline" />
<Button color="neutral" appearance="transparent" />
```

_Note:_ Button's `variant` prop is now deprecated and will be removed in the next major version.
12 changes: 6 additions & 6 deletions packages/core/src/button/Button.css
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
border-color: var(--saltButton-borderColor-disabled, var(--button-borderColor-disabled));
}

.saltButton-solid-accent {
.saltButton-accent.saltButton-solid {
--button-text-color: var(--salt-actionable-accent-bold-foreground);
--button-text-color-hover: var(--salt-actionable-accent-bold-foreground-hover);
--button-text-color-active: var(--salt-actionable-accent-bold-foreground-active);
Expand All @@ -100,7 +100,7 @@
--button-borderColor-disabled: var(--salt-actionable-accent-bold-borderColor-disabled);
}

.saltButton-outline-accent {
.saltButton-accent.saltButton-outline {
--button-text-color: var(--salt-actionable-accent-foreground);
--button-text-color-hover: var(--salt-actionable-accent-foreground-hover);
--button-text-color-active: var(--salt-actionable-accent-foreground-active);
Expand All @@ -115,7 +115,7 @@
--button-borderColor-disabled: var(--salt-actionable-accent-borderColor-disabled);
}

.saltButton-transparent-accent {
.saltButton-accent.saltButton-transparent {
--button-text-color: var(--salt-actionable-accent-subtle-foreground);
--button-text-color-hover: var(--salt-actionable-accent-subtle-foreground-hover);
--button-text-color-active: var(--salt-actionable-accent-subtle-foreground-active);
Expand All @@ -130,7 +130,7 @@
--button-borderColor-disabled: var(--salt-actionable-accent-subtle-borderColor-disabled);
}

.saltButton-solid-neutral {
.saltButton-neutral.saltButton-solid {
--button-text-color: var(--salt-actionable-bold-foreground);
--button-text-color-hover: var(--salt-actionable-bold-foreground-hover);
--button-text-color-active: var(--salt-actionable-bold-foreground-active);
Expand All @@ -145,7 +145,7 @@
--button-borderColor-disabled: var(--salt-actionable-bold-borderColor-disabled);
}

.saltButton-outline-neutral {
.saltButton-neutral.saltButton-outline {
--button-text-color: var(--salt-actionable-foreground);
--button-text-color-hover: var(--salt-actionable-foreground-hover);
--button-text-color-active: var(--salt-actionable-foreground-active);
Expand All @@ -160,7 +160,7 @@
--button-borderColor-disabled: var(--salt-actionable-borderColor-disabled);
}

.saltButton-transparent-neutral {
.saltButton-neutral.saltButton-transparent {
--button-text-color: var(--salt-actionable-subtle-foreground);
--button-text-color-hover: var(--salt-actionable-subtle-foreground-hover);
--button-text-color-active: var(--salt-actionable-subtle-foreground-active);
Expand Down
32 changes: 19 additions & 13 deletions packages/core/src/button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export interface ButtonProps extends ComponentPropsWithoutRef<"button"> {
/**
* The variant to use. Options are 'primary', 'secondary' and 'cta'.
* 'primary' is the default value.
* @deprecated Use `appearance` and `color` instead.
*/
variant?: ButtonVariant;
/**
Expand All @@ -44,6 +45,17 @@ export interface ButtonProps extends ComponentPropsWithoutRef<"button"> {
color?: ButtonColor;
}

function variantToAppearanceAndColor(variant: ButtonVariant) {
switch (variant) {
case "primary":
return { appearance: "solid", color: "neutral" };
case "secondary":
return { appearance: "transparent", color: "neutral" };
case "cta":
return { appearance: "solid", color: "accent" };
}
}

export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
function Button(
{
Expand All @@ -55,8 +67,8 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
onKeyDown,
onBlur,
onClick,
appearance,
color,
appearance: appearanceProp,
color: colorProp,
type = "button",
variant = "primary",
...restProps
Expand All @@ -79,15 +91,9 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
window: targetWindow,
});

const variantStyles = {
primary: { defaultAppearance: "solid", defaultColor: "neutral" },
secondary: { defaultAppearance: "transparent", defaultColor: "neutral" },
cta: { defaultAppearance: "solid", defaultColor: "accent" },
};

const { defaultAppearance, defaultColor } = variantStyles[variant];
const resolvedAppearance = appearance ?? defaultAppearance;
const resolvedColor = color ?? defaultColor;
const mapped = variantToAppearanceAndColor(variant);
const appearance = appearanceProp ?? mapped.appearance;
const color = colorProp ?? mapped.color;

// we do not want to spread tab index in this case because the button element
// does not require tabindex="0" attribute
Expand All @@ -101,8 +107,8 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
{
[withBaseName("disabled")]: disabled,
[withBaseName("active")]: active,
[withBaseName(`${resolvedAppearance}-${resolvedColor}`)]:
resolvedAppearance,
[withBaseName(appearance)]: appearance,
[withBaseName(color)]: color,
},
className,
)}
Expand Down
64 changes: 32 additions & 32 deletions packages/theme/css/characteristics/actionable.css
Original file line number Diff line number Diff line change
Expand Up @@ -45,35 +45,7 @@
--salt-actionable-secondary-borderColor-active: transparent;
--salt-actionable-secondary-borderColor-disabled: transparent;

/* saltButton-solid-neutral previous Primary */
--salt-actionable-bold-foreground: var(--salt-palette-interact-primary-foreground);
--salt-actionable-bold-foreground-hover: var(--salt-palette-interact-primary-foreground-hover);
--salt-actionable-bold-foreground-active: var(--salt-palette-interact-primary-foreground-active);
--salt-actionable-bold-foreground-disabled: var(--salt-palette-interact-primary-foreground-disabled);
--salt-actionable-bold-background: var(--salt-palette-interact-primary-background);
--salt-actionable-bold-background-hover: var(--salt-palette-interact-primary-background-hover);
--salt-actionable-bold-background-active: var(--salt-palette-interact-primary-background-active);
--salt-actionable-bold-background-disabled: var(--salt-palette-interact-primary-background-disabled);
--salt-actionable-bold-borderColor: transparent;
--salt-actionable-bold-borderColor-hover: transparent;
--salt-actionable-bold-borderColor-active: transparent;
--salt-actionable-bold-borderColor-disabled: transparent;

/* saltButton-outline-neutral */
--salt-actionable-foreground: var(--salt-palette-foreground-primary);
--salt-actionable-foreground-hover: var(--salt-palette-interact-primary-foreground-hover);
--salt-actionable-foreground-active: var(--salt-palette-interact-primary-foreground-active);
--salt-actionable-foreground-disabled: var(--salt-palette-interact-primary-foreground-disabled);
--salt-actionable-background: transparent;
--salt-actionable-background-hover: var(--salt-palette-interact-primary-background-hover);
--salt-actionable-background-active: var(--salt-palette-interact-primary-background-active);
--salt-actionable-background-disabled: transparent;
--salt-actionable-borderColor: var(--salt-palette-neutral-primary-border);
--salt-actionable-borderColor-hover: var(--salt-palette-neutral-primary-border);
--salt-actionable-borderColor-active: var(--salt-palette-neutral-primary-border);
--salt-actionable-borderColor-disabled: var(--salt-palette-neutral-primary-border-disabled);

/* saltButton-solid-accent previous CTA */
/* Accent bold */
--salt-actionable-accent-bold-foreground: var(--salt-palette-interact-cta-foreground);
--salt-actionable-accent-bold-foreground-hover: var(--salt-palette-interact-cta-foreground-hover);
--salt-actionable-accent-bold-foreground-active: var(--salt-palette-interact-cta-foreground-active);
Expand All @@ -87,7 +59,21 @@
--salt-actionable-accent-bold-borderColor-active: transparent;
--salt-actionable-accent-bold-borderColor-disabled: transparent;

/* saltButton-outline-accent */
/* Neutral bold */
--salt-actionable-bold-foreground: var(--salt-palette-interact-primary-foreground);
--salt-actionable-bold-foreground-hover: var(--salt-palette-interact-primary-foreground-hover);
--salt-actionable-bold-foreground-active: var(--salt-palette-interact-primary-foreground-active);
--salt-actionable-bold-foreground-disabled: var(--salt-palette-interact-primary-foreground-disabled);
--salt-actionable-bold-background: var(--salt-palette-interact-primary-background);
--salt-actionable-bold-background-hover: var(--salt-palette-interact-primary-background-hover);
--salt-actionable-bold-background-active: var(--salt-palette-interact-primary-background-active);
--salt-actionable-bold-background-disabled: var(--salt-palette-interact-primary-background-disabled);
--salt-actionable-bold-borderColor: transparent;
--salt-actionable-bold-borderColor-hover: transparent;
--salt-actionable-bold-borderColor-active: transparent;
--salt-actionable-bold-borderColor-disabled: transparent;

/* Accent outline */
--salt-actionable-accent-foreground: var(--salt-palette-foreground-primary);
--salt-actionable-accent-foreground-hover: var(--salt-palette-interact-cta-foreground-hover);
--salt-actionable-accent-foreground-active: var(--salt-palette-interact-cta-foreground-active);
Expand All @@ -101,7 +87,21 @@
--salt-actionable-accent-borderColor-active: var(--salt-palette-accent-border);
--salt-actionable-accent-borderColor-disabled: var(--salt-palette-accent-border-disabled);

/* saltButton-transparent-accent */
/* Neutral outline */
--salt-actionable-foreground: var(--salt-palette-foreground-primary);
--salt-actionable-foreground-hover: var(--salt-palette-interact-primary-foreground-hover);
--salt-actionable-foreground-active: var(--salt-palette-interact-primary-foreground-active);
--salt-actionable-foreground-disabled: var(--salt-palette-interact-primary-foreground-disabled);
--salt-actionable-background: transparent;
--salt-actionable-background-hover: var(--salt-palette-interact-primary-background-hover);
--salt-actionable-background-active: var(--salt-palette-interact-primary-background-active);
--salt-actionable-background-disabled: transparent;
--salt-actionable-borderColor: var(--salt-palette-neutral-primary-border);
--salt-actionable-borderColor-hover: var(--salt-palette-neutral-primary-border);
--salt-actionable-borderColor-active: var(--salt-palette-neutral-primary-border);
--salt-actionable-borderColor-disabled: var(--salt-palette-neutral-primary-border-disabled);

/* Accent transparent */
--salt-actionable-accent-subtle-foreground: var(--salt-palette-foreground-primary);
--salt-actionable-accent-subtle-foreground-hover: var(--salt-palette-interact-cta-foreground-hover);
--salt-actionable-accent-subtle-foreground-active: var(--salt-palette-interact-cta-foreground-active);
Expand All @@ -115,7 +115,7 @@
--salt-actionable-accent-subtle-borderColor-active: var(--salt-palette-accent-border);
--salt-actionable-accent-subtle-borderColor-disabled: var(--salt-palette-interact-border-none);

/* saltButton-transparent-neutral previous Secondary */
/* Neutral transparent */
--salt-actionable-subtle-foreground: var(--salt-palette-interact-secondary-foreground);
--salt-actionable-subtle-foreground-hover: var(--salt-palette-interact-secondary-foreground-hover);
--salt-actionable-subtle-foreground-active: var(--salt-palette-interact-secondary-foreground-active);
Expand Down
74 changes: 53 additions & 21 deletions site/docs/components/button/examples.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,21 @@ data:
---

<LivePreviewControls>
<LivePreview componentName="button" exampleName="CTA" >
<LivePreview componentName="button" exampleName="Appearance">

## CTA

Use the CTA button for high-priority actions. For example, a CTA button may prompt a user to register, sign up, submit or buy.
## Appearance

### Best practices

Use CTA buttons sparingly. They represent the default or expected action on the page.
Button supports multiple visual styles; `"solid"`, `"outline"` and `"transparent"`. `"solid"` is the default appearance.

</LivePreview>

<LivePreview componentName="button" exampleName="Color">

<LivePreview componentName="button" exampleName="Primary" >
## Color

## Primary

This is the default variant. Use the primary button for routine, nonurgent actions, for example, to move to the next page or complete a task.
Button has a default color of `"neutral"`, it can be used for routine, nonurgent actions. You can use the `"accent"` color for high-priority actions or call-to-actions.

</LivePreview>

<LivePreview componentName="button" exampleName="Secondary" >

## Secondary

Use the secondary button for noncritical actions that support the user but don't impact a flow. They're typically the alternative option available alongside a primary action. For example, a secondary “back” button may support a primary “next” button.

</LivePreview>

<LivePreview componentName="button" exampleName="IconAndText">

## Icon and text
Expand Down Expand Up @@ -69,15 +56,60 @@ Display an icon-only button with no text when you have limited on-screen space,

Use the disabled state for a button that the user can’t press.

A button with the prop `disabled={true}` will suppress all functionality. If you need to allow the user to place focus on a disabled button, you also need to pass `focusableWhenDisabled={true}`.
A button with the prop `disabled={true}` will suppress all functionality.

</LivePreview>

<LivePreview componentName="button" exampleName="FocusableWhenDisabled" >

## Focusable when disabled

If you need to allow the user to place focus on a disabled button, you also need to pass `focusableWhenDisabled={true}`.

This is useful when you want to show a tooltip or a popover when the user hovers over the button.

</LivePreview>


<LivePreview componentName="button" exampleName="FullWidth" >

## Full width

Use full width buttons on mobile devices or smaller viewports, the button will take up the full width of its container.

</LivePreview>

<LivePreview componentName="button" exampleName="CTA" displayName="CTA - Deprecated" >

## CTA

_Note:_ The `variant` prop is deprecated. Use `appearance="solid"` and `color="accent"` instead.

Use the CTA button for high-priority actions. For example, a CTA button may prompt a user to register, sign up, submit or buy.

### Best practices

Use CTA buttons sparingly. They represent the default or expected action on the page.

</LivePreview>

<LivePreview componentName="button" exampleName="Primary" displayName="Primary - Deprecated" >

## Primary

_Note:_ The `variant` prop is deprecated. Use `appearance="solid"` and `color="neutral"` instead.

This is the default variant. Use the primary button for routine, nonurgent actions, for example, to move to the next page or complete a task.

</LivePreview>

<LivePreview componentName="button" exampleName="Secondary" displayName="Secondary - Deprecated" >

## Secondary

_Note:_ The `variant` prop is deprecated. Use `appearance="transparent"` and `color="neutral"` instead.

Use the secondary button for noncritical actions that support the user but don't impact a flow. They're typically the alternative option available alongside a primary action. For example, a secondary “back” button may support a primary “next” button.

</LivePreview>
</LivePreviewControls>
10 changes: 10 additions & 0 deletions site/src/examples/button/Appearance.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Button } from "@salt-ds/core";
import type { ReactElement } from "react";

export const Appearance = (): ReactElement => (
<>
<Button appearance="solid">Solid</Button>
<Button appearance="outline">Outline</Button>
<Button appearance="transparent">Transparent</Button>
</>
);
25 changes: 25 additions & 0 deletions site/src/examples/button/Color.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Button, GridLayout } from "@salt-ds/core";
import type { ReactElement } from "react";

export const Color = (): ReactElement => (
<GridLayout columns={3}>
<Button appearance="solid" color="neutral">
Solid
</Button>
<Button appearance="outline" color="neutral">
Outline
</Button>
<Button appearance="transparent" color="neutral">
Transparent
</Button>
<Button appearance="solid" color="accent">
Solid
</Button>
<Button appearance="outline" color="accent">
Outline
</Button>
<Button appearance="transparent" color="accent">
Transparent
</Button>
</GridLayout>
);
Loading

0 comments on commit 32157c3

Please sign in to comment.