ghost-keychain/packages/extension-ui/src/components/Dropdown.tsx
Jaco 6bfddb09e8
Use .js imports in src (#1224)
* Use .js imports in src

* Bump dev

* Add WP extension aliases
2023-03-09 11:04:13 +02:00

104 lines
2.5 KiB
TypeScript

// Copyright 2019-2023 @polkadot/extension-ui authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { ThemeProps } from '../types.js';
import React, { useCallback } from 'react';
import arrow from '../assets/arrow-down.svg';
import { styled } from '../styled.js';
import Label from './Label.js';
interface DropdownOption {
text: string;
value: string;
}
interface Props extends ThemeProps {
className?: string;
defaultValue?: string | null;
isDisabled?: boolean
isError?: boolean;
isFocussed?: boolean;
label: string;
onBlur?: () => void;
onChange?: (value: string) => void;
options: DropdownOption[];
value?: string;
}
function Dropdown ({ className, defaultValue, isDisabled, isFocussed, label, onBlur, onChange, options, value }: Props): React.ReactElement<Props> {
const _onChange = useCallback(
({ target: { value } }: React.ChangeEvent<HTMLSelectElement>) =>
onChange && onChange(value.trim()),
[onChange]
);
return (
<>
<Label
className={className}
label={label}
>
<select
autoFocus={isFocussed}
defaultValue={defaultValue || undefined}
disabled={isDisabled}
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, label, 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};
padding: 0.5rem 0.75rem;
width: 100%;
cursor: pointer;
&:read-only {
box-shadow: none;
outline: none;
}
}
label::after {
content: '';
position: absolute;
top: ${label ? 'calc(50% + 14px)' : '50%'};
transform: translateY(-50%);
right: 12px;
width: 8px;
height: 6px;
background: url(${arrow}) center no-repeat;
pointer-events: none;
}
`));