mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-23 17:19:37 +02:00
Merge pull request #28503 from overleaf/mj-split-theme-list-dark-light-legacy
[web] Split dark and light options in theme selector GitOrigin-RevId: 507c5a71269b360d23b246516487a0a072ee7d18
This commit is contained in:
committed by
Copybot
parent
da72a45e86
commit
0b51972da1
@@ -381,6 +381,7 @@
|
||||
"customizing_figures": "",
|
||||
"customizing_tables": "",
|
||||
"dark_mode_pdf_preview": "",
|
||||
"dark_themes": "",
|
||||
"date_and_owner": "",
|
||||
"date_and_time": "",
|
||||
"dealing_with_errors": "",
|
||||
@@ -977,6 +978,7 @@
|
||||
"leave_project": "",
|
||||
"leave_projects": "",
|
||||
"left": "",
|
||||
"legacy_themes": "",
|
||||
"length_unit": "",
|
||||
"let_us_know": "",
|
||||
"let_us_know_how_we_can_help": "",
|
||||
@@ -985,6 +987,7 @@
|
||||
"lets_get_you_set_up": "",
|
||||
"library": "",
|
||||
"licenses": "",
|
||||
"light_themes": "",
|
||||
"limited_document_history": "",
|
||||
"limited_to_n_collaborators_per_project": "",
|
||||
"limited_to_n_collaborators_per_project_plural": "",
|
||||
|
||||
@@ -1,43 +1,19 @@
|
||||
import { useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import getMeta from '../../../../utils/meta'
|
||||
import { useProjectSettingsContext } from '../../context/project-settings-context'
|
||||
import SettingsMenuSelect from './settings-menu-select'
|
||||
import type { Option } from './settings-menu-select'
|
||||
import { useEditorThemesOptionGroups } from '../../hooks/use-editor-theme-option-groups'
|
||||
|
||||
export default function SettingsEditorTheme() {
|
||||
const { t } = useTranslation()
|
||||
const editorThemes = getMeta('ol-editorThemes')
|
||||
const legacyEditorThemes = getMeta('ol-legacyEditorThemes')
|
||||
const { editorTheme, setEditorTheme } = useProjectSettingsContext()
|
||||
|
||||
const options = useMemo(() => {
|
||||
const editorThemeOptions: Array<Option> =
|
||||
editorThemes?.map(theme => ({
|
||||
value: theme.name,
|
||||
label: theme.name.replace(/_/g, ' '),
|
||||
})) ?? []
|
||||
|
||||
const dividerOption: Option = {
|
||||
value: '-',
|
||||
label: '—————————————————',
|
||||
disabled: true,
|
||||
}
|
||||
|
||||
const legacyEditorThemeOptions: Array<Option> =
|
||||
legacyEditorThemes?.map(theme => ({
|
||||
value: theme.name,
|
||||
label: theme.name.replace(/_/g, ' ') + ' (Legacy)',
|
||||
})) ?? []
|
||||
|
||||
return [...editorThemeOptions, dividerOption, ...legacyEditorThemeOptions]
|
||||
}, [editorThemes, legacyEditorThemes])
|
||||
const optGroups = useEditorThemesOptionGroups()
|
||||
|
||||
return (
|
||||
<SettingsMenuSelect
|
||||
onChange={setEditorTheme}
|
||||
value={editorTheme}
|
||||
options={options}
|
||||
optgroups={optGroups}
|
||||
label={t('editor_theme')}
|
||||
name="editorTheme"
|
||||
translateOptions="no"
|
||||
|
||||
@@ -22,8 +22,8 @@ export type Optgroup<T extends PossibleValue = string> = {
|
||||
type SettingsMenuSelectProps<T extends PossibleValue = string> = {
|
||||
label: string
|
||||
name: string
|
||||
options: Array<Option<T>>
|
||||
optgroup?: Optgroup<T>
|
||||
options?: Array<Option<T>>
|
||||
optgroups?: Array<Optgroup<T>>
|
||||
loading?: boolean
|
||||
onChange: (val: T) => void
|
||||
value?: T
|
||||
@@ -35,7 +35,7 @@ export default function SettingsMenuSelect<T extends PossibleValue = string>({
|
||||
label,
|
||||
name,
|
||||
options,
|
||||
optgroup,
|
||||
optgroups,
|
||||
loading,
|
||||
onChange,
|
||||
value,
|
||||
@@ -92,7 +92,7 @@ export default function SettingsMenuSelect<T extends PossibleValue = string>({
|
||||
ref={selectRef}
|
||||
translate={translateOptions}
|
||||
>
|
||||
{options.map(option => (
|
||||
{options?.map(option => (
|
||||
<option
|
||||
key={`${name}-${option.value}`}
|
||||
value={option.value.toString()}
|
||||
@@ -102,8 +102,8 @@ export default function SettingsMenuSelect<T extends PossibleValue = string>({
|
||||
{option.label}
|
||||
</option>
|
||||
))}
|
||||
{optgroup ? (
|
||||
<optgroup label={optgroup.label}>
|
||||
{optgroups?.map(optgroup => (
|
||||
<optgroup label={optgroup.label} key={optgroup.label}>
|
||||
{optgroup.options.map(option => (
|
||||
<option
|
||||
value={option.value.toString()}
|
||||
@@ -113,7 +113,7 @@ export default function SettingsMenuSelect<T extends PossibleValue = string>({
|
||||
</option>
|
||||
))}
|
||||
</optgroup>
|
||||
) : null}
|
||||
))}
|
||||
</OLFormSelect>
|
||||
)}
|
||||
</OLFormGroup>
|
||||
|
||||
@@ -33,7 +33,7 @@ export default function SettingsSpellCheckLanguage() {
|
||||
onChange={setSpellCheckLanguage}
|
||||
value={supportsWebAssembly() ? spellCheckLanguage : ''}
|
||||
options={[{ value: '', label: t('off') }]}
|
||||
optgroup={optgroup}
|
||||
optgroups={[optgroup]}
|
||||
label={t('spell_check')}
|
||||
name="spellCheckLanguage"
|
||||
disabled={permissionsLevel === 'readOnly' || !supportsWebAssembly()}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import getMeta from '@/utils/meta'
|
||||
import { useMemo } from 'react'
|
||||
import { Option } from '../components/settings/settings-menu-select'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
const overrides = new Map([['overleaf', 'overleaf light']])
|
||||
function getThemeName(theme: string): string {
|
||||
return (overrides.get(theme) ?? theme).replace(/_/g, ' ')
|
||||
}
|
||||
|
||||
export function useEditorThemesOptionGroups() {
|
||||
const editorThemes = getMeta('ol-editorThemes')
|
||||
const legacyEditorThemes = getMeta('ol-legacyEditorThemes')
|
||||
const { t } = useTranslation()
|
||||
|
||||
const optgroups = useMemo(() => {
|
||||
const lightThemes: Array<Option> = []
|
||||
const darkThemes: Array<Option> = []
|
||||
|
||||
editorThemes?.forEach(({ name: theme, dark }) => {
|
||||
const target = dark ? darkThemes : lightThemes
|
||||
target.push({
|
||||
value: theme,
|
||||
label: getThemeName(theme),
|
||||
})
|
||||
})
|
||||
|
||||
const legacyEditorThemeOptions: Array<Option> =
|
||||
legacyEditorThemes?.map(({ name: theme }) => ({
|
||||
value: theme,
|
||||
label: getThemeName(theme) + ' (Legacy)',
|
||||
})) ?? []
|
||||
|
||||
const groups = []
|
||||
if (lightThemes.length > 0) {
|
||||
groups.push({ label: t('light_themes'), options: lightThemes })
|
||||
}
|
||||
if (darkThemes.length > 0) {
|
||||
groups.push({ label: t('dark_themes'), options: darkThemes })
|
||||
}
|
||||
if (legacyEditorThemeOptions.length > 0) {
|
||||
groups.push({
|
||||
label: t('legacy_themes'),
|
||||
options: legacyEditorThemeOptions,
|
||||
})
|
||||
}
|
||||
return groups
|
||||
}, [editorThemes, legacyEditorThemes, t])
|
||||
|
||||
return optgroups
|
||||
}
|
||||
@@ -1,44 +1,20 @@
|
||||
import { useProjectSettingsContext } from '@/features/editor-left-menu/context/project-settings-context'
|
||||
import DropdownSetting from '../dropdown-setting'
|
||||
import getMeta from '@/utils/meta'
|
||||
import { useMemo } from 'react'
|
||||
import type { Option } from '../dropdown-setting'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useEditorThemesOptionGroups } from '@/features/editor-left-menu/hooks/use-editor-theme-option-groups'
|
||||
|
||||
export default function EditorThemeSetting() {
|
||||
const editorThemes = getMeta('ol-editorThemes')
|
||||
const legacyEditorThemes = getMeta('ol-legacyEditorThemes')
|
||||
const { editorTheme, setEditorTheme } = useProjectSettingsContext()
|
||||
const { t } = useTranslation()
|
||||
|
||||
const options = useMemo(() => {
|
||||
const editorThemeOptions: Array<Option> =
|
||||
editorThemes?.map(theme => ({
|
||||
value: theme.name,
|
||||
label: theme.name.replace(/_/g, ' '),
|
||||
})) ?? []
|
||||
|
||||
const dividerOption: Option = {
|
||||
value: '-',
|
||||
label: '—————————————————',
|
||||
disabled: true,
|
||||
}
|
||||
|
||||
const legacyEditorThemeOptions: Array<Option> =
|
||||
legacyEditorThemes?.map(theme => ({
|
||||
value: theme.name,
|
||||
label: theme.name.replace(/_/g, ' ') + ' (Legacy)',
|
||||
})) ?? []
|
||||
|
||||
return [...editorThemeOptions, dividerOption, ...legacyEditorThemeOptions]
|
||||
}, [editorThemes, legacyEditorThemes])
|
||||
const optGroups = useEditorThemesOptionGroups()
|
||||
|
||||
return (
|
||||
<DropdownSetting
|
||||
id="editorTheme"
|
||||
label={t('editor_theme')}
|
||||
description={t('the_code_editor_color_scheme')}
|
||||
options={options}
|
||||
optgroups={optGroups}
|
||||
onChange={setEditorTheme}
|
||||
value={editorTheme}
|
||||
translateOptions="no"
|
||||
|
||||
@@ -21,12 +21,10 @@ export type Optgroup<T extends PossibleValue = string> = {
|
||||
type SettingsMenuSelectProps<T extends PossibleValue = string> = {
|
||||
id: string
|
||||
label: string
|
||||
options: Array<Option<T>>
|
||||
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>
|
||||
optgroups?: Array<Optgroup<T>>
|
||||
value?: T
|
||||
disabled?: boolean
|
||||
width?: 'default' | 'wide'
|
||||
@@ -40,7 +38,7 @@ export default function DropdownSetting<T extends PossibleValue = string>({
|
||||
options,
|
||||
onChange,
|
||||
value,
|
||||
optgroup,
|
||||
optgroups,
|
||||
description = undefined,
|
||||
disabled = false,
|
||||
width = 'default',
|
||||
@@ -77,7 +75,7 @@ export default function DropdownSetting<T extends PossibleValue = string>({
|
||||
disabled={disabled}
|
||||
translate={translateOptions}
|
||||
>
|
||||
{options.map(option => (
|
||||
{options?.map(option => (
|
||||
<option
|
||||
key={`${id}-${option.value}`}
|
||||
value={option.value.toString()}
|
||||
@@ -87,8 +85,8 @@ export default function DropdownSetting<T extends PossibleValue = string>({
|
||||
{option.label}
|
||||
</option>
|
||||
))}
|
||||
{optgroup ? (
|
||||
<optgroup label={optgroup.label}>
|
||||
{optgroups?.map(optgroup => (
|
||||
<optgroup label={optgroup.label} key={optgroup.label}>
|
||||
{optgroup.options.map(option => (
|
||||
<option
|
||||
value={option.value.toString()}
|
||||
@@ -98,7 +96,7 @@ export default function DropdownSetting<T extends PossibleValue = string>({
|
||||
</option>
|
||||
))}
|
||||
</optgroup>
|
||||
) : null}
|
||||
))}
|
||||
</OLFormSelect>
|
||||
)}
|
||||
</Setting>
|
||||
|
||||
@@ -31,7 +31,7 @@ export default function SpellCheckSetting() {
|
||||
id="spellCheckLanguage"
|
||||
label={t('spellcheck_language')}
|
||||
options={[{ value: '', label: t('off') }]}
|
||||
optgroup={optgroup}
|
||||
optgroups={[optgroup]}
|
||||
onChange={setSpellCheckLanguage}
|
||||
value={supportsWebAssembly() ? spellCheckLanguage : ''}
|
||||
width="wide"
|
||||
|
||||
@@ -502,6 +502,7 @@
|
||||
"da": "Danish",
|
||||
"dark_mode": "Dark mode",
|
||||
"dark_mode_pdf_preview": "Dark mode PDF preview",
|
||||
"dark_themes": "Dark themes",
|
||||
"date": "Date",
|
||||
"date_and_owner": "Date and owner",
|
||||
"date_and_time": "Date and time",
|
||||
@@ -1263,6 +1264,7 @@
|
||||
"leave_project": "Leave Project",
|
||||
"leave_projects": "Leave Projects",
|
||||
"left": "Left",
|
||||
"legacy_themes": "Legacy themes",
|
||||
"length_unit": "Length unit",
|
||||
"let_us_know": "Let us know",
|
||||
"let_us_know_how_we_can_help": "Let us know how we can help",
|
||||
@@ -1273,6 +1275,7 @@
|
||||
"library": "Library",
|
||||
"license": "License",
|
||||
"licenses": "Licenses",
|
||||
"light_themes": "Light themes",
|
||||
"limited_document_history": "Limited document history",
|
||||
"limited_to_n_collaborators_per_project": "Limited to __count__ collaborator per project",
|
||||
"limited_to_n_collaborators_per_project_plural": "Limited to __count__ collaborators per project",
|
||||
|
||||
@@ -607,7 +607,6 @@ describe('<EditorLeftMenu />', function () {
|
||||
'editortheme-1',
|
||||
'editortheme-2',
|
||||
'editortheme-3',
|
||||
'-',
|
||||
'legacytheme-1',
|
||||
'legacytheme-2',
|
||||
'legacytheme-3',
|
||||
@@ -618,7 +617,6 @@ describe('<EditorLeftMenu />', function () {
|
||||
'editortheme-1',
|
||||
'editortheme-2',
|
||||
'editortheme-3',
|
||||
'—————————————————',
|
||||
'legacytheme-1 (Legacy)',
|
||||
'legacytheme-2 (Legacy)',
|
||||
'legacytheme-3 (Legacy)',
|
||||
|
||||
Reference in New Issue
Block a user