Skip to content

Commit de3eba4

Browse files
feat(mantine, button): update style (#4052)
feat(mantine, button): create new variants feat(mantine, button): use StaticComponents feat(website, button): update all examples using buttons feat(website): change primary color to teal, add it in the picker
1 parent 5023f4f commit de3eba4

35 files changed

+150
-128
lines changed

packages/mantine/src/components/button/Button.tsx

+32-6
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ type ButtonOverloadFactory = Factory<{
2626
variant: ButtonVariant;
2727
staticComponents: {
2828
Group: typeof ButtonGroup;
29+
Primary: typeof ButtonPrimary;
30+
Secondary: typeof ButtonSecondary;
31+
Tertiary: typeof ButtonTertiary;
32+
Quaternary: typeof ButtonQuaternary;
33+
DestructivePrimary: typeof ButtonDestructive;
34+
DestructiveSecondary: typeof ButtonDestructiveSecondary;
35+
DestructiveTertiary: typeof ButtonDestructiveTertiary;
36+
DestructiveQuaternary: typeof ButtonDestructiveQuaternary;
2937
};
3038
}>;
3139

@@ -55,10 +63,28 @@ export const Button = polymorphicFactory<ButtonOverloadFactory>(
5563
);
5664
},
5765
);
58-
Button.Group = MantineButton.Group;
66+
const ButtonPrimary = Button.withProps({variant: 'filled'});
67+
const ButtonSecondary = Button.withProps({variant: 'light'});
68+
const ButtonTertiary = Button.withProps({
69+
variant: 'default',
70+
vars: () => ({root: {'--button-color': 'var(--mantine-primary-color-filled)'}}),
71+
});
72+
const ButtonQuaternary = Button.withProps({variant: 'subtle'});
73+
74+
const ButtonDestructive = Button.withProps({variant: 'filled', color: 'var(--mantine-color-error)'});
75+
const ButtonDestructiveSecondary = Button.withProps({variant: 'light', color: 'var(--mantine-color-error)'});
76+
const ButtonDestructiveTertiary = Button.withProps({
77+
variant: 'default',
78+
vars: () => ({root: {'--button-color': 'var(--mantine-color-error)'}}),
79+
});
80+
const ButtonDestructiveQuaternary = Button.withProps({variant: 'subtle', color: 'var(--mantine-color-error)'});
5981

60-
export const ButtonPrimary = Button.withProps({variant: 'filled'});
61-
export const ButtonSecondary = Button.withProps({variant: 'light'});
62-
export const ButtonTertiary = Button.withProps({variant: 'subtle'});
63-
export const ButtonDestructive = Button.withProps({variant: 'filled', color: 'var(--mantine-color-error)'});
64-
export const ButtonDestructiveSecondary = Button.withProps({variant: 'light', color: 'var(--mantine-color-error)'});
82+
Button.Group = MantineButton.Group;
83+
Button.Primary = ButtonPrimary;
84+
Button.Secondary = ButtonSecondary;
85+
Button.Tertiary = ButtonTertiary;
86+
Button.Quaternary = ButtonQuaternary;
87+
Button.DestructivePrimary = ButtonDestructive;
88+
Button.DestructiveSecondary = ButtonDestructiveSecondary;
89+
Button.DestructiveTertiary = ButtonDestructiveTertiary;
90+
Button.DestructiveQuaternary = ButtonDestructiveQuaternary;

packages/mantine/src/components/collection/Collection.tsx

