diff --git a/playwright/e2e/settings/appearance-user-settings-tab.spec.ts b/playwright/e2e/settings/appearance-user-settings-tab.spec.ts index 3f220acc07..df091f45a8 100644 --- a/playwright/e2e/settings/appearance-user-settings-tab.spec.ts +++ b/playwright/e2e/settings/appearance-user-settings-tab.spec.ts @@ -73,48 +73,18 @@ test.describe("Appearance user settings tab", () => { await expect(page.locator(".mx_RoomView_body[data-layout='bubble']")).toBeVisible(); }); - test("should support changing font size by clicking the font slider", async ({ page, app, user }) => { + test("should support changing font size by using the font size dropdown", async ({ page, app, user }) => { await app.settings.openUserSettings("Appearance"); const tab = page.getByTestId("mx_AppearanceUserSettingsTab"); - const fontSliderSection = tab.locator(".mx_FontScalingPanel_fontSlider"); + const fontDropdown = tab.locator(".mx_FontScalingPanel_Dropdown"); + await expect(fontDropdown.getByLabel("Font size")).toBeVisible(); - await expect(fontSliderSection.getByLabel("Font size")).toBeVisible(); + // Default browser font size is 16px and the select value is 0 + // -4 value is 12px + await fontDropdown.getByLabel("Font size").selectOption({ value: "-4" }); - const slider = fontSliderSection.getByRole("slider"); - // Click the left position of the slider - await slider.click({ position: { x: 0, y: 10 } }); - - const MIN_FONT_SIZE = 11; - // Assert that the smallest font size is selected - await expect(fontSliderSection.locator(`input[value='${MIN_FONT_SIZE}']`)).toBeVisible(); - await expect( - fontSliderSection.locator("output .mx_Slider_selection_label", { hasText: String(MIN_FONT_SIZE) }), - ).toBeVisible(); - - await expect(fontSliderSection).toMatchScreenshot(`font-slider-${MIN_FONT_SIZE}.png`); - - // Click the right position of the slider - await slider.click({ position: { x: 572, y: 10 } }); - - const MAX_FONT_SIZE = 21; - // Assert that the largest font size is selected - await expect(fontSliderSection.locator(`input[value='${MAX_FONT_SIZE}']`)).toBeVisible(); - await expect( - fontSliderSection.locator("output .mx_Slider_selection_label", { hasText: String(MAX_FONT_SIZE) }), - ).toBeVisible(); - - await expect(fontSliderSection).toMatchScreenshot(`font-slider-${MAX_FONT_SIZE}.png`); - }); - - test("should disable font size slider when custom font size is used", async ({ page, app, user }) => { - await app.settings.openUserSettings("Appearance"); - - const panel = page.getByTestId("mx_FontScalingPanel"); - await panel.locator("label", { hasText: "Use custom size" }).click(); - - // Assert that the font slider is disabled - await expect(panel.locator(".mx_FontScalingPanel_fontSlider input[disabled]")).toBeVisible(); + await expect(page).toMatchScreenshot("window-12px.png"); }); test("should support enabling compact group (modern) layout", async ({ page, app, user }) => { diff --git a/playwright/snapshots/settings/appearance-user-settings-tab.spec.ts/appearance-tab-linux.png b/playwright/snapshots/settings/appearance-user-settings-tab.spec.ts/appearance-tab-linux.png index 0d13a72c6e..bb2672fa02 100644 Binary files a/playwright/snapshots/settings/appearance-user-settings-tab.spec.ts/appearance-tab-linux.png and b/playwright/snapshots/settings/appearance-user-settings-tab.spec.ts/appearance-tab-linux.png differ diff --git a/playwright/snapshots/settings/appearance-user-settings-tab.spec.ts/window-12px-linux.png b/playwright/snapshots/settings/appearance-user-settings-tab.spec.ts/window-12px-linux.png new file mode 100644 index 0000000000..aa72c5786d Binary files /dev/null and b/playwright/snapshots/settings/appearance-user-settings-tab.spec.ts/window-12px-linux.png differ diff --git a/res/css/views/settings/_FontScalingPanel.pcss b/res/css/views/settings/_FontScalingPanel.pcss index 3c01321487..974ca0fa0d 100644 --- a/res/css/views/settings/_FontScalingPanel.pcss +++ b/res/css/views/settings/_FontScalingPanel.pcss @@ -36,26 +36,8 @@ limitations under the License. } } -.mx_FontScalingPanel_fontSlider { - display: flex; - align-items: center; - padding: 15px $spacing-20 35px; - background: $panels; - border-radius: 10px; - font-size: $font-10px; - - .mx_FontScalingPanel_fontSlider_smallText, - .mx_FontScalingPanel_fontSlider_largeText { - font-weight: 500; - } - - .mx_FontScalingPanel_fontSlider_smallText { - font-size: $font-15px; - padding-inline-end: $spacing-20; - } - - .mx_FontScalingPanel_fontSlider_largeText { - font-size: $font-18px; - padding-inline-start: $spacing-20; - } +.mx_FontScalingPanel_Dropdown { + width: 120px; + /* Override default mx_Field margin */ + margin-bottom: var(--cpd-space-2x) !important; } diff --git a/src/components/views/settings/FontScalingPanel.tsx b/src/components/views/settings/FontScalingPanel.tsx index f5afa8b834..593e5c7c9f 100644 --- a/src/components/views/settings/FontScalingPanel.tsx +++ b/src/components/views/settings/FontScalingPanel.tsx @@ -14,29 +14,26 @@ See the License for the specific language governing permissions and limitations under the License. */ -import React, { ChangeEvent } from "react"; +import React from "react"; import EventTilePreview from "../elements/EventTilePreview"; -import Field from "../elements/Field"; -import SettingsFlag from "../elements/SettingsFlag"; import SettingsStore from "../../../settings/SettingsStore"; -import Slider from "../elements/Slider"; -import { FontWatcher } from "../../../settings/watchers/FontWatcher"; -import { IValidationResult, IFieldState } from "../elements/Validation"; import { Layout } from "../../../settings/enums/Layout"; import { MatrixClientPeg } from "../../../MatrixClientPeg"; import { SettingLevel } from "../../../settings/SettingLevel"; import { _t } from "../../../languageHandler"; -import { clamp } from "../../../utils/numbers"; import SettingsSubsection from "./shared/SettingsSubsection"; +import Field from "../elements/Field"; +import { FontWatcher } from "../../../settings/watchers/FontWatcher"; interface IProps {} interface IState { + browserFontSize: number; // String displaying the current selected fontSize. - // Needs to be string for things like '17.' without + // Needs to be string for things like '1.' without // trailing 0s. - fontSize: string; + fontSizeDelta: number; useCustomFontSize: boolean; layout: Layout; // User profile data for the message preview @@ -47,6 +44,10 @@ interface IState { export default class FontScalingPanel extends React.Component { private readonly MESSAGE_PREVIEW_TEXT = _t("common|preview_message"); + /** + * Font sizes available (in px) + */ + private readonly sizes = [9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36]; private layoutWatcherRef?: string; private unmounted = false; @@ -54,7 +55,8 @@ export default class FontScalingPanel extends React.Component { super(props); this.state = { - fontSize: SettingsStore.getValue("baseFontSizeV2", null).toString(), + fontSizeDelta: SettingsStore.getValue("fontSizeDelta", null), + browserFontSize: FontWatcher.getBrowserDefaultFontSize(), useCustomFontSize: SettingsStore.getValue("useCustomFontSize"), layout: SettingsStore.getValue("layout"), }; @@ -90,30 +92,22 @@ export default class FontScalingPanel extends React.Component { } } - private onFontSizeChanged = (size: number): void => { - this.setState({ fontSize: size.toString() }); - SettingsStore.setValue("baseFontSizeV2", null, SettingLevel.DEVICE, size); + /** + * Save the new font size + * @param delta + */ + private onFontSizeChanged = async (delta: string): Promise => { + const parsedDelta = parseInt(delta, 10) || 0; + this.setState({ fontSizeDelta: parsedDelta }); + await SettingsStore.setValue("fontSizeDelta", null, SettingLevel.DEVICE, parsedDelta); }; - private onValidateFontSize = async ({ value }: Pick): Promise => { - const parsedSize = parseFloat(value!); - const min = FontWatcher.MIN_SIZE; - const max = FontWatcher.MAX_SIZE; - - if (isNaN(parsedSize)) { - return { valid: false, feedback: _t("settings|appearance|font_size_nan") }; - } - - if (!(min <= parsedSize && parsedSize <= max)) { - return { - valid: false, - feedback: _t("settings|appearance|font_size_limit", { min, max }), - }; - } - - SettingsStore.setValue("baseFontSizeV2", null, SettingLevel.DEVICE, parseInt(value!, 10)); - - return { valid: true, feedback: _t("settings|appearance|font_size_valid", { min, max }) }; + /** + * Compute the difference between the selected font size and the browser font size + * @param fontSize + */ + private computeDeltaFontSize = (fontSize: number): number => { + return fontSize - this.state.browserFontSize; }; public render(): React.ReactNode { @@ -123,6 +117,21 @@ export default class FontScalingPanel extends React.Component { stretchContent data-testid="mx_FontScalingPanel" > + this.onFontSizeChanged(e.target.value)} + > + {this.sizes.map((size) => ( + + ))} + { displayName={this.state.displayName} avatarUrl={this.state.avatarUrl} /> -
-
Aa
- ""} - disabled={this.state.useCustomFontSize} - label={_t("settings|appearance|font_size")} - /> -
Aa
-
- - { - this.setState({ useCustomFontSize: checked }); - if (!checked) { - const size = parseInt(this.state.fontSize, 10); - const clamped = clamp(size, FontWatcher.MIN_SIZE, FontWatcher.MAX_SIZE); - if (clamped !== size) { - this.onFontSizeChanged(clamped); - } - } - }} - useCheckbox={true} - /> - - ) => this.setState({ fontSize: value.target.value })} - disabled={!this.state.useCustomFontSize} - className="mx_AppearanceUserSettingsTab_checkboxControlledField" - /> ); } diff --git a/src/dispatcher/actions.ts b/src/dispatcher/actions.ts index 5783e78331..bbc32817ce 100644 --- a/src/dispatcher/actions.ts +++ b/src/dispatcher/actions.ts @@ -107,9 +107,11 @@ export enum Action { MigrateBaseFontSize = "migrate_base_font_size", /** - * Sets the apps root font size. Should be used with UpdateFontSizePayload + * Sets the apps root font size delta. Should be used with UpdateFontSizeDeltaPayload + * It will add the delta to the current font size. + * The delta should be between {@link FontWatcher.MIN_DELTA} and {@link FontWatcher.MAX_DELTA}. */ - UpdateFontSize = "update_font_size", + UpdateFontSizeDelta = "update_font_size_delta", /** * Sets a system font. Should be used with UpdateSystemFontPayload diff --git a/src/dispatcher/payloads/UpdateFontSizePayload.ts b/src/dispatcher/payloads/UpdateFontSizeDeltaPayload.ts similarity index 70% rename from src/dispatcher/payloads/UpdateFontSizePayload.ts rename to src/dispatcher/payloads/UpdateFontSizeDeltaPayload.ts index 6577acd594..63a36d736b 100644 --- a/src/dispatcher/payloads/UpdateFontSizePayload.ts +++ b/src/dispatcher/payloads/UpdateFontSizeDeltaPayload.ts @@ -17,11 +17,12 @@ limitations under the License. import { ActionPayload } from "../payloads"; import { Action } from "../actions"; -export interface UpdateFontSizePayload extends ActionPayload { - action: Action.UpdateFontSize; +export interface UpdateFontSizeDeltaPayload extends ActionPayload { + action: Action.UpdateFontSizeDelta; /** - * The font size to set the root to + * The delta is added to the current font size. + * The delta should be between {@link FontWatcher.MIN_DELTA} and {@link FontWatcher.MAX_DELTA}. */ - size: number; + delta: number; } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 47d45fc2f0..c974dc5f8b 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2422,9 +2422,7 @@ "custom_theme_success": "Theme added!", "custom_theme_url": "Custom theme URL", "font_size": "Font size", - "font_size_limit": "Custom font size can only be between %(min)s pt and %(max)s pt", - "font_size_nan": "Size must be a number", - "font_size_valid": "Use between %(min)s pt and %(max)s pt", + "font_size_default": "%(fontSize)s (default)", "heading": "Customise your appearance", "image_size_default": "Default", "image_size_large": "Large", diff --git a/src/models/Call.ts b/src/models/Call.ts index 10af51ec54..2756573615 100644 --- a/src/models/Call.ts +++ b/src/models/Call.ts @@ -52,11 +52,11 @@ import WidgetStore from "../stores/WidgetStore"; import { WidgetMessagingStore, WidgetMessagingStoreEvent } from "../stores/widgets/WidgetMessagingStore"; import ActiveWidgetStore, { ActiveWidgetStoreEvent } from "../stores/ActiveWidgetStore"; import { getCurrentLanguage } from "../languageHandler"; -import { FontWatcher } from "../settings/watchers/FontWatcher"; import { PosthogAnalytics } from "../PosthogAnalytics"; import { UPDATE_EVENT } from "../stores/AsyncStore"; import { getJoinedNonFunctionalMembers } from "../utils/room/getJoinedNonFunctionalMembers"; import { isVideoRoom } from "../utils/video-rooms"; +import { FontWatcher } from "../settings/watchers/FontWatcher"; const TIMEOUT_MS = 16000; @@ -687,7 +687,8 @@ export class ElementCall extends Call { roomId: roomId, baseUrl: client.baseUrl, lang: getCurrentLanguage().replace("_", "-"), - fontScale: `${(SettingsStore.getValue("baseFontSizeV2") ?? 16) / FontWatcher.DEFAULT_SIZE}`, + fontScale: (FontWatcher.getRootFontSize() / FontWatcher.getBrowserDefaultFontSize()).toString(), + analyticsID, }); diff --git a/src/settings/Settings.tsx b/src/settings/Settings.tsx index 2cdd93e68d..3dc842945e 100644 --- a/src/settings/Settings.tsx +++ b/src/settings/Settings.tsx @@ -511,6 +511,9 @@ export const SETTINGS: { [setting: string]: ISetting } = { supportedLevels: [SettingLevel.CONFIG], default: 0, }, + /** + * @deprecated in favor of {@link fontSizeDelta} + */ "baseFontSize": { displayName: _td("settings|appearance|font_size"), supportedLevels: LEVELS_ACCOUNT_SETTINGS, @@ -530,12 +533,22 @@ export const SETTINGS: { [setting: string]: ISetting } = { * With the transition to Compound we are moving to a base font size * of 16px. We're taking the opportunity to move away from the `baseFontSize` * setting that had a 5px offset. - * + * @deprecated in favor {@link fontSizeDelta} */ "baseFontSizeV2": { displayName: _td("settings|appearance|font_size"), supportedLevels: [SettingLevel.DEVICE], - default: FontWatcher.DEFAULT_SIZE, + default: "", + controller: new FontSizeController(), + }, + /** + * This delta is added to the browser default font size + * Moving from `baseFontSizeV2` to `fontSizeDelta` to replace the default 16px to --cpd-font-size-root (browser default font size) + fontSizeDelta + */ + "fontSizeDelta": { + displayName: _td("settings|appearance|font_size"), + supportedLevels: [SettingLevel.DEVICE], + default: FontWatcher.DEFAULT_DELTA, controller: new FontSizeController(), }, "useCustomFontSize": { diff --git a/src/settings/controllers/FontSizeController.ts b/src/settings/controllers/FontSizeController.ts index 849a2822fe..83a2db198f 100644 --- a/src/settings/controllers/FontSizeController.ts +++ b/src/settings/controllers/FontSizeController.ts @@ -16,7 +16,7 @@ limitations under the License. import SettingController from "./SettingController"; import dis from "../../dispatcher/dispatcher"; -import { UpdateFontSizePayload } from "../../dispatcher/payloads/UpdateFontSizePayload"; +import { UpdateFontSizeDeltaPayload } from "../../dispatcher/payloads/UpdateFontSizeDeltaPayload"; import { Action } from "../../dispatcher/actions"; import { SettingLevel } from "../SettingLevel"; @@ -34,9 +34,9 @@ export default class FontSizeController extends SettingController { dis.fire(Action.MigrateBaseFontSize); } else if (newValue !== "") { // Dispatch font size change so that everything open responds to the change. - dis.dispatch({ - action: Action.UpdateFontSize, - size: newValue, + dis.dispatch({ + action: Action.UpdateFontSizeDelta, + delta: newValue, }); } } diff --git a/src/settings/watchers/FontWatcher.ts b/src/settings/watchers/FontWatcher.ts index bb538d1809..df1a7ba499 100644 --- a/src/settings/watchers/FontWatcher.ts +++ b/src/settings/watchers/FontWatcher.ts @@ -22,20 +22,19 @@ import { Action } from "../../dispatcher/actions"; import { SettingLevel } from "../SettingLevel"; import { UpdateSystemFontPayload } from "../../dispatcher/payloads/UpdateSystemFontPayload"; import { ActionPayload } from "../../dispatcher/payloads"; -import { clamp } from "../../utils/numbers"; export class FontWatcher implements IWatcher { /** - * Value indirectly defined by Compound. - * All `rem` calculations are made from a `16px` values in the - * @vector-im/compound-design-tokens package - * - * We might want to move to using `100%` instead so we can inherit the user - * preference set in the browser regarding font sizes. + * This Compound value is using `100%` of the default browser font size. + * It allows EW to use the browser's default font size instead of a fixed value. + * All the Compound font size are using `rem`, they are relative to the root font size + * and therefore of the browser font size. */ - public static readonly DEFAULT_SIZE = 16; - public static readonly MIN_SIZE = FontWatcher.DEFAULT_SIZE - 5; - public static readonly MAX_SIZE = FontWatcher.DEFAULT_SIZE + 5; + private static readonly DEFAULT_SIZE = "var(--cpd-font-size-root)"; + /** + * Default delta added to the ${@link DEFAULT_SIZE} + */ + public static readonly DEFAULT_DELTA = 0; private dispatcherRef: string | null; @@ -54,28 +53,106 @@ export class FontWatcher implements IWatcher { } /** - * Migrating the old `baseFontSize` for Compound. - * Everything will becomes slightly larger, and getting rid of the `SIZE_DIFF` - * weirdness for locally persisted values + * Migrate the base font size from the V1 and V2 version to the V3 version + * @private */ private async migrateBaseFontSize(): Promise { - const legacyBaseFontSize = SettingsStore.getValue("baseFontSize"); - if (legacyBaseFontSize) { - console.log("Migrating base font size for Compound, current value", legacyBaseFontSize); + await this.migrateBaseFontV1toFontSizeDelta(); + await this.migrateBaseFontV2toFontSizeDelta(); + } - // For some odd reason, the persisted value in user storage has an offset - // of 5 pixels for all values stored under `baseFontSize` - const LEGACY_SIZE_DIFF = 5; - // Compound uses a base font size of `16px`, whereas the old Element - // styles based their calculations off a `15px` root font size. - const ROOT_FONT_SIZE_INCREASE = 1; + /** + * Migrating from the V1 version of the base font size to the new delta system. + * The delta system is using the default browser font size as a base + * Everything will become slightly larger, and getting rid of the `SIZE_DIFF` + * weirdness for locally persisted values + * @private + */ + private async migrateBaseFontV1toFontSizeDelta(): Promise { + const legacyBaseFontSize = SettingsStore.getValue("baseFontSize"); + // No baseFontV1 found, nothing to migrate + if (!legacyBaseFontSize) return; - const baseFontSize = legacyBaseFontSize + ROOT_FONT_SIZE_INCREASE + LEGACY_SIZE_DIFF; + console.log( + "Migrating base font size -> base font size V2 -> font size delta for Compound, current value", + legacyBaseFontSize, + ); - await SettingsStore.setValue("baseFontSizeV2", null, SettingLevel.DEVICE, baseFontSize); - await SettingsStore.setValue("baseFontSize", null, SettingLevel.DEVICE, ""); - console.log("Migration complete, deleting legacy `baseFontSize`"); - } + // Compute the V1 to V2 version before migrating to fontSizeDelta + const baseFontSizeV2 = this.computeBaseFontSizeV1toV2(legacyBaseFontSize); + + // Compute the difference between the V2 and the fontSizeDelta + const delta = this.computeFontSizeDeltaFromV2BaseFontSize(baseFontSizeV2); + + await SettingsStore.setValue("fontSizeDelta", null, SettingLevel.DEVICE, delta); + await SettingsStore.setValue("baseFontSize", null, SettingLevel.DEVICE, 0); + console.log("Migration complete, deleting legacy `baseFontSize`"); + } + + /** + * Migrating from the V2 version of the base font size to the new delta system + * @private + */ + private async migrateBaseFontV2toFontSizeDelta(): Promise { + const legacyBaseFontV2Size = SettingsStore.getValue("baseFontSizeV2"); + // No baseFontV2 found, nothing to migrate + if (!legacyBaseFontV2Size) return; + + console.log("Migrating base font size V2 for Compound, current value", legacyBaseFontV2Size); + + // Compute the difference between the V2 and the fontSizeDelta + const delta = this.computeFontSizeDeltaFromV2BaseFontSize(legacyBaseFontV2Size); + + await SettingsStore.setValue("fontSizeDelta", null, SettingLevel.DEVICE, delta); + await SettingsStore.setValue("baseFontSizeV2", null, SettingLevel.DEVICE, 0); + console.log("Migration complete, deleting legacy `baseFontSizeV2`"); + } + + /** + * Compute the V2 font size from the V1 font size + * @param legacyBaseFontSize + * @private + */ + private computeBaseFontSizeV1toV2(legacyBaseFontSize: number): number { + // For some odd reason, the persisted value in user storage has an offset + // of 5 pixels for all values stored under `baseFontSize` + const LEGACY_SIZE_DIFF = 5; + + // Compound uses a base font size of `16px`, whereas the old Element + // styles based their calculations off a `15px` root font size. + const ROOT_FONT_SIZE_INCREASE = 1; + + // Compute the font size of the V2 version before migrating to V3 + return legacyBaseFontSize + ROOT_FONT_SIZE_INCREASE + LEGACY_SIZE_DIFF; + } + + /** + * Compute the difference between the V2 font size and the default browser font size + * @param legacyBaseFontV2Size + * @private + */ + private computeFontSizeDeltaFromV2BaseFontSize(legacyBaseFontV2Size: number): number { + const browserDefaultFontSize = FontWatcher.getRootFontSize(); + + // Compute the difference between the V2 font size and the default browser font size + return legacyBaseFontV2Size - browserDefaultFontSize; + } + + /** + * Get the root font size of the document + * Fallback to 16px if the value is not found + * @returns {number} + */ + public static getRootFontSize(): number { + return parseInt(window.getComputedStyle(document.documentElement).getPropertyValue("font-size"), 10) || 16; + } + + /** + * Get the browser default font size + * @returns {number} the default font size of the browser + */ + public static getBrowserDefaultFontSize(): number { + return this.getRootFontSize() - SettingsStore.getValue("fontSizeDelta"); } public stop(): void { @@ -84,7 +161,7 @@ export class FontWatcher implements IWatcher { } private updateFont(): void { - this.setRootFontSize(SettingsStore.getValue("baseFontSizeV2")); + this.setRootFontSize(SettingsStore.getValue("fontSizeDelta")); this.setSystemFont({ useBundledEmojiFont: SettingsStore.getValue("useBundledEmojiFont"), useSystemFont: SettingsStore.getValue("useSystemFont"), @@ -95,13 +172,13 @@ export class FontWatcher implements IWatcher { private onAction = (payload: ActionPayload): void => { if (payload.action === Action.MigrateBaseFontSize) { this.migrateBaseFontSize(); - } else if (payload.action === Action.UpdateFontSize) { - this.setRootFontSize(payload.size); + } else if (payload.action === Action.UpdateFontSizeDelta) { + this.setRootFontSize(payload.delta); } else if (payload.action === Action.UpdateSystemFont) { this.setSystemFont(payload as UpdateSystemFontPayload); } else if (payload.action === Action.OnLoggedOut) { // Clear font overrides when logging out - this.setRootFontSize(FontWatcher.DEFAULT_SIZE); + this.setRootFontSize(FontWatcher.DEFAULT_DELTA); this.setSystemFont({ useBundledEmojiFont: false, useSystemFont: false, @@ -113,13 +190,14 @@ export class FontWatcher implements IWatcher { } }; - private setRootFontSize = async (size: number): Promise => { - const fontSize = clamp(size, FontWatcher.MIN_SIZE, FontWatcher.MAX_SIZE); - - if (fontSize !== size) { - await SettingsStore.setValue("baseFontSizeV2", null, SettingLevel.DEVICE, fontSize); - } - document.querySelector(":root")!.style.fontSize = toPx(fontSize); + /** + * Set the root font size of the document + * @param delta {number} the delta to add to the default font size + */ + private setRootFontSize = async (delta: number): Promise => { + // Add the delta to the browser default font size + document.querySelector(":root")!.style.fontSize = + `calc(${FontWatcher.DEFAULT_SIZE} + ${toPx(delta)})`; }; public static readonly FONT_FAMILY_CUSTOM_PROPERTY = "--cpd-font-family-sans"; diff --git a/test/components/views/settings/FontScalingPanel-test.tsx b/test/components/views/settings/FontScalingPanel-test.tsx index deb8df3c50..f2e0710b41 100644 --- a/test/components/views/settings/FontScalingPanel-test.tsx +++ b/test/components/views/settings/FontScalingPanel-test.tsx @@ -15,11 +15,10 @@ limitations under the License. */ import React from "react"; -import { fireEvent, render, waitFor } from "@testing-library/react"; +import { render } from "@testing-library/react"; import * as TestUtils from "../../../test-utils"; import FontScalingPanel from "../../../../src/components/views/settings/FontScalingPanel"; -import SettingsStore from "../../../../src/settings/SettingsStore"; describe("FontScalingPanel", () => { it("renders the font scaling UI", () => { @@ -27,19 +26,4 @@ describe("FontScalingPanel", () => { const { asFragment } = render(); expect(asFragment()).toMatchSnapshot(); }); - - it("should clamp custom font size when disabling it", async () => { - jest.spyOn(SettingsStore, "setValue").mockResolvedValue(undefined); - TestUtils.stubClient(); - const { container, getByText } = render(); - fireEvent.click(getByText("Use custom size")); - await waitFor(() => { - expect(container.querySelector("input[checked]")).toBeDefined(); - }); - fireEvent.change(container.querySelector("#font_size_field")!, { target: { value: "25" } }); - fireEvent.click(getByText("Use custom size")); - await waitFor(() => { - expect(container.querySelector("#font_size_field")).toHaveValue(21); - }); - }); }); diff --git a/test/components/views/settings/__snapshots__/FontScalingPanel-test.tsx.snap b/test/components/views/settings/__snapshots__/FontScalingPanel-test.tsx.snap index d7ac318608..a118c32823 100644 --- a/test/components/views/settings/__snapshots__/FontScalingPanel-test.tsx.snap +++ b/test/components/views/settings/__snapshots__/FontScalingPanel-test.tsx.snap @@ -18,6 +18,117 @@ exports[`FontScalingPanel renders the font scaling UI 1`] = `
+
+ + +
@@ -33,83 +144,6 @@ exports[`FontScalingPanel renders the font scaling UI 1`] = ` />
-
-
- Aa -
-
- - - - 16 - - -
-
- Aa -
-
- - -