Improve Button styles

Signed-off-by: Charles de Dreuille <charles.dedreuille@gmail.com>
This commit is contained in:
Charles de Dreuille
2025-12-23 08:52:55 +01:00
parent 591d8a2483
commit e727a9441e
8 changed files with 201 additions and 36 deletions
File diff suppressed because one or more lines are too long
+32 -8
View File
@@ -59,10 +59,22 @@
--bui-bg-solid-hover: #163a66;
--bui-bg-solid-pressed: #0f2b4e;
--bui-bg-solid-disabled: #ebebeb;
--bui-bg-tint: transparent;
--bui-bg-tint-hover: #1f549366;
--bui-bg-tint-pressed: #1f549399;
--bui-bg-tint-disabled: #ebebeb;
--bui-bg-neutral-on-surface-0: oklch(0% 0 0 / .06);
--bui-bg-neutral-on-surface-0-hover: oklch(0% 0 0 / .12);
--bui-bg-neutral-on-surface-0-pressed: oklch(0% 0 0 / .16);
--bui-bg-neutral-on-surface-0-disabled: oklch(0% 0 0 / .06);
--bui-bg-neutral-on-surface-1: oklch(0% 0 0 / .06);
--bui-bg-neutral-on-surface-1-hover: oklch(0% 0 0 / .12);
--bui-bg-neutral-on-surface-1-pressed: oklch(0% 0 0 / .16);
--bui-bg-neutral-on-surface-1-disabled: oklch(0% 0 0 / .06);
--bui-bg-neutral-on-surface-2: oklch(0% 0 0 / .06);
--bui-bg-neutral-on-surface-2-hover: oklch(0% 0 0 / .12);
--bui-bg-neutral-on-surface-2-pressed: oklch(0% 0 0 / .16);
--bui-bg-neutral-on-surface-2-disabled: oklch(0% 0 0 / .06);
--bui-bg-neutral-on-surface-3: oklch(0% 0 0 / .06);
--bui-bg-neutral-on-surface-3-hover: oklch(0% 0 0 / .12);
--bui-bg-neutral-on-surface-3-pressed: oklch(0% 0 0 / .16);
--bui-bg-neutral-on-surface-3-disabled: oklch(0% 0 0 / .06);
--bui-bg-danger: #feebe7;
--bui-bg-warning: #fff2b2;
--bui-bg-success: #e6f6eb;
@@ -108,10 +120,22 @@
--bui-bg-solid-hover: #83b9fd;
--bui-bg-solid-pressed: #83b9fd;
--bui-bg-solid-disabled: #222;
--bui-bg-tint: transparent;
--bui-bg-tint-hover: #9cc9ff1f;
--bui-bg-tint-pressed: #9cc9ff29;
--bui-bg-tint-disabled: transparent;
--bui-bg-neutral-on-surface-0: oklch(100% 0 0 / .1);
--bui-bg-neutral-on-surface-0-hover: oklch(100% 0 0 / .14);
--bui-bg-neutral-on-surface-0-pressed: oklch(100% 0 0 / .2);
--bui-bg-neutral-on-surface-0-disabled: oklch(100% 0 0 / .1);
--bui-bg-neutral-on-surface-1: oklch(100% 0 0 / .06);
--bui-bg-neutral-on-surface-1-hover: oklch(100% 0 0 / .1);
--bui-bg-neutral-on-surface-1-pressed: oklch(100% 0 0 / .16);
--bui-bg-neutral-on-surface-1-disabled: oklch(100% 0 0 / .06);
--bui-bg-neutral-on-surface-2: oklch(100% 0 0 / .08);
--bui-bg-neutral-on-surface-2-hover: oklch(100% 0 0 / .12);
--bui-bg-neutral-on-surface-2-pressed: oklch(100% 0 0 / .2);
--bui-bg-neutral-on-surface-2-disabled: oklch(100% 0 0 / .08);
--bui-bg-neutral-on-surface-3: oklch(100% 0 0 / .08);
--bui-bg-neutral-on-surface-3-hover: oklch(100% 0 0 / .12);
--bui-bg-neutral-on-surface-3-pressed: oklch(100% 0 0 / .2);
--bui-bg-neutral-on-surface-3-disabled: oklch(100% 0 0 / .08);
--bui-bg-danger: #3b1219;
--bui-bg-warning: #302008;
--bui-bg-success: #132d21;
+1
View File
@@ -323,6 +323,7 @@ export interface ButtonProps extends ButtonProps_2 {
iconStart?: ReactElement;
// (undocumented)
loading?: boolean;
onSurface?: Responsive<Surface>;
// (undocumented)
size?: 'small' | 'medium' | Partial<Record<Breakpoint, 'small' | 'medium'>>;
// (undocumented)
@@ -381,11 +381,11 @@ export const SurfacesNested = meta.story({
inherit the surface from the parent.
</Box>
<Box {...args} surface="1">
<Button>Button</Button>
<Button variant="secondary">Button</Button>
<Box {...args} surface="2" mt="4">
<Button>Button</Button>
<Button variant="secondary">Button</Button>
<Box {...args} mt="4">
<Button>Button</Button>
<Button variant="secondary">Button</Button>
</Box>
</Box>
</Box>
@@ -31,6 +31,7 @@
flex-shrink: 0;
transition: background-color var(--loading-duration) ease-out,
box-shadow var(--loading-duration) ease-out;
background-color: transparent;
&[data-disabled='true'] {
cursor: not-allowed;
@@ -67,17 +68,58 @@
}
.bui-Button[data-variant='secondary'] {
background-color: var(--bui-bg-surface-1);
box-shadow: inset 0 0 0 1px var(--bui-border);
color: var(--bui-fg-primary);
&:hover {
box-shadow: inset 0 0 0 1px var(--bui-border-hover);
transition: box-shadow 150ms ease;
&[data-surface='0'] {
background-color: var(--bui-bg-neutral-on-surface-0);
&:hover {
background-color: var(--bui-bg-neutral-on-surface-0-hover);
}
&:active {
background-color: var(--bui-bg-neutral-on-surface-0-pressed);
}
}
&:active {
box-shadow: inset 0 0 0 1px var(--bui-border-pressed);
&[data-surface='1'] {
background-color: var(--bui-bg-neutral-on-surface-1);
&:hover {
background-color: var(--bui-bg-neutral-on-surface-1-hover);
}
&:active {
background-color: var(--bui-bg-neutral-on-surface-1-pressed);
}
}
&[data-surface='2'] {
background-color: var(--bui-bg-neutral-on-surface-2);
&:hover {
background-color: var(--bui-bg-neutral-on-surface-2-hover);
}
&:active {
background-color: var(--bui-bg-neutral-on-surface-2-pressed);
}
}
&[data-surface='3'] {
background-color: var(--bui-bg-neutral-on-surface-3);
&:hover {
background-color: var(--bui-bg-neutral-on-surface-3-hover);
}
&:active {
background-color: var(--bui-bg-neutral-on-surface-3-pressed);
}
}
&:hover {
transition: background-color 150ms ease;
}
&:focus-visible {
@@ -97,13 +139,48 @@
background-color: transparent;
color: var(--bui-fg-primary);
&:hover {
background-color: var(--bui-bg-surface-1);
transition: background-color 200ms ease;
&[data-surface='0'] {
&:hover {
background-color: var(--bui-bg-neutral-on-surface-0-hover);
}
&:active {
background-color: var(--bui-bg-neutral-on-surface-0-pressed);
}
}
&:active {
background-color: var(--bui-bg-surface-2);
&[data-surface='1'] {
&:hover {
background-color: var(--bui-bg-neutral-on-surface-1-hover);
}
&:active {
background-color: var(--bui-bg-neutral-on-surface-1-pressed);
}
}
&[data-surface='2'] {
&:hover {
background-color: var(--bui-bg-neutral-on-surface-2-hover);
}
&:active {
background-color: var(--bui-bg-neutral-on-surface-2-pressed);
}
}
&[data-surface='3'] {
&:hover {
background-color: var(--bui-bg-neutral-on-surface-3-hover);
}
&:active {
background-color: var(--bui-bg-neutral-on-surface-3-pressed);
}
}
&:hover {
transition: background-color 200ms ease;
}
&:focus-visible {
@@ -53,16 +53,63 @@ export const Variants = meta.story({
},
},
render: () => (
<Flex align="center">
<Button iconStart={<RiCloudLine />} variant="primary">
Button
</Button>
<Button iconStart={<RiCloudLine />} variant="secondary">
Button
</Button>
<Button iconStart={<RiCloudLine />} variant="tertiary">
Button
</Button>
<Flex direction="column" gap="4">
<Flex direction="column" gap="4">
<Text>On Surface 0</Text>
<Flex align="center" surface="0" p="4">
<Button iconStart={<RiCloudLine />} variant="primary">
Button
</Button>
<Button iconStart={<RiCloudLine />} variant="secondary">
Button
</Button>
<Button iconStart={<RiCloudLine />} variant="tertiary">
Button
</Button>
</Flex>
</Flex>
<Flex direction="column" gap="4">
<Text>On Surface 1</Text>
<Flex align="center" surface="1" p="4">
<Button iconStart={<RiCloudLine />} variant="primary">
Button
</Button>
<Button iconStart={<RiCloudLine />} variant="secondary">
Button
</Button>
<Button iconStart={<RiCloudLine />} variant="tertiary">
Button
</Button>
</Flex>
</Flex>
<Flex direction="column" gap="4">
<Text>On Surface 2</Text>
<Flex align="center" surface="2" p="4">
<Button iconStart={<RiCloudLine />} variant="primary">
Button
</Button>
<Button iconStart={<RiCloudLine />} variant="secondary">
Button
</Button>
<Button iconStart={<RiCloudLine />} variant="tertiary">
Button
</Button>
</Flex>
</Flex>
<Flex direction="column" gap="4">
<Text>On Surface 3</Text>
<Flex align="center" surface="3" p="4">
<Button iconStart={<RiCloudLine />} variant="primary">
Button
</Button>
<Button iconStart={<RiCloudLine />} variant="secondary">
Button
</Button>
<Button iconStart={<RiCloudLine />} variant="tertiary">
Button
</Button>
</Flex>
</Flex>
</Flex>
),
});
+15 -2
View File
@@ -22,6 +22,7 @@ import type { ButtonProps } from './types';
import { useStyles } from '../../hooks/useStyles';
import { ButtonDefinition } from './definition';
import styles from './Button.module.css';
import { useSurface } from '../../hooks/useSurface';
/** @public */
export const Button = forwardRef(
@@ -35,8 +36,19 @@ export const Button = forwardRef(
},
);
const { children, className, iconStart, iconEnd, loading, ...rest } =
cleanedProps;
const {
children,
className,
iconStart,
iconEnd,
loading,
onSurface,
...rest
} = cleanedProps;
const { surface } = useSurface();
const surfaceToUse = onSurface || surface;
return (
<RAButton
@@ -44,6 +56,7 @@ export const Button = forwardRef(
ref={ref}
isPending={loading}
{...dataAttributes}
{...(surfaceToUse ? { 'data-surface': surfaceToUse } : {})}
{...rest}
>
{({ isPending }) => (
@@ -17,6 +17,7 @@
import { Breakpoint } from '../..';
import { ReactElement, ReactNode } from 'react';
import { ButtonProps as RAButtonProps } from 'react-aria-components';
import { Responsive, Surface } from '../../types';
/**
* Properties for {@link Button}
@@ -34,4 +35,6 @@ export interface ButtonProps extends RAButtonProps {
iconEnd?: ReactElement;
children?: ReactNode;
loading?: boolean;
/** Surface the button is placed on. Defaults to context surface if available */
onSurface?: Responsive<Surface>;
}