diff options
| author | Oskar Nyberg <oskar@mullvad.net> | 2022-07-24 14:15:12 +0200 |
|---|---|---|
| committer | Oskar Nyberg <oskar@mullvad.net> | 2022-07-26 13:08:56 +0200 |
| commit | e4a7323b6cb045a23839740a4fdfc33864337f1c (patch) | |
| tree | 80d8cf6ff6a0f9518c28dd79a0e224b1279266ec /gui | |
| parent | 8199bc6c1e6f9ac6ecd114a62eb2e6f759357a8e (diff) | |
| download | mullvadvpn-e4a7323b6cb045a23839740a4fdfc33864337f1c.tar.xz mullvadvpn-e4a7323b6cb045a23839740a4fdfc33864337f1c.zip | |
Add support for new appearances to Selector
Diffstat (limited to 'gui')
| -rw-r--r-- | gui/src/renderer/components/Filter.tsx | 4 | ||||
| -rw-r--r-- | gui/src/renderer/components/SelectLanguage.tsx | 4 | ||||
| -rw-r--r-- | gui/src/renderer/components/cell/Section.tsx | 15 | ||||
| -rw-r--r-- | gui/src/renderer/components/cell/Selector.tsx | 90 |
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 }) => ({ |
