summaryrefslogtreecommitdiffhomepage
path: root/gui/src/renderer
diff options
context:
space:
mode:
authorOskar Nyberg <oskar@mullvad.net>2022-07-24 14:15:12 +0200
committerOskar Nyberg <oskar@mullvad.net>2022-07-26 13:08:56 +0200
commite4a7323b6cb045a23839740a4fdfc33864337f1c (patch)
tree80d8cf6ff6a0f9518c28dd79a0e224b1279266ec /gui/src/renderer
parent8199bc6c1e6f9ac6ecd114a62eb2e6f759357a8e (diff)
downloadmullvadvpn-e4a7323b6cb045a23839740a4fdfc33864337f1c.tar.xz
mullvadvpn-e4a7323b6cb045a23839740a4fdfc33864337f1c.zip
Add support for new appearances to Selector
Diffstat (limited to 'gui/src/renderer')
-rw-r--r--gui/src/renderer/components/Filter.tsx4
-rw-r--r--gui/src/renderer/components/SelectLanguage.tsx4
-rw-r--r--gui/src/renderer/components/cell/Section.tsx15
-rw-r--r--gui/src/renderer/components/cell/Selector.tsx90
4 files changed, 77 insertions, 36 deletions
diff --git a/gui/src/renderer/components/Filter.tsx b/gui/src/renderer/components/Filter.tsx
index 86e0d2dbb3..79253ed7b0 100644
--- a/gui/src/renderer/components/Filter.tsx
+++ b/gui/src/renderer/components/Filter.tsx
@@ -174,9 +174,9 @@ function providersSelector(state: IReduxState): Record<string, boolean> {
);
}
-const StyledSelector = (styled(Selector)({
+const StyledSelector = styled(Selector)({
marginBottom: 0,
-}) as unknown) as new <T>() => Selector<T>;
+}) as typeof Selector;
interface IFilterByOwnershipProps {
ownership: Ownership;
diff --git a/gui/src/renderer/components/SelectLanguage.tsx b/gui/src/renderer/components/SelectLanguage.tsx
index 86d0c8166f..419557f700 100644
--- a/gui/src/renderer/components/SelectLanguage.tsx
+++ b/gui/src/renderer/components/SelectLanguage.tsx
@@ -31,9 +31,9 @@ const StyledNavigationScrollbars = styled(NavigationScrollbars)({
flex: 1,
});
-const StyledSelector = (styled(Selector)({
+const StyledSelector = styled(Selector)({
marginBottom: 0,
-}) as unknown) as new <T>() => Selector<T>;
+}) as typeof Selector;
export default class SelectLanguage extends React.Component<IProps, IState> {
private scrollView = React.createRef<CustomScrollbarsRef>();
diff --git a/gui/src/renderer/components/cell/Section.tsx b/gui/src/renderer/components/cell/Section.tsx
index 1c1779248f..83c179d3cc 100644
--- a/gui/src/renderer/components/cell/Section.tsx
+++ b/gui/src/renderer/components/cell/Section.tsx
@@ -2,20 +2,29 @@ import React from 'react';
import styled from 'styled-components';
import { colors } from '../../../config.json';
-import { buttonText } from '../common-styles';
+import { buttonText, openSans, sourceSansPro } from '../common-styles';
const StyledSection = styled.div({
display: 'flex',
flexDirection: 'column',
});
-export const SectionTitle = styled.span(buttonText, {
+interface SectionTitleProps {
+ disabled?: boolean;
+ thin?: boolean;
+}
+
+export const SectionTitle = styled.span(buttonText, (props: SectionTitleProps) => ({
display: 'flex',
minHeight: '44px',
alignItems: 'center',
backgroundColor: colors.blue,
padding: '0 16px 0 22px',
-});
+ color: props.disabled ? colors.white20 : colors.white,
+ fontWeight: props.thin ? 400 : 600,
+ fontSize: props.thin ? '15px' : '18px',
+ ...(props.thin ? openSans : sourceSansPro),
+}));
export const CellSectionContext = React.createContext<boolean>(false);
diff --git a/gui/src/renderer/components/cell/Selector.tsx b/gui/src/renderer/components/cell/Selector.tsx
index ea2abb90ef..e815519552 100644
--- a/gui/src/renderer/components/cell/Selector.tsx
+++ b/gui/src/renderer/components/cell/Selector.tsx
@@ -2,10 +2,28 @@ import * as React from 'react';
import styled from 'styled-components';
import { colors } from '../../../config.json';
-import { AriaInput, AriaLabel } from '../AriaGroup';
+import { useBoolean } from '../../lib/utilityHooks';
+import Accordion from '../Accordion';
+import { AriaDetails, AriaInput, AriaLabel } from '../AriaGroup';
+import ChevronButton from '../ChevronButton';
import { normalText } from '../common-styles';
+import InfoButton from '../InfoButton';
import * as Cell from '.';
+const StyledTitle = styled(Cell.Container)({
+ display: 'flex',
+ padding: 0,
+});
+
+const StyledTitleLabel = styled(Cell.SectionTitle)({
+ flex: 1,
+});
+
+const StyledChevronButton = styled(ChevronButton)({
+ padding: 0,
+ marginRight: '16px',
+});
+
export interface ISelectorItem<T> {
label: string;
value: T;
@@ -19,41 +37,55 @@ interface ISelectorProps<T> {
onSelect: (value: T) => void;
selectedCellRef?: React.Ref<HTMLButtonElement>;
className?: string;
+ details?: React.ReactElement;
+ expandable?: boolean;
+ disabled?: boolean;
+ thinTitle?: boolean;
}
-export default class Selector<T> extends React.Component<ISelectorProps<T>> {
- public render() {
- const items = this.props.values.map((item, i) => {
- const selected = item.value === this.props.value;
+export default function Selector<T>(props: ISelectorProps<T>) {
+ const [expanded, , , toggleExpanded] = useBoolean(!props.expandable);
- return (
- <SelectorCell
- key={i}
- value={item.value}
- selected={selected}
- disabled={item.disabled}
- forwardedRef={selected ? this.props.selectedCellRef : undefined}
- onSelect={this.props.onSelect}>
- {item.label}
- </SelectorCell>
- );
- });
+ const items = props.values.map((item, i) => {
+ const selected = item.value === props.value;
- const title = this.props.title && (
+ return (
+ <SelectorCell
+ key={i}
+ value={item.value}
+ selected={selected}
+ disabled={props.disabled || item.disabled}
+ forwardedRef={selected ? props.selectedCellRef : undefined}
+ onSelect={props.onSelect}>
+ {item.label}
+ </SelectorCell>
+ );
+ });
+
+ const title = props.title && (
+ <StyledTitle>
<AriaLabel>
- <Cell.SectionTitle as="label">{this.props.title}</Cell.SectionTitle>
+ <StyledTitleLabel as="label" disabled={props.disabled} thin={props.thinTitle}>
+ {props.title}
+ </StyledTitleLabel>
</AriaLabel>
- );
+ {props.details && (
+ <AriaDetails>
+ <InfoButton>{props.details}</InfoButton>
+ </AriaDetails>
+ )}
+ {props.expandable && <StyledChevronButton up={expanded} onClick={toggleExpanded} />}
+ </StyledTitle>
+ );
- return (
- <AriaInput>
- <Cell.Section role="listbox" className={this.props.className}>
- {title}
- {items}
- </Cell.Section>
- </AriaInput>
- );
- }
+ return (
+ <AriaInput>
+ <Cell.Section role="listbox" className={props.className}>
+ {title}
+ {props.expandable ? <Accordion expanded={expanded}>{items}</Accordion> : items}
+ </Cell.Section>
+ </AriaInput>
+ );
}
const StyledCellIcon = styled(Cell.Icon)((props: { visible: boolean }) => ({