mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-06-02 05:41:33 +02:00
3b5ea89a1c
* Update test for the loading spinner component * Create a story for the loading spinner component * Move role and use CSS for spacing instead * Add a classname prop * Reuse LoadingSpinner * Use OLSpinner instead of Spinner * Use data-testid since status role was moved * Wait for journals to load * Use `isLoading` prop instead and fix the button's height * Use `isLoading` prop instead * Use LoadingSpinner instead and remove spacing * Update test for the loading spinner component * Use `isLoading` prop instead * Add aria-describedby to layout button for processing state * Replace `spinner` to `ol-spinner` * Scope status * Remove redundant `div.loading` --------- Co-authored-by: Antoine Clausse <antoine.clausse@overleaf.com> GitOrigin-RevId: 8f43b991f8f458b2abd5a4661913ac9b972d892a
107 lines
2.9 KiB
TypeScript
107 lines
2.9 KiB
TypeScript
import OLFormSelect from '@/shared/components/ol/ol-form-select'
|
|
import { ChangeEventHandler, useCallback } from 'react'
|
|
import Setting from './setting'
|
|
import classNames from 'classnames'
|
|
import OLSpinner from '@/shared/components/ol/ol-spinner'
|
|
|
|
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> = {
|
|
id: string
|
|
label: string
|
|
options: Array<Option<T>>
|
|
onChange: (val: T) => void
|
|
description?: string
|
|
// TODO: We can remove optgroup when the spellcheck setting is
|
|
// split into 2 and no longer uses it.
|
|
optgroup?: Optgroup<T>
|
|
value?: T
|
|
disabled?: boolean
|
|
width?: 'default' | 'wide'
|
|
loading?: boolean
|
|
translateOptions?: 'yes' | 'no'
|
|
}
|
|
|
|
export default function DropdownSetting<T extends PossibleValue = string>({
|
|
id,
|
|
label,
|
|
options,
|
|
onChange,
|
|
value,
|
|
optgroup,
|
|
description = undefined,
|
|
disabled = false,
|
|
width = 'default',
|
|
loading = false,
|
|
translateOptions,
|
|
}: 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]
|
|
)
|
|
|
|
return (
|
|
<Setting controlId={id} label={label} description={description}>
|
|
{loading ? (
|
|
<OLSpinner size="sm" />
|
|
) : (
|
|
<OLFormSelect
|
|
id={id}
|
|
className={classNames('ide-dropdown-setting', {
|
|
'ide-dropdown-setting-wide': width === 'wide',
|
|
})}
|
|
size="sm"
|
|
onChange={handleChange}
|
|
value={value?.toString()}
|
|
disabled={disabled}
|
|
translate={translateOptions}
|
|
>
|
|
{options.map(option => (
|
|
<option
|
|
key={`${id}-${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>
|
|
)}
|
|
</Setting>
|
|
)
|
|
}
|