Skip to content

Commit 7b0e2ce

Browse files
committed
Button styling cleanup, prop consistency
1 parent 7dd74ec commit 7b0e2ce

File tree

9 files changed

+119
-44
lines changed

9 files changed

+119
-44
lines changed

resources/scripts/components/elements/button/Button.tsx

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
11
import React, { forwardRef } from 'react';
22
import classNames from 'classnames';
3+
import { ButtonProps, Options } from '@/components/elements/button/types';
34
import styles from './style.module.css';
45

5-
export type ButtonProps = JSX.IntrinsicElements['button'] & {
6-
square?: boolean;
7-
small?: boolean;
8-
}
9-
106
const Button = forwardRef<HTMLButtonElement, ButtonProps>(
11-
({ children, square, small, className, ...rest }, ref) => {
7+
({ children, shape, size, variant, className, ...rest }, ref) => {
128
return (
139
<button
1410
ref={ref}
15-
className={classNames(styles.button, { [styles.square]: square, [styles.small]: small }, className)}
11+
className={classNames(
12+
styles.button,
13+
styles.primary,
14+
{
15+
[styles.secondary]: variant === Options.Variant.Secondary,
16+
[styles.square]: shape === Options.Shape.IconSquare,
17+
[styles.small]: size === Options.Size.Small,
18+
[styles.large]: size === Options.Size.Large,
19+
},
20+
className,
21+
)}
1622
{...rest}
1723
>
1824
{children}
@@ -31,6 +37,12 @@ const DangerButton = forwardRef<HTMLButtonElement, ButtonProps>(({ className, ..
3137
<Button ref={ref} className={classNames(styles.danger, className)} {...props} />
3238
));
3339

34-
const _Button = Object.assign(Button, { Text: TextButton, Danger: DangerButton });
40+
const _Button = Object.assign(Button, {
41+
Sizes: Options.Size,
42+
Shapes: Options.Shape,
43+
Variants: Options.Variant,
44+
Text: TextButton,
45+
Danger: DangerButton,
46+
});
3547

3648
export default _Button;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
export { ButtonProps } from './types';
12
export { default as Button } from './Button';
23
export { default as styles } from './style.module.css';
Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,73 @@
11
.button {
22
@apply px-4 py-2 inline-flex items-center justify-center;
3-
@apply bg-blue-600 rounded text-base font-semibold text-blue-50 transition-all duration-100;
4-
@apply hover:bg-blue-500 active:bg-blue-500;
3+
@apply rounded text-base font-semibold transition-all duration-100;
4+
@apply focus:ring-[3px] focus:ring-offset-2 focus:ring-offset-gray-700 focus:ring-opacity-50;
55

6-
&.square {
7-
@apply p-2;
6+
/* Sizing Controls */
7+
&.small {
8+
@apply px-4 py-1 font-normal text-sm focus:ring-2;
89
}
910

10-
&:focus {
11-
@apply ring-[3px] ring-blue-500 ring-offset-2 ring-offset-neutral-700;
11+
&.large {
12+
@apply px-5 py-3;
1213
}
1314

14-
/* Sizing Controls */
15-
&.small {
16-
@apply px-3 py-1 font-normal focus:ring-2;
15+
&.secondary {
16+
@apply text-gray-50 bg-transparent;
1717

18-
&.square {
19-
@apply p-1;
18+
&:disabled {
19+
@apply bg-transparent;
2020
}
2121
}
2222

2323
&:disabled {
2424
@apply cursor-not-allowed;
2525
}
26+
27+
&.square {
28+
@apply p-0 w-12 h-12;
29+
30+
&.small {
31+
@apply w-8 h-8;
32+
}
33+
}
34+
}
35+
36+
.primary {
37+
@apply bg-blue-600 text-blue-50;
38+
@apply hover:bg-blue-500 active:bg-blue-500 focus:ring-blue-400 focus:ring-opacity-75;
39+
40+
&.secondary {
41+
@apply hover:bg-blue-600 active:bg-blue-600;
42+
}
43+
44+
&:disabled {
45+
@apply bg-blue-500/75 text-blue-200/75;
46+
}
2647
}
2748

2849
.text {
29-
@apply text-gray-50 bg-transparent focus:ring-neutral-300 focus:ring-opacity-50 hover:bg-neutral-500 active:bg-neutral-500;
50+
@apply bg-gray-500 text-gray-50;
51+
@apply hover:bg-gray-400 active:bg-gray-400 focus:ring-gray-300 focus:ring-opacity-50;
52+
53+
&.secondary {
54+
@apply hover:bg-gray-500 active:bg-gray-500;
55+
}
3056

3157
&:disabled {
32-
@apply hover:bg-transparent text-gray-300;
58+
@apply bg-gray-500/75 text-gray-200/75;
3359
}
3460
}
3561

3662
.danger {
37-
@apply bg-red-600 hover:bg-red-500 active:bg-red-500 focus:ring-red-500 text-red-50;
63+
@apply bg-red-600 text-gray-50;
64+
@apply hover:bg-red-500 active:bg-red-500 focus:ring-red-400 focus:ring-opacity-75;
65+
66+
&.secondary {
67+
@apply hover:bg-red-600 active:bg-red-600;
68+
}
69+
70+
&:disabled {
71+
@apply bg-red-600/75 text-red-50/75;
72+
}
3873
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
enum Shape {
2+
Default,
3+
IconSquare,
4+
}
5+
6+
enum Size {
7+
Default,
8+
Small,
9+
Large,
10+
}
11+
12+
enum Variant {
13+
Primary,
14+
Secondary,
15+
}
16+
17+
export const Options = { Shape, Size, Variant };
18+
19+
export type ButtonProps = JSX.IntrinsicElements['button'] & {
20+
shape?: Shape;
21+
size?: Size;
22+
variant?: Variant;
23+
}

resources/scripts/components/elements/dialog/Dialog.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,12 @@ const Dialog = ({ open, title, description, onClose, hideCloseIcon, children }:
7878
{/* Keep this below the other buttons so that it isn't the default focus if they're present. */}
7979
{!hideCloseIcon &&
8080
<div className={'absolute right-0 top-0 m-4'}>
81-
<Button.Text square small onClick={onClose} className={'hover:rotate-90'}>
81+
<Button.Text
82+
size={Button.Sizes.Small}
83+
shape={Button.Shapes.IconSquare}
84+
onClick={onClose}
85+
className={'hover:rotate-90'}
86+
>
8287
<XIcon className={'w-5 h-5'}/>
8388
</Button.Text>
8489
</div>

resources/scripts/components/elements/table/PaginationFooter.tsx

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ const PaginationFooter = ({ pagination, className, onPageSelect }: Props) => {
3030
return null;
3131
}
3232

33+
const buttonProps = (page: number) => ({
34+
size: Button.Sizes.Small,
35+
shape: Button.Shapes.IconSquare,
36+
variant: Button.Variants.Secondary,
37+
onClick: () => onPageSelect(page),
38+
});
39+
3340
return (
3441
<div className={classNames('flex items-center justify-between my-2', className)}>
3542
<p className={'text-sm text-neutral-500'}>
@@ -42,21 +49,21 @@ const PaginationFooter = ({ pagination, className, onPageSelect }: Props) => {
4249
</p>
4350
{pagination.totalPages > 1 &&
4451
<div className={'flex space-x-1'}>
45-
<Button.Text small disabled={pages.previous.length !== 2} onClick={() => onPageSelect(1)}>
52+
<Button.Text {...buttonProps(1)} disabled={pages.previous.length !== 2}>
4653
<ChevronDoubleLeftIcon className={'w-3 h-3'}/>
4754
</Button.Text>
4855
{pages.previous.reverse().map((value) => (
49-
<Button.Text small key={`previous-${value}`} onClick={() => onPageSelect(value)}>
56+
<Button.Text key={`previous-${value}`} {...buttonProps(value)}>
5057
{value}
5158
</Button.Text>
5259
))}
53-
<Button small disabled>{current}</Button>
60+
<Button size={Button.Sizes.Small} shape={Button.Shapes.IconSquare}>{current}</Button>
5461
{pages.next.map((value) => (
55-
<Button.Text small key={`next-${value}`} onClick={() => onPageSelect(value)}>
62+
<Button.Text key={`next-${value}`} {...buttonProps(value)}>
5663
{value}
5764
</Button.Text>
5865
))}
59-
<Button.Text small disabled={pages.next.length !== 2} onClick={() => onPageSelect(total)}>
66+
<Button.Text {...buttonProps(total)} disabled={pages.next.length !== 2}>
6067
<ChevronDoubleRightIcon className={'w-3 h-3'}/>
6168
</Button.Text>
6269
</div>

resources/scripts/components/server/settings/ReinstallServerBox.tsx

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { Actions, useStoreActions } from 'easy-peasy';
66
import { ApplicationStore } from '@/state';
77
import { httpErrorToHuman } from '@/api/http';
88
import tw from 'twin.macro';
9-
import Button from '@/components/elements/Button';
9+
import { Button } from '@/components/elements/button/index';
1010
import { Dialog } from '@/components/elements/dialog';
1111

1212
export default () => {
@@ -57,14 +57,9 @@ export default () => {
5757
</strong>
5858
</p>
5959
<div css={tw`mt-6 text-right`}>
60-
<Button
61-
type={'button'}
62-
color={'red'}
63-
isSecondary
64-
onClick={() => setModalVisible(true)}
65-
>
60+
<Button.Danger variant={Button.Variants.Secondary} onClick={() => setModalVisible(true)}>
6661
Reinstall Server
67-
</Button>
62+
</Button.Danger>
6863
</div>
6964
</TitledGreyBox>
7065
);

resources/scripts/components/server/settings/RenameServerBox.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { object, string } from 'yup';
99
import SpinnerOverlay from '@/components/elements/SpinnerOverlay';
1010
import { ApplicationStore } from '@/state';
1111
import { httpErrorToHuman } from '@/api/http';
12-
import Button from '@/components/elements/Button';
12+
import { Button } from '@/components/elements/button/index';
1313
import tw from 'twin.macro';
1414

1515
interface Values {

resources/scripts/components/server/settings/SettingsContainer.tsx

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ import ReinstallServerBox from '@/components/server/settings/ReinstallServerBox'
99
import tw from 'twin.macro';
1010
import Input from '@/components/elements/Input';
1111
import Label from '@/components/elements/Label';
12-
import { LinkButton } from '@/components/elements/Button';
1312
import ServerContentBlock from '@/components/elements/ServerContentBlock';
1413
import isEqual from 'react-fast-compare';
1514
import CopyOnClick from '@/components/elements/CopyOnClick';
1615
import { formatIp } from '@/helpers';
16+
import { Button } from '@/components/elements/button/index';
1717

1818
export default () => {
1919
const username = useStoreState(state => state.user.data!.username);
@@ -58,12 +58,9 @@ export default () => {
5858
</div>
5959
</div>
6060
<div css={tw`ml-4`}>
61-
<LinkButton
62-
isSecondary
63-
href={`sftp://${username}.${id}@${formatIp(sftp.ip)}:${sftp.port}`}
64-
>
65-
Launch SFTP
66-
</LinkButton>
61+
<a href={`sftp://${username}.${id}@${formatIp(sftp.ip)}:${sftp.port}`}>
62+
<Button.Text variant={Button.Variants.Secondary}>Launch SFTP</Button.Text>
63+
</a>
6764
</div>
6865
</div>
6966
</TitledGreyBox>

0 commit comments

Comments
 (0)