Merge pull request #783 from robintown/font-params

Add URL params to control fonts
This commit is contained in:
Robin 2022-12-10 18:55:35 -05:00 committed by GitHub
commit f9845617b3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 156 additions and 58 deletions

View file

@ -131,7 +131,7 @@
}
.leftNav h3 {
font-size: 18px;
font-size: var(--font-size-subtitle);
}
.nav {

View file

@ -19,7 +19,7 @@
padding: 8px 16px;
outline: none;
cursor: pointer;
font-size: 15px;
font-size: var(--font-size-body);
min-height: 32px;
}

View file

@ -12,7 +12,10 @@
align-items: center;
padding: 0 12px;
color: var(--primary-content);
font-size: 14px;
font-size: var(--font-size-body);
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.menuItem > * {

View file

@ -29,7 +29,7 @@
.modalHeader h3 {
font-weight: 600;
font-size: 24px;
font-size: var(--font-size-title);
margin: 0;
}

View file

@ -8,7 +8,7 @@
border-radius: 8px;
max-width: 135px;
width: max-content;
font-size: 12px;
font-size: var(--font-size-caption);
font-weight: 500;
text-align: center;
}

View file

@ -21,30 +21,60 @@ export interface UrlParams {
roomAlias: string | null;
roomId: string | null;
viaServers: string[];
// Whether the app is running in embedded mode, and should keep the user
// confined to the current room
/**
* Whether the app is running in embedded mode, and should keep the user
* confined to the current room.
*/
isEmbedded: boolean;
// Whether the app should pause before joining the call until it sees an
// io.element.join widget action, allowing it to be preloaded
/**
* Whether the app should pause before joining the call until it sees an
* io.element.join widget action, allowing it to be preloaded.
*/
preload: boolean;
// Whether to hide the room header when in a call
/**
* Whether to hide the room header when in a call.
*/
hideHeader: boolean;
// Whether to hide the screen-sharing button
/**
* Whether to hide the screen-sharing button.
*/
hideScreensharing: boolean;
// Whether to start a walkie-talkie call instead of a video call
/**
* Whether to start a walkie-talkie call instead of a video call.
*/
isPtt: boolean;
// Whether to use end-to-end encryption
/**
* Whether to use end-to-end encryption.
*/
e2eEnabled: boolean;
// The user's ID (only used in matryoshka mode)
/**
* The user's ID (only used in matryoshka mode).
*/
userId: string | null;
// The display name to use for auto-registration
/**
* The display name to use for auto-registration.
*/
displayName: string | null;
// The device's ID (only used in matryoshka mode)
/**
* The device's ID (only used in matryoshka mode).
*/
deviceId: string | null;
// The base URL of the homeserver to use for media lookups in matryoshka mode
/**
* The base URL of the homeserver to use for media lookups in matryoshka mode.
*/
baseUrl: string | null;
// The BCP 47 code of the language the app should use
/**
* The BCP 47 code of the language the app should use.
*/
lang: string | null;
/**
* The fonts which the interface should use, if not empty.
*/
fonts: string[];
/**
* The factor by which to scale the interface's font size.
*/
fontScale: number | null;
}
/**
@ -81,6 +111,8 @@ export const getUrlParams = (
? fragment
: fragment.substring(0, fragmentQueryStart);
const fontScale = parseFloat(getParam("fontScale") ?? "");
return {
roomAlias: fragmentRoute.length > 1 ? fragmentRoute : null,
roomId: getParam("roomId"),
@ -96,6 +128,8 @@ export const getUrlParams = (
deviceId: getParam("deviceId"),
baseUrl: getParam("baseUrl"),
lang: getParam("lang"),
fonts: getAllParams("font"),
fontScale: Number.isNaN(fontScale) ? null : fontScale,
};
};

View file

@ -10,13 +10,13 @@
.avatar {
width: 24px;
height: 24px;
font-size: 12px;
font-size: var(--font-size-caption);
}
@media (min-width: 800px) {
.avatar {
width: 32px;
height: 32px;
font-size: 15px;
font-size: var(--font-size-body);
}
}

View file

@ -36,7 +36,7 @@
.formContainer h4 {
font-weight: normal;
font-size: 18px;
font-size: var(--font-size-subtitle);
margin-bottom: 0;
}
@ -48,7 +48,7 @@
.formContainer button {
height: 48px;
width: 100%;
font-size: 15px;
font-size: var(--font-size-body);
font-weight: 600;
}
@ -61,7 +61,7 @@
.authLinks {
margin-bottom: 100px;
font-size: 15px;
font-size: var(--font-size-body);
}
.authLinks a {

View file

@ -41,7 +41,7 @@ limitations under the License.
.copyButton {
padding: 7px 15px;
border-radius: 8px;
font-size: 14px;
font-size: var(--font-size-body);
font-weight: 700;
}
@ -142,7 +142,7 @@ limitations under the License.
.copyButton span {
font-weight: 600;
font-size: 15px;
font-size: var(--font-size-body);
margin-right: 10px;
overflow: hidden;
white-space: nowrap;

View file

@ -23,8 +23,20 @@ limitations under the License.
@import "normalize.css/normalize.css";
:root {
--font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI",
"Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans",
"Helvetica Neue", sans-serif;
--inter-unicode-range: U+0000-20e2, U+20e4-23ce, U+23d0-24c1, U+24c3-259f,
U+25c2-2664, U+2666-2763, U+2765-2b05, U+2b07-2b1b, U+2b1d-10FFFF;
--font-scale: 1;
--font-size-micro: calc(10px * var(--font-scale));
--font-size-caption: calc(12px * var(--font-scale));
--font-size-body: calc(15px * var(--font-scale));
--font-size-subtitle: calc(18px * var(--font-scale));
--font-size-title: calc(24px * var(--font-scale));
--font-size-headline: calc(32px * var(--font-scale));
--accent: #0dbd8b;
--accent-20: #0dbd8b33;
--alert: #ff5b55;
@ -127,9 +139,7 @@ body {
color: var(--primary-content);
color-scheme: dark;
margin: 0;
font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto",
"Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
font-family: var(--font-family);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
@ -159,28 +169,31 @@ a {
/* Headline Semi Bold */
h1 {
font-weight: 600;
font-size: 32px;
line-height: 39px;
font-size: var(--font-size-headline);
}
/* Title */
h2 {
font-weight: 600;
font-size: 24px;
line-height: 29px;
font-size: var(--font-size-title);
}
/* Subtitle */
h3 {
font-weight: 400;
font-size: 18px;
line-height: 22px;
font-size: var(--font-size-subtitle);
}
h1,
h2,
h3 {
line-height: 1.2;
}
/* Body */
p {
font-size: 15px;
line-height: 24px;
font-size: var(--font-size-body);
line-height: var(--font-size-title);
}
a {
@ -202,21 +215,21 @@ hr {
text-align: center;
height: 5px;
font-weight: 600;
font-size: 15px;
font-size: var(--font-size-body);
line-height: 24px;
margin: 0 12px;
}
summary {
font-size: 14px;
font-size: var(--font-size-body);
}
details > :not(summary) {
margin-left: 16px;
margin-left: var(--font-size-body);
}
details[open] > summary {
margin-bottom: 16px;
margin-bottom: var(--font-size-body);
}
#root > [data-overlay-container] {

View file

@ -133,6 +133,21 @@ export class Initializer {
import.meta.env.VITE_THEME_BACKGROUND_85 as string
);
}
// Custom fonts
const { fonts, fontScale } = getUrlParams();
if (fontScale !== null) {
document.documentElement.style.setProperty(
"--font-scale",
fontScale.toString()
);
}
if (fonts.length > 0) {
document.documentElement.style.setProperty(
"--font-family",
fonts.map((f) => `"${f}"`).join(", ")
);
}
}
public static init(): Promise<void> | null {

View file

@ -32,7 +32,7 @@
.inputField input,
.inputField textarea {
font-weight: 400;
font-size: 15px;
font-size: var(--font-size-body);
border: none;
border-radius: 4px;
padding: 12px 9px 10px 9px;
@ -73,7 +73,7 @@
top 0.25s ease-out 0.1s, background-color 0.25s ease-out 0.1s;
color: var(--tertiary-content);
background-color: transparent;
font-size: 15px;
font-size: var(--font-size-body);
position: absolute;
left: 0;
top: 0;
@ -104,7 +104,7 @@
background-color: var(--system);
transition: font-size 0.25s ease-out 0s, color 0.25s ease-out 0s,
top 0.25s ease-out 0s, background-color 0.25s ease-out 0s;
font-size: 10px;
font-size: var(--font-size-micro);
top: -13px;
padding: 0 2px;
pointer-events: auto;
@ -125,7 +125,7 @@
display: flex;
align-items: center;
flex-grow: 1;
font-size: 15px;
font-size: var(--font-size-body);
line-height: 24px;
}
@ -174,7 +174,7 @@
.errorMessage {
margin: 0;
font-size: 13px;
font-size: var(--font-size-caption);
color: var(--alert);
font-weight: 600;
}

View file

@ -7,7 +7,7 @@
.label {
font-weight: 600;
font-size: 18px;
font-size: var(--font-size-subtitle);
margin-top: 0;
margin-bottom: 12px;
}
@ -20,7 +20,7 @@
background-color: var(--background);
border-radius: 8px;
border: 1px solid var(--quinary-content);
font-size: 15px;
font-size: var(--font-size-body);
color: var(--primary-content);
height: 40px;
max-width: 100%;

View file

@ -19,7 +19,7 @@
}
.sequenceDiagramViewer :global(.messageText) {
font-size: 12px;
font-size: var(--font-size-caption);
fill: var(--primary-content) !important;
stroke: var(--primary-content) !important;
}

