2023-01-03 19:55:46 +00:00
|
|
|
// Copyright 2021 Signal Messenger, LLC
|
2021-06-01 20:45:43 +00:00
|
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
|
2021-10-26 19:15:33 +00:00
|
|
|
import type { ChangeEvent } from 'react';
|
2022-12-14 23:59:09 +00:00
|
|
|
import React, { useCallback } from 'react';
|
2021-06-01 20:45:43 +00:00
|
|
|
import classNames from 'classnames';
|
|
|
|
|
|
|
|
export type Option = Readonly<{
|
2021-08-05 12:35:33 +00:00
|
|
|
disabled?: boolean;
|
2021-06-01 20:45:43 +00:00
|
|
|
text: string;
|
|
|
|
value: string | number;
|
|
|
|
}>;
|
|
|
|
|
|
|
|
export type PropsType = Readonly<{
|
2022-04-07 21:40:57 +00:00
|
|
|
ariaLabel?: string;
|
2021-08-18 20:08:14 +00:00
|
|
|
disabled?: boolean;
|
2022-04-07 21:40:57 +00:00
|
|
|
id?: string;
|
2021-06-01 20:45:43 +00:00
|
|
|
moduleClassName?: string;
|
2021-08-18 20:08:14 +00:00
|
|
|
name?: string;
|
2021-06-01 20:45:43 +00:00
|
|
|
options: ReadonlyArray<Option>;
|
|
|
|
onChange(value: string): void;
|
2021-08-18 20:08:14 +00:00
|
|
|
value?: string | number;
|
2021-06-01 20:45:43 +00:00
|
|
|
}>;
|
|
|
|
|
2022-11-18 00:45:19 +00:00
|
|
|
export const Select = React.forwardRef(function SelectInner(
|
|
|
|
{
|
|
|
|
ariaLabel,
|
|
|
|
disabled,
|
|
|
|
id,
|
|
|
|
moduleClassName,
|
|
|
|
name,
|
|
|
|
onChange,
|
|
|
|
options,
|
|
|
|
value,
|
|
|
|
}: PropsType,
|
|
|
|
ref: React.Ref<HTMLSelectElement>
|
|
|
|
): JSX.Element {
|
2022-12-14 23:59:09 +00:00
|
|
|
const onSelectChange = useCallback(
|
|
|
|
(event: ChangeEvent<HTMLSelectElement>) => {
|
|
|
|
onChange(event.target.value);
|
|
|
|
},
|
|
|
|
[onChange]
|
|
|
|
);
|
2021-06-01 20:45:43 +00:00
|
|
|
|
2022-11-18 00:45:19 +00:00
|
|
|
return (
|
|
|
|
<div className={classNames(['module-select', moduleClassName])}>
|
|
|
|
<select
|
|
|
|
aria-label={ariaLabel}
|
|
|
|
disabled={disabled}
|
|
|
|
id={id}
|
|
|
|
name={name}
|
|
|
|
value={value}
|
|
|
|
onChange={onSelectChange}
|
|
|
|
ref={ref}
|
|
|
|
>
|
|
|
|
{options.map(
|
|
|
|
({ disabled: optionDisabled, text, value: optionValue }) => {
|
|
|
|
return (
|
|
|
|
<option
|
|
|
|
disabled={optionDisabled}
|
|
|
|
value={optionValue}
|
|
|
|
key={optionValue}
|
|
|
|
aria-label={text}
|
|
|
|
>
|
|
|
|
{text}
|
|
|
|
</option>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
)}
|
|
|
|
</select>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
});
|