101 lines
2.4 KiB
TypeScript
101 lines
2.4 KiB
TypeScript
// Copyright 2019-2020 @polkadot/extension-ui authors & contributors
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
import { ThemeProps } from '../types';
|
|
|
|
import React from 'react';
|
|
import styled from 'styled-components';
|
|
|
|
import arrow from '../assets/arrow-down.svg';
|
|
import Label from './Label';
|
|
|
|
interface DropdownOption {
|
|
text: string;
|
|
value: string;
|
|
}
|
|
|
|
interface Props extends ThemeProps {
|
|
className?: string;
|
|
defaultValue?: string | null;
|
|
isError?: boolean;
|
|
isFocussed?: boolean;
|
|
label: string;
|
|
onBlur?: () => void;
|
|
onChange?: (value: string) => void;
|
|
options: DropdownOption[];
|
|
value?: string;
|
|
}
|
|
|
|
function Dropdown ({ className, defaultValue, isFocussed, label, onBlur, onChange, options, value }: Props): React.ReactElement<Props> {
|
|
const _onChange = ({ target: { value } }: React.ChangeEvent<HTMLSelectElement>): void => {
|
|
onChange && onChange(value.trim());
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<Label
|
|
className={className}
|
|
label={label}
|
|
>
|
|
<select
|
|
autoFocus={isFocussed}
|
|
defaultValue={defaultValue || undefined}
|
|
onBlur={onBlur}
|
|
onChange={_onChange}
|
|
value={value}
|
|
>
|
|
{options.map(({ text, value }): React.ReactNode => (
|
|
<option
|
|
key={value}
|
|
value={value}
|
|
>
|
|
{text}
|
|
</option>
|
|
))}
|
|
</select>
|
|
</Label>
|
|
</>
|
|
);
|
|
}
|
|
|
|
export default React.memo(styled(Dropdown)(({ isError, theme }: Props) => `
|
|
position: relative;
|
|
|
|
select {
|
|
-webkit-appearance: none;
|
|
-moz-appearance: none;
|
|
appearance: none;
|
|
background: ${theme.readonlyInputBackground};
|
|
border-color: ${isError ? theme.errorBorderColor : theme.inputBorderColor};
|
|
border-radius: ${theme.borderRadius};
|
|
border-style: solid;
|
|
border-width: 1px;
|
|
box-sizing: border-box;
|
|
color: ${isError ? theme.errorBorderColor : theme.textColor};
|
|
display: block;
|
|
font-family: ${theme.fontFamily};
|
|
font-size: ${theme.fontSize};
|
|
font-weight: 600;
|
|
padding: 0.5rem 0.75rem;
|
|
width: 100%;
|
|
cursor: pointer;
|
|
|
|
&:read-only {
|
|
box-shadow: none;
|
|
outline: none;
|
|
}
|
|
}
|
|
|
|
label::after {
|
|
content: '';
|
|
position: absolute;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
right: 12px;
|
|
width: 8px;
|
|
height: 6px;
|
|
background: url(${arrow}) center no-repeat;
|
|
pointer-events: none;
|
|
}
|
|
`));
|