Skip to content

Appearance: fonts for themes, and any text size - #115

Open
vitalNohj wants to merge 3 commits into
TannerMidd:mainfrom
vitalNohj:theme-fonts
Open

vitalNohj wants to merge 3 commits into
TannerMidd:mainfrom
vitalNohj:theme-fonts

Conversation

@vitalNohj

Copy link
Copy Markdown
Contributor

Closes #114.

Phone, before Pocket's fonts Fonts for a theme of your own Phone, after
Desktop, before Desktop, after: Inter, Iosevka with ligatures, 16.5 px
Fonts for a theme Text size

What changes

Fonts for a theme, in Appearance (web/sheets/appearance.js, src/server/themes.ts, src/server/http/api.ts)

  • The section is under the theme tools and always named after the theme in use: "Fonts for Reading".
  • Text font: Geist, Inter, System Sans, JetBrains Mono, Fira Code, IBM Plex Mono, Iosevka, System Mono.
  • Code font: JetBrains Mono, Fira Code, IBM Plex Mono, Iosevka, System Mono.
  • Ligatures: on or off.
  • A preview shows text, italics, and code with =>, !== and a comment.
  • On the owner's themes, each choice is saved to the theme's fonts.css, which theme.css imports first. Its values win over the theme's own, so the menus always show what is in use.
    • It goes through a new owner-only PUT /api/themes/:id/fonts, which accepts only the fonts in the menus.
    • The existing theme live-update shows each change in every tab that uses the theme, with no reload.
    • A theme with only colors also gets the theme.json that a stylesheet needs.
  • Pocket and Lantern show their fonts read-only, with Duplicate to change. This uses the existing Duplicate flow.
  • Guests and viewers see no menus. They get the fonts by picking the theme.
  • A theme's own CSS can still set --sans, --mono and --ligatures, as before.

The app's fonts (web/fonts/, web/style.css)

  • @font-face rules for:
    • "Pocket Inter"
    • "Pocket Fira Code"
    • "Pocket IBM Plex Mono"
    • "Pocket Iosevka"
    • "Pocket Nerd Symbols"
    • JetBrains Mono's italic for "Pocket Mono"
  • Each file comes from the project's own GitHub release and was checked against GitHub's SHA-256 digest. Licenses are included, and web/fonts/SOURCES.md lists where each file came from.
    • Fira Code 6.2
    • IBM Plex Mono variable 1.0.0
    • Inter 4.1
    • Iosevka 34.9.0 (unhinted, Regular/SemiBold/Bold and their italics)
    • Nerd Fonts 3.5.1 "Symbols Only" Mono, cut down to its icon ranges
  • The Nerd Fonts icons are in the default --mono, after JetBrains Mono.
    • The icon file has a unicode-range, so a browser downloads it only when an icon shows.
    • Each icon is one character wide, so columns still line up.

Preload and re-fit (web/index.html, src/server/themes.ts, web/composer.js)

  • The theme list now names the app's font files a theme uses. Before, it named only the theme's own files. index.html preloads them before the first paint, so a reload doesn't flash Geist or JetBrains Mono first.
  • The message box and the status line now re-fit after the theme changes or a font finishes loading. Before, a wider font left the box too short until you typed again.

Text size (web/theme.js, web/sheets/appearance.js)

  • Buttons for 13, 15, 17 and 20, plus a field for any size from 10 to 32 px, in half-pixel steps.
  • A value outside the range is kept to it. Saved sizes from before still work.

Docs: docs/extensions/themes.md (the app's fonts and Fonts for), docs/extensions/reference/theme-surface.md, docs/features.md, and font credits in README.md.

Size: about 1,100 lines without the font files: roughly 500 of tests, about 220 of CSS, and the rest code and docs. A browser downloads only the fonts its theme uses. Iosevka is the largest, at about 3.4 MB for all six files.

Tests

  • test/font-ui.test.ts (Chromium), 6 tests:
    • The default look keeps Geist and JetBrains Mono, with JetBrains Mono's real italic for comments.
    • A guest who picks the owner's theme gets its fonts and ligatures, preloaded on reload.
    • The message box re-fits when a theme's wider font loads. This fails without the composer.js change.
    • The Nerd Fonts icon file loads only for icons, and each icon is one character wide.
    • The owner's flow:
      • Pocket shows its fonts and Duplicate to change.
      • On a theme of the owner's, a pick shows at once and is still there after a reload.
    • A typed text size of 27.5 px is used and stays; 99 is kept to 32.
  • test/themes.test.ts, 2 tests:
    • The app's fonts a theme uses are preloaded, and a font named only in a CSS comment is ignored. This fails without the themes.ts and index.html changes.
    • Saving fonts:
      • writes fonts.css, keeps the theme's own CSS, and imports fonts.css only once;
      • handles System Sans and System Mono;
      • refuses fonts not in the menus, and Pocket and Lantern;
      • leaves a colors-only theme usable.
  • On main (0.19.0): all 392 tests pass. npm run check, ESLint and Prettier pass.
  • Tried by hand on a live Pocket, phone and desktop sizes: duplicate Pocket, pick fonts on the copy, type a text size.

Themes already choose the fonts and ligatures (--sans, --mono,
--ligatures). This gives them more to choose from, and fixes two gaps when
a theme changes the font.

- The app bundles Inter, Fira Code, IBM Plex Mono, and Iosevka, which a
  theme names in --sans or --mono ("Pocket Inter", ...) instead of shipping
  font files of its own. A browser downloads only the ones a theme uses.
- Real italics: JetBrains Mono, Inter, IBM Plex Mono, and Iosevka bring
  their own italic files, so code comments and emphasis are no longer
  slanted by the browser. The default look gains JetBrains Mono's italic.
- The Nerd Fonts icons that prompts and tools print, as a font of icons
  alone in the default --mono, fetched only when an icon shows.
- No flash on reload: the page preloads the app's fonts a theme names, as
  it does the theme's own. Before, it preloaded Geist and JetBrains Mono
  and then switched.
- The message box and the status line measure again when a theme's
  stylesheets or a font finish loading. Before, a theme with a wider font
  left the box too short for its text until the next keystroke.

web/fonts/SOURCES.md says where each font came from and how it was
checked; Iosevka and the Nerd Fonts symbols are trimmed, with every name
kept. The theme guide lists the fonts a theme can name.
Under the theme tools, the owner picks the theme in use's Text font,
Code font, and Ligatures, with a preview. Each choice is saved into the
theme (its fonts.css, which theme.css imports first, and whose values
win over the theme's own), so everyone who uses it gets it at once. A
theme that comes with the app is duplicated first; a theme of colors
alone gets the stylesheet and the theme.json it needs.
- "Fonts for <theme>" is always there: a theme of the owner's has the
  menus; one that comes with the app shows its fonts, with Duplicate to
  change.
- System Sans and System Mono, the device's own fonts, in the menus.
- Text size: 13, 15, 17, or 20, or any size from 10 to 32 px typed in,
  in half pixels.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Appearance: choose a theme's fonts, and any text size

1 participant