From ce1d63d92c48b7eed487523f3ead0d7fd3ac6017 Mon Sep 17 00:00:00 2001 From: Alf Eaton Date: Fri, 17 Jan 2025 10:32:45 +0000 Subject: [PATCH] Create a shared module for CSS styles from user settings (#22925) GitOrigin-RevId: 1e62258e1e38d8ab2ce8debc51c53a98f4e915f6 --- .../settings/settings-font-family.tsx | 2 +- .../settings/settings-line-height.tsx | 2 +- .../settings/settings-overall-theme.tsx | 2 +- .../js/features/history/extensions/theme.ts | 29 ++++---------- .../source-editor/extensions/theme.ts | 40 +++++++------------ .../hooks/use-codemirror-scope.ts | 7 +--- .../web/frontend/js/shared/utils/styles.ts | 29 ++++++++++++++ services/web/types/project-settings.ts | 2 +- services/web/types/user-settings.ts | 6 +-- 9 files changed, 59 insertions(+), 60 deletions(-) create mode 100644 services/web/frontend/js/shared/utils/styles.ts diff --git a/services/web/frontend/js/features/editor-left-menu/components/settings/settings-font-family.tsx b/services/web/frontend/js/features/editor-left-menu/components/settings/settings-font-family.tsx index cfa62a1826..5a327093a4 100644 --- a/services/web/frontend/js/features/editor-left-menu/components/settings/settings-font-family.tsx +++ b/services/web/frontend/js/features/editor-left-menu/components/settings/settings-font-family.tsx @@ -1,8 +1,8 @@ import { useTranslation } from 'react-i18next' -import { FontFamily } from '../../../source-editor/extensions/theme' import { useProjectSettingsContext } from '../../context/project-settings-context' import SettingsMenuSelect from './settings-menu-select' import BetaBadge from '@/shared/components/beta-badge' +import { FontFamily } from '@/shared/utils/styles' export default function SettingsFontFamily() { const { t } = useTranslation() diff --git a/services/web/frontend/js/features/editor-left-menu/components/settings/settings-line-height.tsx b/services/web/frontend/js/features/editor-left-menu/components/settings/settings-line-height.tsx index 6694306fe5..b0d5201771 100644 --- a/services/web/frontend/js/features/editor-left-menu/components/settings/settings-line-height.tsx +++ b/services/web/frontend/js/features/editor-left-menu/components/settings/settings-line-height.tsx @@ -1,7 +1,7 @@ import { useTranslation } from 'react-i18next' -import type { LineHeight } from '../../../source-editor/extensions/theme' import { useProjectSettingsContext } from '../../context/project-settings-context' import SettingsMenuSelect from './settings-menu-select' +import { LineHeight } from '@/shared/utils/styles' export default function SettingsLineHeight() { const { t } = useTranslation() diff --git a/services/web/frontend/js/features/editor-left-menu/components/settings/settings-overall-theme.tsx b/services/web/frontend/js/features/editor-left-menu/components/settings/settings-overall-theme.tsx index 9e2d846a35..f63be25433 100644 --- a/services/web/frontend/js/features/editor-left-menu/components/settings/settings-overall-theme.tsx +++ b/services/web/frontend/js/features/editor-left-menu/components/settings/settings-overall-theme.tsx @@ -5,8 +5,8 @@ import getMeta from '../../../../utils/meta' import SettingsMenuSelect, { Option } from './settings-menu-select' import { useProjectSettingsContext } from '../../context/project-settings-context' import type { OverallThemeMeta } from '../../../../../../types/project-settings' -import type { OverallTheme } from '../../../source-editor/extensions/theme' import { isIEEEBranded } from '@/utils/is-ieee-branded' +import { OverallTheme } from '@/shared/utils/styles' export default function SettingsOverallTheme() { const { t } = useTranslation() diff --git a/services/web/frontend/js/features/history/extensions/theme.ts b/services/web/frontend/js/features/history/extensions/theme.ts index fda9c3185b..268b9d2dfd 100644 --- a/services/web/frontend/js/features/history/extensions/theme.ts +++ b/services/web/frontend/js/features/history/extensions/theme.ts @@ -1,8 +1,6 @@ import { EditorView } from '@codemirror/view' import { Compartment, TransactionSpec } from '@codemirror/state' - -export type FontFamily = 'monaco' | 'lucida' | 'opendyslexicmono' -export type LineHeight = 'compact' | 'normal' | 'wide' +import { FontFamily, LineHeight, userStyles } from '@/shared/utils/styles' export type Options = { fontSize: number @@ -17,31 +15,20 @@ export const theme = (options: Options) => [ optionsThemeConf.of(createThemeFromOptions(options)), ] -export const lineHeights: Record = { - compact: 1.33, - normal: 1.6, - wide: 2, -} - -const fontFamilies: Record = { - monaco: ['Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'monospace'], - lucida: ['Lucida Console', 'Source Code Pro', 'monospace'], - opendyslexicmono: ['OpenDyslexic Mono', 'monospace'], -} - const createThemeFromOptions = ({ fontSize = 12, fontFamily = 'monaco', lineHeight = 'normal', }: Options) => { // Theme styles that depend on settings - const fontFamilyValue = fontFamilies[fontFamily]?.join(', ') + const styles = userStyles({ fontSize, fontFamily, lineHeight }) + return [ EditorView.editorAttributes.of({ style: Object.entries({ - '--font-size': `${fontSize}px`, - '--source-font-family': fontFamilyValue, - '--line-height': lineHeights[lineHeight], + '--font-size': styles.fontSize, + '--source-font-family': styles.fontFamily, + '--line-height': styles.lineHeight, }) .map(([key, value]) => `${key}: ${value}`) .join(';'), @@ -50,8 +37,8 @@ const createThemeFromOptions = ({ // TODO: set these on document.body, or a new container element for the tooltips, without using a style mod EditorView.theme({ '.cm-tooltip': { - '--font-size': `${fontSize}px`, - '--source-font-family': fontFamilyValue, + '--font-size': styles.fontSize, + '--source-font-family': styles.fontFamily, }, }), ] diff --git a/services/web/frontend/js/features/source-editor/extensions/theme.ts b/services/web/frontend/js/features/source-editor/extensions/theme.ts index f38289cce2..233f2c8dac 100644 --- a/services/web/frontend/js/features/source-editor/extensions/theme.ts +++ b/services/web/frontend/js/features/source-editor/extensions/theme.ts @@ -3,15 +3,17 @@ import { Annotation, Compartment, TransactionSpec } from '@codemirror/state' import { syntaxHighlighting } from '@codemirror/language' import { classHighlighter } from './class-highlighter' import classNames from 'classnames' +import { + FontFamily, + LineHeight, + OverallTheme, + userStyles, +} from '@/shared/utils/styles' const optionsThemeConf = new Compartment() const selectedThemeConf = new Compartment() export const themeOptionsChange = Annotation.define() -export type FontFamily = 'monaco' | 'lucida' | 'opendyslexicmono' -export type LineHeight = 'compact' | 'normal' | 'wide' -export type OverallTheme = '' | 'light-' - type Options = { fontSize: number fontFamily: FontFamily @@ -53,18 +55,6 @@ const svgUrl = (content: string) => `${content}` )}')` -export const lineHeights: Record = { - compact: 1.33, - normal: 1.6, - wide: 2, -} - -const fontFamilies: Record = { - monaco: ['Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'monospace'], - lucida: ['Lucida Console', 'Source Code Pro', 'monospace'], - opendyslexicmono: ['OpenDyslexic Mono', 'monospace'], -} - const createThemeFromOptions = ({ fontSize = 12, fontFamily = 'monaco', @@ -72,9 +62,9 @@ const createThemeFromOptions = ({ overallTheme = '', bootstrapVersion = 3, }: Options) => { - /** - * Theme styles that depend on settings. - */ + // Theme styles that depend on settings. + const styles = userStyles({ fontSize, fontFamily, lineHeight }) + return [ EditorView.editorAttributes.of({ class: classNames( @@ -82,9 +72,9 @@ const createThemeFromOptions = ({ 'bootstrap-' + bootstrapVersion ), style: Object.entries({ - '--font-size': `${fontSize}px`, - '--source-font-family': fontFamilies[fontFamily]?.join(', '), - '--line-height': lineHeights[lineHeight], + '--font-size': styles.fontSize, + '--source-font-family': styles.fontFamily, + '--line-height': styles.lineHeight, }) .map(([key, value]) => `${key}: ${value}`) .join(';'), @@ -93,9 +83,9 @@ const createThemeFromOptions = ({ // TODO: set these on document.body, or a new container element for the tooltips, without using a style mod EditorView.theme({ '.cm-tooltip': { - '--font-size': `${fontSize}px`, - '--source-font-family': fontFamilies[fontFamily]?.join(', '), - '--line-height': lineHeights[lineHeight], + '--font-size': styles.fontSize, + '--source-font-family': styles.fontFamily, + '--line-height': styles.lineHeight, }, }), ] diff --git a/services/web/frontend/js/features/source-editor/hooks/use-codemirror-scope.ts b/services/web/frontend/js/features/source-editor/hooks/use-codemirror-scope.ts index 7d6a8e6589..c4a1090431 100644 --- a/services/web/frontend/js/features/source-editor/hooks/use-codemirror-scope.ts +++ b/services/web/frontend/js/features/source-editor/hooks/use-codemirror-scope.ts @@ -5,11 +5,7 @@ import useScopeEventEmitter from '../../../shared/hooks/use-scope-event-emitter' import useEventListener from '../../../shared/hooks/use-event-listener' import useScopeEventListener from '../../../shared/hooks/use-scope-event-listener' import { createExtensions } from '../extensions' -import { - lineHeights, - setEditorTheme, - setOptionsTheme, -} from '../extensions/theme' +import { setEditorTheme, setOptionsTheme } from '../extensions/theme' import { restoreCursorPosition, setCursorLineAndScroll, @@ -63,6 +59,7 @@ import { useThreadsContext } from '@/features/review-panel-new/context/threads-c import { useHunspell } from '@/features/source-editor/hooks/use-hunspell' import { isBootstrap5 } from '@/features/utils/bootstrap-5' import { Permissions } from '@/features/ide-react/types/permissions' +import { lineHeights } from '@/shared/utils/styles' function useCodeMirrorScope(view: EditorView) { const { fileTreeData } = useFileTreeData() diff --git a/services/web/frontend/js/shared/utils/styles.ts b/services/web/frontend/js/shared/utils/styles.ts new file mode 100644 index 0000000000..2b30b3ed7c --- /dev/null +++ b/services/web/frontend/js/shared/utils/styles.ts @@ -0,0 +1,29 @@ +export type OverallTheme = '' | 'light-' + +export const fontFamilies = { + monaco: ['Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'monospace'], + lucida: ['Lucida Console', 'Source Code Pro', 'monospace'], + opendyslexicmono: ['OpenDyslexic Mono', 'monospace'], +} + +export type FontFamily = keyof typeof fontFamilies + +export const lineHeights = { + compact: 1.33, + normal: 1.6, + wide: 2, +} + +export type LineHeight = keyof typeof lineHeights + +type Options = { + fontFamily: FontFamily + fontSize: number + lineHeight: LineHeight +} + +export const userStyles = ({ fontFamily, fontSize, lineHeight }: Options) => ({ + fontFamily: fontFamilies[fontFamily]?.join(','), + fontSize: `${fontSize}px`, + lineHeight: lineHeights[lineHeight], +}) diff --git a/services/web/types/project-settings.ts b/services/web/types/project-settings.ts index dd649033b8..ec4f006197 100644 --- a/services/web/types/project-settings.ts +++ b/services/web/types/project-settings.ts @@ -1,5 +1,5 @@ -import { OverallTheme } from '../frontend/js/features/source-editor/extensions/theme' import { Brand } from './helpers/brand' +import { OverallTheme } from '@/shared/utils/styles' export type AllowedImageName = { imageDesc: string diff --git a/services/web/types/user-settings.ts b/services/web/types/user-settings.ts index a574454ddd..0f49d11dad 100644 --- a/services/web/types/user-settings.ts +++ b/services/web/types/user-settings.ts @@ -1,8 +1,4 @@ -import { - FontFamily, - LineHeight, - OverallTheme, -} from '@/features/source-editor/extensions/theme' +import { FontFamily, LineHeight, OverallTheme } from '@/shared/utils/styles' export type Keybindings = 'none' | 'default' | 'vim' | 'emacs' export type PdfViewer = 'pdfjs' | 'native'