summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOskar Nyberg <oskar@mullvad.net>2024-01-16 13:45:32 +0100
committerOskar Nyberg <oskar@mullvad.net>2024-01-29 09:33:49 +0100
commite5cfedffc08ccdcf7f703b2ae8e565ccc7407295 (patch)
tree1f2909d9db0ab53755c7f57c90c265bfdc133141
parent7a16c4b1fd1b210699dbeb8d72c64ebda9e55251 (diff)
downloadmullvadvpn-e5cfedffc08ccdcf7f703b2ae8e565ccc7407295.tar.xz
mullvadvpn-e5cfedffc08ccdcf7f703b2ae8e565ccc7407295.zip
Add small button component
-rw-r--r--gui/src/renderer/components/Modal.tsx23
-rw-r--r--gui/src/renderer/components/SmallButton.tsx88
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>
+ );
+}