mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-12 21:23:45 +01:00
107 lines
2.8 KiB
TypeScript
107 lines
2.8 KiB
TypeScript
import OLFormGroup from '@/features/ui/components/ol/ol-form-group'
|
|
import OLFormLabel from '@/features/ui/components/ol/ol-form-label'
|
|
import OLFormSelect from '@/features/ui/components/ol/ol-form-select'
|
|
import { ChangeEventHandler, useCallback, useRef } from 'react'
|
|
import { Spinner } from 'react-bootstrap-5'
|
|
|
|
type PossibleValue = string | number | boolean
|
|
|
|
export type Option<T extends PossibleValue = string> = {
|
|
value: T
|
|
label: string
|
|
ariaHidden?: 'true' | 'false'
|
|
disabled?: boolean
|
|
}
|
|
|
|
export type Optgroup<T extends PossibleValue = string> = {
|
|
label: string
|
|
options: Array<Option<T>>
|
|
}
|
|
|
|
type SettingsMenuSelectProps<T extends PossibleValue = string> = {
|
|
label: string
|
|
name: string
|
|
options: Array<Option<T>>
|
|
optgroup?: Optgroup<T>
|
|
loading?: boolean
|
|
onChange: (val: T) => void
|
|
value?: T
|
|
disabled?: boolean
|
|
}
|
|
|
|
export default function SettingsMenuSelect<T extends PossibleValue = string>({
|
|
label,
|
|
name,
|
|
options,
|
|
optgroup,
|
|
loading,
|
|
onChange,
|
|
value,
|
|
disabled = false,
|
|
}: SettingsMenuSelectProps<T>) {
|
|
const handleChange: ChangeEventHandler<HTMLSelectElement> = useCallback(
|
|
event => {
|
|
const selectedValue = event.target.value
|
|
let onChangeValue: PossibleValue = selectedValue
|
|
if (typeof value === 'boolean') {
|
|
onChangeValue = selectedValue === 'true'
|
|
} else if (typeof value === 'number') {
|
|
onChangeValue = parseInt(selectedValue, 10)
|
|
}
|
|
onChange(onChangeValue as T)
|
|
},
|
|
[onChange, value]
|
|
)
|
|
const selectRef = useRef<HTMLSelectElement | null>(null)
|
|
|
|
return (
|
|
<OLFormGroup
|
|
controlId={`settings-menu-${name}`}
|
|
className="left-menu-setting"
|
|
>
|
|
<OLFormLabel>{label}</OLFormLabel>
|
|
{loading ? (
|
|
<p className="mb-0">
|
|
<Spinner
|
|
animation="border"
|
|
aria-hidden="true"
|
|
size="sm"
|
|
role="status"
|
|
/>
|
|
</p>
|
|
) : (
|
|
<OLFormSelect
|
|
size="sm"
|
|
onChange={handleChange}
|
|
value={value?.toString()}
|
|
disabled={disabled}
|
|
ref={selectRef}
|
|
>
|
|
{options.map(option => (
|
|
<option
|
|
key={`${name}-${option.value}`}
|
|
value={option.value.toString()}
|
|
aria-hidden={option.ariaHidden}
|
|
disabled={option.disabled}
|
|
>
|
|
{option.label}
|
|
</option>
|
|
))}
|
|
{optgroup ? (
|
|
<optgroup label={optgroup.label}>
|
|
{optgroup.options.map(option => (
|
|
<option
|
|
value={option.value.toString()}
|
|
key={option.value.toString()}
|
|
>
|
|
{option.label}
|
|
</option>
|
|
))}
|
|
</optgroup>
|
|
) : null}
|
|
</OLFormSelect>
|
|
)}
|
|
</OLFormGroup>
|
|
)
|
|
}
|