Skip to content

Commit

Permalink
feat: Refactor button component (#1065)
Browse files Browse the repository at this point in the history
Co-authored-by: Aram <[email protected]>
  • Loading branch information
dlnr and alimpens authored Feb 13, 2024
1 parent 0245886 commit c9984e3
Show file tree
Hide file tree
Showing 11 changed files with 148 additions and 294 deletions.
70 changes: 61 additions & 9 deletions packages/css/src/components/button/button.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,94 @@
* Copyright (c) 2023 Gemeente Amsterdam
*/

@import "../../../node_modules/@utrecht/components/button/css";

@mixin reset {
-webkit-text-size-adjust: 100%;
}

.amsterdam-button {
border: none;
cursor: var(--amsterdam-button-cursor);
display: inline-flex;
font-family: var(--amsterdam-button-font-family);
font-size: var(--amsterdam-button-font-size);
gap: var(--amsterdam-button-gap);
line-height: var(--amsterdam-button-line-height);
outline-offset: var(--amsterdam-button-outline-offset);
padding-block-end: var(--amsterdam-button-padding-block-end);
padding-block-start: var(--amsterdam-button-padding-block-start);
padding-inline-end: var(--amsterdam-button-padding-inline-end);
padding-inline-start: var(--amsterdam-button-padding-inline-start);
touch-action: manipulation;

&:disabled,
&[aria-disabled="true"] {
cursor: var(--amsterdam-button-disabled-cursor);
}

@include reset;
}

@mixin amsterdam-button-forced-color-mode {
@media screen and (-ms-high-contrast: active), screen and (forced-colors: active) {
border: 2px solid ButtonBorder; // add border because forced colors changes box-shadow to none
}
}

.amsterdam-button--busy {
cursor: var(--amsterdam-button-busy-cursor);
}

.amsterdam-button--primary {
background-color: var(--amsterdam-button-primary-background-color);
box-shadow: var(--amsterdam-button-primary-box-shadow);
color: var(--amsterdam-button-primary-color);

&:disabled,
[aria-disabled="true"] {
background-color: var(--amsterdam-button-primary-disabled-background-color);
box-shadow: var(--amsterdam-button-primary-disabled-box-shadow);
}

&:hover:not(:disabled, [aria-disabled="true"]) {
background-color: var(--amsterdam-button-primary-hover-background-color);
box-shadow: var(--amsterdam-button-primary-hover-box-shadow);
}

@include amsterdam-button-forced-color-mode;
}

.amsterdam-button--secondary {
background-color: var(--amsterdam-button-secondary-background-color);
box-shadow: var(--amsterdam-button-secondary-box-shadow);
color: var(--amsterdam-button-secondary-color);

&:disabled,
[aria-disabled="true"] {
background-color: var(--amsterdam-button-secondary-disabled-background-color);
box-shadow: var(--amsterdam-button-secondary-disabled-box-shadow);
color: var(--amsterdam-button-secondary-disabled-color);
}

&:hover:not(:disabled, [aria-disabled="true"]) {
box-shadow: var(--amsterdam-button-secondary-hover-box-shadow);
color: var(--amsterdam-button-secondary-hover-color);
}
}

.amsterdam-button--secondary:focus:not(:hover, [aria-disabled="true"]) {
box-shadow: var(--amsterdam-button-secondary-focus-box-shadow);
@include amsterdam-button-forced-color-mode;
}

.amsterdam-button--tertiary {
background-color: var(--amsterdam-button-tertiary-background-color);
color: var(--amsterdam-button-tertiary-color);

&:disabled,
[aria-disabled="true"] {
background-color: var(--amsterdam-button-tertiary-disabled-background-color);
color: var(--amsterdam-button-tertiary-disabled-color);
}

&:hover:not(:disabled, [aria-disabled="true"]) {
box-shadow: var(--amsterdam-button-tertiary-hover-box-shadow);
color: var(--amsterdam-button-tertiary-hover-color);
}
}

.amsterdam-button--tertiary:focus:not(:hover, [aria-disabled="true"]) {
box-shadow: none;
}
1 change: 0 additions & 1 deletion packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
],
"dependencies": {
"@amsterdam/design-system-react-icons": "workspace:*",
"@utrecht/component-library-react": "3.0.0",
"clsx": "2.1.0"
},
"devDependencies": {
Expand Down
8 changes: 4 additions & 4 deletions packages/react/src/Button/Button.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ describe('Button', () => {

expect(button).toBeInTheDocument()
expect(button).toHaveAttribute('type', 'button')
expect(button).toHaveClass('utrecht-button--primary-action')
expect(button).toHaveClass('amsterdam-button--primary')
})

it('renders a button with a specified variant', () => {
Expand All @@ -49,11 +49,11 @@ describe('Button', () => {
})

expect(buttonPrimary).toBeInTheDocument()
expect(buttonPrimary).toHaveClass('utrecht-button--primary-action')
expect(buttonPrimary).toHaveClass('amsterdam-button--primary')
expect(buttonSecondary).toBeInTheDocument()
expect(buttonSecondary).toHaveClass('utrecht-button--secondary-action')
expect(buttonSecondary).toHaveClass('amsterdam-button--secondary')
expect(buttonTertiary).toBeInTheDocument()
expect(buttonTertiary).toHaveClass('utrecht-button--subtle')
expect(buttonTertiary).toHaveClass('amsterdam-button--tertiary')
})

it('renders a disabled button with a specified variant', () => {
Expand Down
37 changes: 12 additions & 25 deletions packages/react/src/Button/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,47 +1,34 @@
/**
* @license EUPL-1.2+
* Copyright (c) 2021 Robbert Broersma
* Copyright (c) 2023 Gemeente Amsterdam
* Copyright (c) 2024 Gemeente Amsterdam
*/

import { Button as CommunityButton } from '@utrecht/component-library-react'
import clsx from 'clsx'
import { forwardRef } from 'react'
import type { ButtonHTMLAttributes, ForwardedRef, PropsWithChildren } from 'react'

export type ButtonProps = {
variant?: 'primary' | 'secondary' | 'tertiary'
/** Render the button in a busy state to indicate something has to finish loading */
busy?: boolean
} & PropsWithChildren<ButtonHTMLAttributes<HTMLButtonElement>>

type CommunityButtonAppearance = 'primary-action-button' | 'secondary-action-button' | 'subtle-button'

function getAppearance(variant: ButtonProps['variant']): CommunityButtonAppearance {
switch (variant) {
case 'secondary':
return 'secondary-action-button'
case 'tertiary':
return 'subtle-button'
default:
return 'primary-action-button'
}
}

export const Button = forwardRef(
({ children, disabled, variant = 'primary', ...restProps }: ButtonProps, ref: ForwardedRef<HTMLButtonElement>) => {
(
{ children, type, disabled, busy, variant = 'primary', ...restProps }: ButtonProps,
ref: ForwardedRef<HTMLButtonElement>,
) => {
return (
<CommunityButton
<button
{...restProps}
appearance={getAppearance(variant)}
ref={ref}
disabled={disabled}
className={clsx(
'amsterdam-button',
variant === 'secondary' && 'amsterdam-button--secondary',
variant === 'tertiary' && 'amsterdam-button--tertiary',
)}
className={clsx('amsterdam-button', busy === true && 'amsterdam-button--busy', `amsterdam-button--${variant}`)}
type={type || 'button'}
aria-busy={busy || undefined}
>
{children}
</CommunityButton>
</button>
)
},
)
Expand Down
29 changes: 0 additions & 29 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"utrecht": {
"amsterdam": {
"action": {
"activate": { "cursor": { "value": "pointer" } },
"busy": { "cursor": { "value": "wait" } },
Expand Down
7 changes: 0 additions & 7 deletions proprietary/tokens/src/common/utrecht/focus.tokens.json

This file was deleted.

45 changes: 42 additions & 3 deletions proprietary/tokens/src/components/amsterdam/button.tokens.json
Original file line number Diff line number Diff line change
@@ -1,23 +1,62 @@
{
"amsterdam": {
"button": {
"cursor": { "value": "{amsterdam.action.activate.cursor}" },
"font-family": { "value": "{amsterdam.typography.font-family}" },
"font-size": { "value": "{amsterdam.typography.text-level.5.font-size}" },
"line-height": { "value": "{amsterdam.typography.text-level.5.line-height}" },
"gap": { "value": "1rem" },
"padding-inline-start": { "value": "1rem" },
"padding-inline-end": { "value": "1rem" },
"padding-block-start": { "value": "0.5rem" },
"padding-block-end": { "value": "0.5rem" },
"outline-offset": { "value": "{amsterdam.focus.outline-offset}" },
"busy": {
"cursor": { "value": "{amsterdam.action.busy.cursor}" }
},
"disabled": {
"cursor": { "value": "{amsterdam.action.disabled.cursor}" }
},
"primary": {
"background-color": { "value": "{amsterdam.color.primary-blue}" },
"box-shadow": { "value": "inset 0 0 0 2px {amsterdam.color.primary-blue}" },
"color": { "value": "{amsterdam.color.primary-white}" },
"disabled": {
"background-color": { "value": "{amsterdam.color.neutral-grey2}" },
"box-shadow": { "value": "inset 0 0 0 2px {amsterdam.color.neutral-grey2}" }
},
"hover": {
"background-color": { "value": "{amsterdam.color.dark-blue}" },
"box-shadow": { "value": "inset 0 0 0 2px {amsterdam.color.dark-blue}" }
}
},
"secondary": {
"background-color": { "value": "{amsterdam.color.primary-white}" },
"color": { "value": "{amsterdam.color.primary-blue}" },
"box-shadow": { "value": "inset 0 0 0 2px {amsterdam.color.primary-blue}" },
"hover": {
"box-shadow": { "value": "inset 0 0 0 3px {amsterdam.color.dark-blue}" }
"box-shadow": { "value": "inset 0 0 0 3px {amsterdam.color.dark-blue}" },
"color": { "value": "{amsterdam.color.dark-blue}" }
},
"disabled": {
"box-shadow": { "value": "inset 0 0 0 2px {amsterdam.color.neutral-grey2}" }
"background-color": { "value": "{amsterdam.color.primary-white}" },
"box-shadow": { "value": "inset 0 0 0 2px {amsterdam.color.neutral-grey2}" },
"color": { "value": "{amsterdam.color.neutral-grey2}" }
},
"focus": {
"box-shadow": { "value": "inset 0 0 0 2px {amsterdam.color.primary-blue}" }
}
},
"tertiary": {
"background-color": { "value": "transparent" },
"color": { "value": "{amsterdam.color.primary-blue}" },
"hover": {
"box-shadow": { "value": "inset 0 0 0 2px {amsterdam.color.dark-blue}" }
"box-shadow": { "value": "inset 0 0 0 2px {amsterdam.color.dark-blue}" },
"color": { "value": "{amsterdam.color.dark-blue}" }
},
"disabled": {
"background-color": { "value": "transparent" },
"color": { "value": "{amsterdam.color.neutral-grey2}" }
}
}
}
Expand Down
Loading

0 comments on commit c9984e3

Please sign in to comment.