diff options
| author | Oskar Nyberg <oskar@mullvad.net> | 2024-01-16 13:45:32 +0100 |
|---|---|---|
| committer | Oskar Nyberg <oskar@mullvad.net> | 2024-01-29 09:33:49 +0100 |
| commit | e5cfedffc08ccdcf7f703b2ae8e565ccc7407295 (patch) | |
| tree | 1f2909d9db0ab53755c7f57c90c265bfdc133141 /gui/src | |
| parent | 7a16c4b1fd1b210699dbeb8d72c64ebda9e55251 (diff) | |
| download | mullvadvpn-e5cfedffc08ccdcf7f703b2ae8e565ccc7407295.tar.xz mullvadvpn-e5cfedffc08ccdcf7f703b2ae8e565ccc7407295.zip | |
Add small button component
Diffstat (limited to 'gui/src')
| -rw-r--r-- | gui/src/renderer/components/Modal.tsx | 23 | ||||
| -rw-r--r-- | gui/src/renderer/components/SmallButton.tsx | 88 |
2 files changed, 105 insertions, 6 deletions
diff --git a/gui/src/renderer/components/Modal.tsx b/gui/src/renderer/components/Modal.tsx index 60b7dd1473..64e92daa95 100644 --- a/gui/src/renderer/components/Modal.tsx +++ b/gui/src/renderer/components/Modal.tsx @@ -10,6 +10,7 @@ import { measurements, tinyText } from './common-styles'; import CustomScrollbars from './CustomScrollbars'; import ImageView from './ImageView'; import { BackAction } from './KeyboardNavigation'; +import { SmallButtonGrid } from './SmallButton'; const MODAL_CONTAINER_ID = 'modal-container'; @@ -147,6 +148,10 @@ const ModalAlertButtonGroupContainer = styled.div({ marginTop: measurements.buttonVerticalMargin, }); +const StyledSmallButtonGrid = styled(SmallButtonGrid)({ + marginRight: '16px', +}); + const ModalAlertButtonContainer = styled.div({ display: 'flex', flexDirection: 'column', @@ -157,7 +162,8 @@ interface IModalAlertProps { type?: ModalAlertType; iconColor?: string; message?: string | Array<string>; - buttons: React.ReactNode[]; + buttons?: React.ReactNode[]; + gridButtons?: React.ReactNode[]; children?: React.ReactNode; close?: () => void; } @@ -277,11 +283,16 @@ class ModalAlertImpl extends React.Component<IModalAlertImplProps, IModalAlertSt </StyledCustomScrollbars> <ModalAlertButtonGroupContainer> - <AppButton.ButtonGroup> - {this.props.buttons.map((button, index) => ( - <ModalAlertButtonContainer key={index}>{button}</ModalAlertButtonContainer> - ))} - </AppButton.ButtonGroup> + {this.props.gridButtons && ( + <StyledSmallButtonGrid>{this.props.gridButtons}</StyledSmallButtonGrid> + )} + {this.props.buttons && ( + <AppButton.ButtonGroup> + {this.props.buttons.map((button, index) => ( + <ModalAlertButtonContainer key={index}>{button}</ModalAlertButtonContainer> + ))} + </AppButton.ButtonGroup> + )} </ModalAlertButtonGroupContainer> </StyledModalAlert> </ModalAlertContainer> diff --git a/gui/src/renderer/components/SmallButton.tsx b/gui/src/renderer/components/SmallButton.tsx new file mode 100644 index 0000000000..181a557fd2 --- /dev/null +++ b/gui/src/renderer/components/SmallButton.tsx @@ -0,0 +1,88 @@ +import React from 'react'; +import styled from 'styled-components'; + +import { colors } from '../../config.json'; +import { smallText } from './common-styles'; + +export enum SmallButtonColor { + blue, + red, +} + +function getButtonColors(color?: SmallButtonColor, disabled?: boolean) { + switch (color) { + case SmallButtonColor.red: + return { + background: disabled ? colors.red60 : colors.red, + backgroundHover: disabled ? colors.red60 : colors.red80, + }; + default: + return { + background: disabled ? colors.blue50 : colors.blue, + backgroundHover: disabled ? colors.blue50 : colors.blue60, + }; + } +} + +const StyledSmallButton = styled.button<{ $color?: SmallButtonColor; disabled?: boolean }>( + smallText, + (props) => { + const buttonColors = getButtonColors(props.$color, props.disabled); + return { + height: '32px', + padding: '5px 16px', + border: 'none', + background: buttonColors.background, + color: props.disabled ? colors.white50 : colors.white, + borderRadius: '4px', + marginLeft: '12px', + + [`${StyledSmallButtonGrid} &&`]: { + marginLeft: 0, + }, + + '&&:hover': { + background: buttonColors.backgroundHover, + }, + }; + }, +); + +interface SmallButtonProps + extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'onClick' | 'color'> { + onClick: () => void; + children: string; + color?: SmallButtonColor; +} + +export function SmallButton(props: SmallButtonProps) { + const { color, ...otherProps } = props; + return <StyledSmallButton $color={props.color} {...otherProps} />; +} + +export const SmallButtonGroup = styled.div<{ $noMarginTop?: boolean }>((props) => ({ + display: 'flex', + justifyContent: 'end', + margin: '0 23px', + marginTop: props.$noMarginTop ? 0 : '30px', +})); + +const StyledSmallButtonGrid = styled.div<{ $columns: number }>((props) => ({ + display: 'grid', + gridTemplateColumns: `repeat(${props.$columns}, 1fr)`, + gridColumnGap: '10px', +})); + +interface SmallButtonGridProps { + className?: string; +} + +export function SmallButtonGrid(props: React.PropsWithChildren<SmallButtonGridProps>) { + return ( + <StyledSmallButtonGrid + $columns={React.Children.count(props.children)} + className={props.className}> + {props.children} + </StyledSmallButtonGrid> + ); +} |