+2-3
Original file line numberDiff line numberDiff line change
@@ -256,14 +256,13 @@ export const Collection = <T,>(props: CollectionProps<T> & {ref?: ForwardedRef<H
256256
<Group>
257257
<Tooltip label={addDisabledTooltip} disabled={addAllowed}>
258258
<Box>
259-
<Button
260-
variant="subtle"
259+
<Button.Quaternary
261260
leftSection={<AddSize16Px height={16} />}
262261
onClick={() => onInsertItem(newItem, value?.length ?? 0)}
263262
disabled={!addAllowed}
264263
>
265264
{addLabel}
266-
</Button>
265+
</Button.Quaternary>
267266
</Box>
268267
</Tooltip>
269268
</Group>

packages/mantine/src/components/date-range-picker/DateRangePickerInlineCalendar.tsx

+2-6
Original file line numberDiff line numberDiff line change
@@ -117,12 +117,8 @@ export const DateRangePickerInlineCalendar = ({
117117
</Center>
118118

119119
<Group justify="right" gap="xs" px="md" py="sm" className={DateRangeClasses.save}>
120-
<Button variant="outline" size="xs" onClick={onCancel}>
121-
Cancel
122-
</Button>
123-
<Button size="xs" onClick={onCalendarApply}>
124-
Apply
125-
</Button>
120+
<Button.Tertiary onClick={onCancel}>Cancel</Button.Tertiary>
121+
<Button.Primary onClick={onCalendarApply}>Apply</Button.Primary>
126122
</Group>
127123
</>
128124
);

packages/mantine/src/components/inline-confirm/InlineConfirmPrompt.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ interface InlineConfirmPromptProps extends Omit<GroupProps, 'children'>, InlineC
1515
/**
1616
* Confirm button element
1717
*
18-
* @default <Button color="red">Delete</Button>
18+
* @default <Button.DestructivePrimary>Delete</Button.DestructivePrimary>
1919
*/
2020
confirm?: ReactElement;
2121
/**
2222
* Cancel button element
2323
*
24-
* @default <Button variant="outline">Cancel</Button>
24+
* @default <Button.Tertiary>Cancel</Button.Tertiary>
2525
*/
2626
cancel?: ReactElement;
2727
/**
@@ -42,8 +42,8 @@ export type InlineConfirmPromptFactory = Factory<{
4242

4343
const defaultProps: Partial<InlineConfirmPromptProps> = {
4444
label: 'Are you sure?',
45-
confirm: <Button color="red">Delete</Button>,
46-
cancel: <Button variant="outline">Cancel</Button>,
45+
confirm: <Button.DestructivePrimary>Delete</Button.DestructivePrimary>,
46+
cancel: <Button.Tertiary>Cancel</Button.Tertiary>,
4747
gap: 'xs',
4848
wrap: 'nowrap',
4949
};

packages/mantine/src/components/prompt/PromptCancelButton.tsx

+3-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import {Button, CompoundStylesApiProps, factory, Factory, useProps} from '@mantine/core';
2-
import {ButtonProps} from '../button/Button';
1+
import {CompoundStylesApiProps, factory, Factory, useProps} from '@mantine/core';
2+
import {Button, ButtonProps} from '../button/Button';
33
import {usePromptContext} from './Prompt.context';
44

55
export type PromptCancelButtonStylesNamesVariant = 'cancel';
@@ -22,12 +22,5 @@ export const PromptCancelButton = factory<PromptCancelButtonFactory>((_props, re
2222
const props = useProps('PromptCancelButton', defaultProps, _props);
2323
const {className, classNames, style, styles, unstyled, vars, ...others} = props;
2424

25-
return (
26-
<Button
27-
ref={ref}
28-
variant="outline"
29-
{...others}
30-
{...getStyles('cancel', {style, styles, className, classNames})}
31-
/>
32-
);
25+
return <Button.Tertiary ref={ref} {...others} {...getStyles('cancel', {style, styles, className, classNames})} />;
3326
});

packages/mantine/src/components/prompt/PromptConfirmButton.tsx

+14-10
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import {CompoundStylesApiProps, factory, Factory, useProps} from '@mantine/core';
1+
import {CompoundStylesApiProps, factory, Factory, PolymorphicComponentProps, useProps} from '@mantine/core';
2+
import {JSXElementConstructor, ReactElement} from 'react';
23
import {Button, ButtonProps} from '../button/Button';
34
import {PromptVariant} from './Prompt';
45
import {usePromptContext} from './Prompt.context';
@@ -16,11 +17,16 @@ export type PromptConfirmButtonFactory = Factory<{
1617
compound: true;
1718
}>;
1819

19-
const COLOR_BY_VARIANT: Record<PromptVariant, string> = {
20-
success: 'var(--mantine-primary-color-filled)',
21-
info: 'var(--mantine-primary-color-filled)',
22-
warning: 'var(--mantine-color-error)',
23-
critical: 'var(--mantine-color-error)',
20+
const COMPONENT_BY_VARIANT: Record<
21+
PromptVariant,
22+
<L = 'button'>(
23+
props: PolymorphicComponentProps<L, ButtonProps>,
24+
) => ReactElement<any, string | JSXElementConstructor<any>>
25+
> = {
26+
success: Button.Primary,
27+
info: Button.Primary,
28+
warning: Button.DestructivePrimary,
29+
critical: Button.DestructivePrimary,
2430
};
2531

2632
const defaultProps: Partial<PromptConfirmButtonProps> = {};
@@ -40,12 +46,10 @@ export const PromptConfirmButton = factory<PromptConfirmButtonFactory>((_props,
4046
disabledTooltipProps,
4147
...others
4248
} = props;
43-
49+
const Component = COMPONENT_BY_VARIANT[variant];
4450
return (
45-
<Button
51+
<Component
4652
ref={ref}
47-
variant="filled"
48-
color={COLOR_BY_VARIANT[variant]}
4953
disabled={disabled}
5054
disabledTooltip={disabledTooltip}
5155
disabledTooltipProps={disabledTooltipProps}

packages/mantine/src/components/table/table-actions/TableActionItem.tsx

+2-3
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,14 @@ export const TableActionItem = polymorphicFactory<TableActionItemFactory>(
5454

5555
if (primary) {
5656
return (
57-
<Button
57+
<Button.Quaternary
5858
component={component}
5959
ref={ref}
60-
variant="subtle"
6160
{...others}
6261
{...getStyles('actionItemRoot', {className, style, classNames, styles})}
6362
>
6463
{children}
65-
</Button>
64+
</Button.Quaternary>
6665
);
6766
}
6867

packages/mantine/src/components/table/table-actions/TableActionsList.tsx

+4-5
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@ import {MoreSize16Px} from '@coveord/plasma-react-icons';
22
import {
33
ActionIcon,
44
Box,
5-
Button,
6-
CSSProperties,
75
CompoundStylesApiProps,
6+
CSSProperties,
87
ExtendComponent,
98
Factory,
109
Menu,
@@ -13,6 +12,7 @@ import {
1312
useProps,
1413
} from '@mantine/core';
1514
import {MouseEventHandler, ReactNode, useState} from 'react';
15+
import {Button} from '../../button';
1616
import {InlineConfirm} from '../../inline-confirm';
1717
import {TableAction} from '../Table.types';
1818
import {useTableContext} from '../TableContext';
@@ -131,13 +131,12 @@ export const TableActionsList = (props: TableActionsListProps) => {
131131
<TableActionProvider value={{primary: false}}>
132132
<Menu withinPortal={false} {...others} keepMounted>
133133
<Menu.Target>
134-
<Button
134+
<Button.Quaternary
135135
{...getStyles('actionsTarget', {styles, classNames})}
136-
variant="subtle"
137136
leftSection={icon}
138137
>
139138
{label}
140-
</Button>
139+
</Button.Quaternary>
141140
</Menu.Target>
142141
<Menu.Dropdown {...getStyles('actionsDropdown', {styles, classNames})}>
143142
<ActionsGroupsMenuItems

packages/mantine/src/components/table/table-header/TableHeader.tsx

+2-3
Original file line numberDiff line numberDiff line change
@@ -73,14 +73,13 @@ export const TableHeader = factory<TableHeaderFactory>((props, ref) => {
7373
order={TableComponentsOrder.MultiSelectInfo}
7474
>
7575
<Tooltip label={unselectAllLabel}>
76-
<Button
76+
<Button.Quaternary
7777
onClick={store.clearRowSelection}
78-
variant="subtle"
7978
disabled={!store.rowSelectionEnabled}
8079
leftSection={<CrossSize16Px height={16} />}
8180
>
8281
{selectedCountLabel(selectedRows.length)}
83-
</Button>
82+
</Button.Quaternary>
8483
</Tooltip>
8584
</Grid.Col>
8685
) : null}

packages/mantine/src/styles/Alert.module.css

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
font-weight: 500;
33
}
44

5+
.icon {
6+
margin-inline-end: var(--mantine-spacing-sm);
7+
}
8+
59
.closeButton {
610
& svg {
711
width: 20px;
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
11
.label {
22
font-weight: 500;
33
}
4+
5+
.root {
6+
&[data-variant='subtle'] {
7+
&:where(:disabled:not([data-loading]), [data-disabled]:not([data-loading])) {
8+
background: transparent;
9+
}
10+
}
11+
}

packages/website/src/App.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ interface PlatformAppThemeProps {
4141
}
4242

4343
export const PlatformAppTheme: FunctionComponent<PlatformAppThemeProps> = ({children}) => {
44-
const [primaryColor, setPrimaryColor] = useState<DefaultMantineColor>('blue');
44+
const [primaryColor, setPrimaryColor] = useState<DefaultMantineColor>('teal');
4545
const PlasmaWebsiteTheme = useMemo(
4646
() =>
4747
createTheme({

packages/website/src/TopBar.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ const ColorSchemePicker = () => {
5252

5353
const PrimaryColorPicker = () => (
5454
<Group gap="xs">
55+
<ColorPickerSwatch color="teal" />
5556
<ColorPickerSwatch color="blue" />
5657
<ColorPickerSwatch color="violet" />
5758
</Group>

packages/website/src/examples/form/button/Button.demo.tsx

+9-15
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,20 @@
1-
import {
2-
ButtonDestructive,
3-
ButtonDestructiveSecondary,
4-
ButtonPrimary,
5-
ButtonSecondary,
6-
ButtonTertiary,
7-
Group,
8-
showNotification,
9-
Stack,
10-
} from '@coveord/plasma-mantine';
1+
import {Button, Group, showNotification, Stack} from '@coveord/plasma-mantine';
112

123
const Demo = () => {
134
const onClick = () => showNotification({message: 'Button clicked', autoClose: false});
145
return (
156
<Stack gap="sm">
167
<Group gap="sm">
17-
<ButtonPrimary onClick={onClick}>Primary</ButtonPrimary>
18-
<ButtonSecondary onClick={onClick}>Secondary</ButtonSecondary>
19-
<ButtonTertiary onClick={onClick}>Tertiary</ButtonTertiary>
8+
<Button.Primary onClick={onClick}>Button</Button.Primary>
9+
<Button.Secondary onClick={onClick}>Button</Button.Secondary>
10+
<Button.Tertiary onClick={onClick}>Button</Button.Tertiary>
11+
<Button.Quaternary onClick={onClick}>Button</Button.Quaternary>
2012
</Group>
2113
<Group gap="sm">
22-
<ButtonDestructive onClick={onClick}>Destructive</ButtonDestructive>
23-
<ButtonDestructiveSecondary onClick={onClick}>Destructive secondary</ButtonDestructiveSecondary>
14+
<Button.DestructivePrimary onClick={onClick}>Button</Button.DestructivePrimary>
15+
<Button.DestructiveSecondary onClick={onClick}>Button</Button.DestructiveSecondary>
16+
<Button.DestructiveTertiary onClick={onClick}>Button</Button.DestructiveTertiary>
17+
<Button.DestructiveQuaternary onClick={onClick}>Button</Button.DestructiveQuaternary>
2418
</Group>
2519
</Stack>
2620
);

packages/website/src/examples/form/button/ButtonDestructive.demo.tsx

-8
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,38 @@
1-
import {Button} from '@coveord/plasma-mantine';
1+
import {Button, Group, Stack} from '@coveord/plasma-mantine';
22

3-
const Demo = () => (
4-
<Button disabled disabledTooltip="This button is disabled" onClick={() => alert('button clicked')}>
5-
Disabled button
6-
</Button>
7-
);
3+
const Demo = () => {
4+
const onClick = () => alert("This won't work because the button is disabled");
5+
return (
6+
<Stack gap="sm">
7+
<Group gap="sm">
8+
<Button.Primary disabled disabledTooltip="This button is disabled" onClick={onClick}>
9+
Button
10+
</Button.Primary>
11+
<Button.Secondary disabled disabledTooltip="This button is disabled" onClick={onClick}>
12+
Button
13+
</Button.Secondary>
14+
<Button.Tertiary disabled disabledTooltip="This button is disabled" onClick={onClick}>
15+
Button
16+
</Button.Tertiary>
17+
<Button.Quaternary disabled disabledTooltip="This button is disabled" onClick={onClick}>
18+
Button
19+
</Button.Quaternary>
20+
</Group>
21+
<Group gap="sm">
22+
<Button.DestructivePrimary disabled disabledTooltip="This button is disabled" onClick={onClick}>
23+
Button
24+
</Button.DestructivePrimary>
25+
<Button.DestructiveSecondary disabled disabledTooltip="This button is disabled" onClick={onClick}>
26+
Button
27+
</Button.DestructiveSecondary>
28+
<Button.DestructiveTertiary disabled disabledTooltip="This button is disabled" onClick={onClick}>
29+
Button
30+
</Button.DestructiveTertiary>
31+
<Button.DestructiveQuaternary disabled disabledTooltip="This button is disabled" onClick={onClick}>
32+
Button
33+
</Button.DestructiveQuaternary>
34+
</Group>
35+
</Stack>
36+
);
37+
};
838
export default Demo;

packages/website/src/examples/form/button/ButtonSecondary.demo.tsx

-6
This file was deleted.

packages/website/src/examples/form/button/ButtonWithAsyncLoader.demo.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ const promise = async () => {
1515
};
1616

1717
const Demo = () => (
18-
<Button loading loaderProps={{type: 'oval'}} onClick={promise}>
18+
<Button.Primary loading onClick={promise}>
1919
Save
20-
</Button>
20+
</Button.Primary>
2121
);
2222
export default Demo;

0 commit comments

Comments
 (0)