View file

@ -54,7 +54,7 @@ limitations under the License.
bottom: 86px;
left: 50%;
font-weight: 600;
font-size: 15px;
font-size: var(--font-size-body);
transform: translateX(-50%);
}

View file

@ -64,7 +64,7 @@
.actionTip {
margin-top: 20px;
margin-bottom: 20px;
font-size: 17px;
font-size: var(--font-size-subtitle);
}
.footer {

View file

@ -1,11 +1,11 @@
.caption {
font-size: 12px;
line-height: 15px;
font-size: var(--font-size-caption);
line-height: var(--font-size-body);
}
.micro {
font-size: 10px;
line-height: 12px;
font-size: var(--font-size-micro);
line-height: var(--font-size-caption);
}
.regular {

View file

@ -119,9 +119,9 @@
}
.memberName span {
font-size: 12px;
font-size: var(--font-size-caption);
font-weight: 400;
line-height: 16px;
line-height: var(--font-size-body);
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
@ -152,8 +152,8 @@
align-items: center;
padding: 4px 8px;
font-weight: normal;
font-size: 12px;
line-height: 15px;
font-size: var(--font-size-caption);
line-height: var(--font-size-body);
}
.screensharePIP {

33
test/initializer-test.ts Normal file
View file

@ -0,0 +1,33 @@
/*
Copyright 2022 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { Initializer } from "../src/initializer";
test("initBeforeReact sets font family from URL param", () => {
window.location.hash = "#?font=DejaVu Sans";
Initializer.initBeforeReact();
expect(
getComputedStyle(document.documentElement).getPropertyValue("--font-family")
).toBe('"DejaVu Sans"');
});
test("initBeforeReact sets font scale from URL param", () => {
window.location.hash = "#?fontScale=1.2";
Initializer.initBeforeReact();
expect(
getComputedStyle(document.documentElement).getPropertyValue("--font-scale")
).toBe("1.2");
});