From 4c4b69d23212307cb63ca3bff6470caabaefb500 Mon Sep 17 00:00:00 2001 From: Oleg Isonen Date: Sun, 15 Sep 2024 16:21:07 +0100 Subject: [PATCH 01/14] Key is now category not just the exact font name --- packages/fonts/src/constants.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/fonts/src/constants.ts b/packages/fonts/src/constants.ts index 1696a5c24036..8e5d42797894 100644 --- a/packages/fonts/src/constants.ts +++ b/packages/fonts/src/constants.ts @@ -1,12 +1,12 @@ import type { FontFormat } from "./schema"; export const SYSTEM_FONTS = new Map([ - ["Arial", ["Roboto", "sans-serif"]], - ["Times New Roman", ["sans"]], - ["Courier New", ["monospace"]], - ["system-ui", []], - ["SimSun", ["Songti SC, sans-serif"]], - ["PingFang SC", ["Microsoft Ya Hei", "sans-serif"]], + ["Arial", ["Arial", "Roboto", "sans-serif"]], + ["Times New Roman", ["Times New Roman", "sans"]], + ["Courier New", ["Courier New", "monospace"]], + ["system-ui", ["system-ui"]], + ["SimSun", ["SimSun", "Songti SC, sans-serif"]], + ["PingFang SC", ["PingFang SC", "Microsoft Ya Hei", "sans-serif"]], ]); export const DEFAULT_FONT_FALLBACK = "sans-serif"; From 0112db447b943224f12dcd79d994718a2a12d476 Mon Sep 17 00:00:00 2001 From: Oleg Isonen Date: Sun, 15 Sep 2024 17:34:37 +0100 Subject: [PATCH 02/14] add modern font stacks --- .../shared/fonts-manager/fonts-manager.tsx | 39 ++++- .../src/components/__DEPRECATED__/list.tsx | 2 +- packages/fonts/src/constants.ts | 147 +++++++++++++++++- 3 files changed, 184 insertions(+), 4 deletions(-) diff --git a/apps/builder/app/builder/shared/fonts-manager/fonts-manager.tsx b/apps/builder/app/builder/shared/fonts-manager/fonts-manager.tsx index 290da8720642..1d07a0720932 100644 --- a/apps/builder/app/builder/shared/fonts-manager/fonts-manager.tsx +++ b/apps/builder/app/builder/shared/fonts-manager/fonts-manager.tsx @@ -5,6 +5,10 @@ import { theme, useSearchFieldKeys, findNextListItemIndex, + Tooltip, + Text, + rawTheme, + Link, } from "@webstudio-is/design-system"; import { AssetsShell, @@ -14,7 +18,7 @@ import { } from "~/builder/shared/assets"; import { useEffect, useMemo, useState } from "react"; import { useMenu } from "./item-menu"; -import { CheckMarkIcon } from "@webstudio-is/icons"; +import { CheckMarkIcon, InfoCircleIcon } from "@webstudio-is/icons"; import { type Item, filterIdsByFamily, @@ -167,7 +171,38 @@ export const FontsManager = ({ value, onChange }: FontsManagerProps) => { {uploadedItems.length !== 0 && ( )} - {"System"} + + { + "System font stack CSS organized by typeface classification for every modern OS. No downloading, no layout shifts, no flashes—just instant renders. Learn more about " + } + + modern font stacks + + . + + } + > + + + } + > + System + )} {systemItems.map((item, index) => diff --git a/packages/design-system/src/components/__DEPRECATED__/list.tsx b/packages/design-system/src/components/__DEPRECATED__/list.tsx index 790b00ab355d..73b09f9eee65 100644 --- a/packages/design-system/src/components/__DEPRECATED__/list.tsx +++ b/packages/design-system/src/components/__DEPRECATED__/list.tsx @@ -82,7 +82,7 @@ export const DeprecatedListItem = forwardRef< {children} diff --git a/packages/fonts/src/constants.ts b/packages/fonts/src/constants.ts index 8e5d42797894..555387bbb73e 100644 --- a/packages/fonts/src/constants.ts +++ b/packages/fonts/src/constants.ts @@ -4,7 +4,152 @@ export const SYSTEM_FONTS = new Map([ ["Arial", ["Arial", "Roboto", "sans-serif"]], ["Times New Roman", ["Times New Roman", "sans"]], ["Courier New", ["Courier New", "monospace"]], - ["system-ui", ["system-ui"]], + ["System UI", ["system-ui", "sans-serif"]], + // Modern font stacks + // https://github.com/system-fonts/modern-font-stacks + [ + "Transitional", + ["Charter", "Bitstream Charter", "Sitka Text", "Cambria", "serif"], + ], + [ + "Old Style", + ["Iowan Old Style", "Palatino Linotype", "URW Palladio L", "P052", "serif"], + ], + [ + "Humanist", + [ + "Seravek", + "Gill Sans Nova", + "Ubuntu", + "Calibri", + "DejaVu Sans", + "source-sans-pro", + "sans-serif", + ], + ], + [ + "Geometric Humanist", + [ + "Seravek", + "Avenir", + "Montserrat", + "Corbel", + "URW Gothic", + "source-sans-pro", + "sans-serif", + ], + ], + [ + "Classical Humanist", + ["Optima", "Candara", "Noto Sans", "source-sans-pro", "sans-serif"], + ], + [ + "Neo-Grotesque", + [ + "Inter", + "Roboto", + "Helvetica Neue", + "Arial Nova", + "Nimbus Sans", + "Arial", + "sans-serif", + ], + ], + ["Monospace Slab Serif", ["Nimbus Mono PS", "Courier New", "monospace"]], + [ + "Monospace Code", + [ + "ui-monospace", + "Cascadia Code", + "Source Code Pro", + "Menlo", + "Consolas", + "DejaVu Sans Mono", + "monospace", + ], + ], + [ + "Industrial", + [ + "Bahnschrift", + "DIN Alternate", + "Franklin Gothic Medium", + "Nimbus Sans Narrow", + "sans-serif-condensed", + "sans-serif", + ], + ], + [ + "Rounded Sans", + [ + "ui-rounded", + "Hiragino Maru Gothic ProN", + "Quicksand", + "Comfortaa", + "Manjari", + "Arial Rounded MT", + "Arial Rounded MT Bold", + "Calibri", + "source-sans-pro", + "sans-serif", + ], + ], + [ + "Slab Serif", + [ + "Rockwell", + "Rockwell Nova", + "Roboto Slab", + "DejaVu Serif", + "Sitka Small", + "serif", + ], + ], + [ + "Antique", + [ + "Superclarendon", + "Bookman Old Style", + "URW Bookman", + "URW Bookman L", + "Georgia Pro", + "Georgia", + "serif", + ], + ], + [ + "Didone", + [ + "Didot", + "Bodoni MT", + "Noto Serif Display", + "URW Palladio L", + "P052", + "Sylfaen", + "serif", + ], + ], + [ + "Handwritten", + [ + "Segoe Print", + "Bradley Hand", + "Chilanka", + "TSCu_Comic", + "casual", + "cursive", + ], + ], + [ + "Emoji", + [ + "Apple Color Emoji", + "Segoe UI Emoji", + "Segoe UI Symbol", + "Noto Color Emoji", + ], + ], + // Chineese fonts ["SimSun", ["SimSun", "Songti SC, sans-serif"]], ["PingFang SC", ["PingFang SC", "Microsoft Ya Hei", "sans-serif"]], ]); From 462062ea95b7096a5ee73f6407afced008696a52 Mon Sep 17 00:00:00 2001 From: Oleg Isonen Date: Sun, 15 Sep 2024 17:43:00 +0100 Subject: [PATCH 03/14] tooltip formatting --- apps/builder/app/builder/shared/fonts-manager/fonts-manager.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/builder/app/builder/shared/fonts-manager/fonts-manager.tsx b/apps/builder/app/builder/shared/fonts-manager/fonts-manager.tsx index 1d07a0720932..de4b102dda4c 100644 --- a/apps/builder/app/builder/shared/fonts-manager/fonts-manager.tsx +++ b/apps/builder/app/builder/shared/fonts-manager/fonts-manager.tsx @@ -179,7 +179,7 @@ export const FontsManager = ({ value, onChange }: FontsManagerProps) => { content={ { - "System font stack CSS organized by typeface classification for every modern OS. No downloading, no layout shifts, no flashes—just instant renders. Learn more about " + "System font stack CSS organized by typeface classification for every modern OS. No downloading, no layout shifts, no flashes — just instant renders. Learn more about " } Date: Sun, 15 Sep 2024 17:45:15 +0100 Subject: [PATCH 04/14] put old fonts at the end --- packages/fonts/src/constants.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/fonts/src/constants.ts b/packages/fonts/src/constants.ts index 555387bbb73e..3ce9bdc88bd9 100644 --- a/packages/fonts/src/constants.ts +++ b/packages/fonts/src/constants.ts @@ -1,9 +1,6 @@ import type { FontFormat } from "./schema"; export const SYSTEM_FONTS = new Map([ - ["Arial", ["Arial", "Roboto", "sans-serif"]], - ["Times New Roman", ["Times New Roman", "sans"]], - ["Courier New", ["Courier New", "monospace"]], ["System UI", ["system-ui", "sans-serif"]], // Modern font stacks // https://github.com/system-fonts/modern-font-stacks @@ -148,6 +145,9 @@ export const SYSTEM_FONTS = new Map([ "Segoe UI Symbol", "Noto Color Emoji", ], + ["Arial", ["Arial", "Roboto", "sans-serif"]], + ["Times New Roman", ["Times New Roman", "sans"]], + ["Courier New", ["Courier New", "monospace"]], ], // Chineese fonts ["SimSun", ["SimSun", "Songti SC, sans-serif"]], From 43cd88f745e91b82d1d0f702d610062c7f56b8b1 Mon Sep 17 00:00:00 2001 From: Oleg Isonen Date: Sun, 15 Sep 2024 17:47:03 +0100 Subject: [PATCH 05/14] fix geometric humanist --- packages/fonts/src/constants.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/fonts/src/constants.ts b/packages/fonts/src/constants.ts index 3ce9bdc88bd9..3b7af7fedafa 100644 --- a/packages/fonts/src/constants.ts +++ b/packages/fonts/src/constants.ts @@ -27,7 +27,6 @@ export const SYSTEM_FONTS = new Map([ [ "Geometric Humanist", [ - "Seravek", "Avenir", "Montserrat", "Corbel", From 48cf02755c951777561c50668ff8a4201d5d54f0 Mon Sep 17 00:00:00 2001 From: Oleg Isonen Date: Sun, 15 Sep 2024 20:17:12 +0100 Subject: [PATCH 06/14] fix old system fonts --- packages/fonts/src/constants.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/fonts/src/constants.ts b/packages/fonts/src/constants.ts index 3b7af7fedafa..c8f7f239a3f1 100644 --- a/packages/fonts/src/constants.ts +++ b/packages/fonts/src/constants.ts @@ -144,10 +144,10 @@ export const SYSTEM_FONTS = new Map([ "Segoe UI Symbol", "Noto Color Emoji", ], - ["Arial", ["Arial", "Roboto", "sans-serif"]], - ["Times New Roman", ["Times New Roman", "sans"]], - ["Courier New", ["Courier New", "monospace"]], ], + ["Arial", ["Arial", "Roboto", "sans-serif"]], + ["Times New Roman", ["Times New Roman", "sans"]], + ["Courier New", ["Courier New", "monospace"]], // Chineese fonts ["SimSun", ["SimSun", "Songti SC, sans-serif"]], ["PingFang SC", ["PingFang SC", "Microsoft Ya Hei", "sans-serif"]], From 584a910235cd146bfb07d0e82ae16aea4888f7f3 Mon Sep 17 00:00:00 2001 From: Oleg Isonen Date: Sun, 15 Sep 2024 22:47:17 +0100 Subject: [PATCH 07/14] use mapped value --- packages/css-engine/src/core/to-value.test.ts | 17 ++++++++++------- packages/css-engine/src/core/to-value.ts | 5 ++--- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/packages/css-engine/src/core/to-value.test.ts b/packages/css-engine/src/core/to-value.test.ts index 9cb7a3fb4c3c..37c4d981df9b 100644 --- a/packages/css-engine/src/core/to-value.test.ts +++ b/packages/css-engine/src/core/to-value.test.ts @@ -47,11 +47,14 @@ describe("Convert WS CSS Values to native CSS strings", () => { }); test("fontFamily", () => { - const value = toValue({ - type: "fontFamily", - value: ["Courier New"], - }); - expect(value).toBe('"Courier New", monospace'); + expect( + toValue({ + type: "fontFamily", + value: ["Emoji"], + }) + ).toBe( + '"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"' + ); }); test("Transform font family value to override default fallback", () => { @@ -64,12 +67,12 @@ describe("Convert WS CSS Values to native CSS strings", () => { if (styleValue.type === "fontFamily") { return { type: "fontFamily", - value: [styleValue.value[0]], + value: ["A B"], }; } } ); - expect(value).toBe('"Courier New"'); + expect(value).toBe('"A B"'); }); test("array", () => { diff --git a/packages/css-engine/src/core/to-value.ts b/packages/css-engine/src/core/to-value.ts index 10f4d2aa927e..295ad97d31b2 100644 --- a/packages/css-engine/src/core/to-value.ts +++ b/packages/css-engine/src/core/to-value.ts @@ -7,12 +7,11 @@ export type TransformValue = (styleValue: StyleValue) => undefined | StyleValue; const fallbackTransform: TransformValue = (styleValue) => { if (styleValue.type === "fontFamily") { const firstFontFamily = styleValue.value[0]; - - const fontFamily = styleValue.value; + const fontFamily = SYSTEM_FONTS.get(firstFontFamily); const fallbacks = SYSTEM_FONTS.get(firstFontFamily) ?? [ DEFAULT_FONT_FALLBACK, ]; - const value = Array.from(new Set([...fontFamily, ...fallbacks])); + const value = Array.from(new Set([...(fontFamily ?? []), ...fallbacks])); return { type: "fontFamily", From 35b2ea369b9d14cd29b4949dde0803ce95444125 Mon Sep 17 00:00:00 2001 From: Oleg Isonen Date: Sun, 15 Sep 2024 23:18:27 +0100 Subject: [PATCH 08/14] add descriptions --- .../shared/fonts-manager/fonts-manager.tsx | 15 +- .../shared/fonts-manager/item-utils.ts | 2 + packages/css-engine/src/core/to-value.ts | 6 +- packages/fonts/src/constants.ts | 300 +++++++++++------- 4 files changed, 210 insertions(+), 113 deletions(-) diff --git a/apps/builder/app/builder/shared/fonts-manager/fonts-manager.tsx b/apps/builder/app/builder/shared/fonts-manager/fonts-manager.tsx index de4b102dda4c..737573072cf4 100644 --- a/apps/builder/app/builder/shared/fonts-manager/fonts-manager.tsx +++ b/apps/builder/app/builder/shared/fonts-manager/fonts-manager.tsx @@ -141,7 +141,18 @@ export const FontsManager = ({ value, onChange }: FontsManagerProps) => { {...itemProps} key={key} prefix={itemProps.current ? : undefined} - suffix={item.type === "uploaded" ? renderMenu(index) : undefined} + suffix={ + item.type === "uploaded" ? ( + renderMenu(index) + ) : itemProps.state === "selected" && item.description ? ( + + + + ) : undefined + } > {item.label} @@ -179,7 +190,7 @@ export const FontsManager = ({ value, onChange }: FontsManagerProps) => { content={ { - "System font stack CSS organized by typeface classification for every modern OS. No downloading, no layout shifts, no flashes — just instant renders. Learn more about " + "System font stack CSS organized by typeface classification for every modern OS. No downloading, no layout shifts, no flashes— just instant renders. Learn more about " } ({ label, type: "system", + description: SYSTEM_FONTS.get(label)?.description, })); // We can have 2+ assets with the same family name, so we use a map to dedupe. const uploaded = new Map(); diff --git a/packages/css-engine/src/core/to-value.ts b/packages/css-engine/src/core/to-value.ts index 295ad97d31b2..25f3c20d35c8 100644 --- a/packages/css-engine/src/core/to-value.ts +++ b/packages/css-engine/src/core/to-value.ts @@ -6,12 +6,10 @@ export type TransformValue = (styleValue: StyleValue) => undefined | StyleValue; const fallbackTransform: TransformValue = (styleValue) => { if (styleValue.type === "fontFamily") { - const firstFontFamily = styleValue.value[0]; - const fontFamily = SYSTEM_FONTS.get(firstFontFamily); - const fallbacks = SYSTEM_FONTS.get(firstFontFamily) ?? [ + const fonts = SYSTEM_FONTS.get(styleValue.value[0])?.stack ?? [ DEFAULT_FONT_FALLBACK, ]; - const value = Array.from(new Set([...(fontFamily ?? []), ...fallbacks])); + const value = Array.from(new Set(fonts)); return { type: "fontFamily", diff --git a/packages/fonts/src/constants.ts b/packages/fonts/src/constants.ts index c8f7f239a3f1..85ef75665af4 100644 --- a/packages/fonts/src/constants.ts +++ b/packages/fonts/src/constants.ts @@ -1,156 +1,242 @@ import type { FontFormat } from "./schema"; export const SYSTEM_FONTS = new Map([ - ["System UI", ["system-ui", "sans-serif"]], + [ + "System UI", + { + stack: ["system-ui", "sans-serif"], + description: + "System UI fonts are those native to the operating system interface. They are highly legible and easy to read at small sizes, contains many font weights, and is ideal for UI elements.", + }, + ], // Modern font stacks // https://github.com/system-fonts/modern-font-stacks [ "Transitional", - ["Charter", "Bitstream Charter", "Sitka Text", "Cambria", "serif"], + { + stack: ["Charter", "Bitstream Charter", "Sitka Text", "Cambria", "serif"], + description: + "Transitional typefaces are a mix between Old Style and Modern typefaces that was developed during The Enlightenment. One of the most famous examples of a Transitional typeface is Times New Roman, which was developed for the Times of London newspaper.", + }, ], [ "Old Style", - ["Iowan Old Style", "Palatino Linotype", "URW Palladio L", "P052", "serif"], + { + stack: [ + "Iowan Old Style", + "Palatino Linotype", + "URW Palladio L", + "P052", + "serif", + ], + description: + "Old Style typefaces are characterized by diagonal stress, low contrast between thick and thin strokes, and rounded serifs, and were developed in the Renaissance period. One of the most famous examples of an Old Style typeface is Garamond.", + }, ], [ "Humanist", - [ - "Seravek", - "Gill Sans Nova", - "Ubuntu", - "Calibri", - "DejaVu Sans", - "source-sans-pro", - "sans-serif", - ], + { + stack: [ + "Seravek", + "Gill Sans Nova", + "Ubuntu", + "Calibri", + "DejaVu Sans", + "source-sans-pro", + "sans-serif", + ], + description: + "Humanist typefaces are characterized by their organic, calligraphic forms and low contrast between thick and thin strokes. These typefaces are inspired by the handwriting of the Renaissance period and are often considered to be more legible and easier to read than other sans-serif typefaces.", + }, ], [ "Geometric Humanist", - [ - "Avenir", - "Montserrat", - "Corbel", - "URW Gothic", - "source-sans-pro", - "sans-serif", - ], + { + stack: [ + "Avenir", + "Montserrat", + "Corbel", + "URW Gothic", + "source-sans-pro", + "sans-serif", + ], + description: + "Geometric Humanist typefaces are characterized by their clean, geometric forms and uniform stroke widths. These typefaces are often considered to be modern and sleek in appearance, and are often used for headlines and other display purposes. Futura is a famous example of this classification.", + }, ], [ "Classical Humanist", - ["Optima", "Candara", "Noto Sans", "source-sans-pro", "sans-serif"], + { + stack: [ + "Optima", + "Candara", + "Noto Sans", + "source-sans-pro", + "sans-serif", + ], + description: + "Classical Humanist typefaces are characterized by how the strokes subtly widen as they reach the stroke terminals without ending in a serif. These typefaces are inspired by classical Roman capitals and the stone-carving on Renaissance-period tombstones.", + }, ], [ "Neo-Grotesque", - [ - "Inter", - "Roboto", - "Helvetica Neue", - "Arial Nova", - "Nimbus Sans", - "Arial", - "sans-serif", - ], - ], - ["Monospace Slab Serif", ["Nimbus Mono PS", "Courier New", "monospace"]], + { + stack: [ + "Inter", + "Roboto", + "Helvetica Neue", + "Arial Nova", + "Nimbus Sans", + "Arial", + "sans-serif", + ], + description: + "Neo-Grotesque typefaces are a style of sans-serif that was developed in the late 19th and early 20th centuries and is characterized by its clean, geometric forms and uniform stroke widths. One of the most famous examples of a Neo-Grotesque typeface is Helvetica.", + }, + ], + [ + "Monospace Slab Serif", + { + stack: ["Nimbus Mono PS", "Courier New", "monospace"], + description: + "Monospace Slab Serif typefaces are characterized by their fixed-width letters, which have the same width regardless of their shape, and its simple, geometric forms. Used to emulate typewriter output for reports, tabular work and technical documentation.", + }, + ], [ "Monospace Code", - [ - "ui-monospace", - "Cascadia Code", - "Source Code Pro", - "Menlo", - "Consolas", - "DejaVu Sans Mono", - "monospace", - ], + { + stack: [ + "ui-monospace", + "Cascadia Code", + "Source Code Pro", + "Menlo", + "Consolas", + "DejaVu Sans Mono", + "monospace", + ], + description: + "Monospace Code typefaces are specifically designed for use in programming and other technical applications. These typefaces are characterized by their monospaced design, which means that all letters and characters have the same width, and their clear, legible forms.", + }, ], [ "Industrial", - [ - "Bahnschrift", - "DIN Alternate", - "Franklin Gothic Medium", - "Nimbus Sans Narrow", - "sans-serif-condensed", - "sans-serif", - ], + { + stack: [ + "Bahnschrift", + "DIN Alternate", + "Franklin Gothic Medium", + "Nimbus Sans Narrow", + "sans-serif-condensed", + "sans-serif", + ], + description: + "Industrial typefaces originated in the late 19th century and was heavily influenced by the advancements in technology and industry during that time. Industrial typefaces are characterized by their bold, sans-serif letterforms, simple and straightforward appearance, and the use of straight lines and geometric shapes.", + }, ], [ "Rounded Sans", - [ - "ui-rounded", - "Hiragino Maru Gothic ProN", - "Quicksand", - "Comfortaa", - "Manjari", - "Arial Rounded MT", - "Arial Rounded MT Bold", - "Calibri", - "source-sans-pro", - "sans-serif", - ], + { + stack: [ + "ui-rounded", + "Hiragino Maru Gothic ProN", + "Quicksand", + "Comfortaa", + "Manjari", + "Arial Rounded MT", + "Arial Rounded MT Bold", + "Calibri", + "source-sans-pro", + "sans-serif", + ], + description: + "Rounded typefaces are characterized by the rounded curved letterforms and give a softer, friendlier appearance. The rounded edges give the typeface a more organic and playful feel, making it suitable for use in informal or child-friendly designs. The rounded sans-serif style has been popular since the 1950s, and it continues to be widely used in advertising, branding, and other forms of graphic design.", + }, ], [ "Slab Serif", - [ - "Rockwell", - "Rockwell Nova", - "Roboto Slab", - "DejaVu Serif", - "Sitka Small", - "serif", - ], + { + stack: [ + "Rockwell", + "Rockwell Nova", + "Roboto Slab", + "DejaVu Serif", + "Sitka Small", + "serif", + ], + description: + "Slab Serif typefaces are characterized by the presence of thick, block-like serifs on the ends of each letterform. These serifs are usually unbracketed, meaning they do not have any curved or tapered transitions to the main stroke of the letter.", + }, ], [ "Antique", - [ - "Superclarendon", - "Bookman Old Style", - "URW Bookman", - "URW Bookman L", - "Georgia Pro", - "Georgia", - "serif", - ], + { + stack: [ + "Superclarendon", + "Bookman Old Style", + "URW Bookman", + "URW Bookman L", + "Georgia Pro", + "Georgia", + "serif", + ], + description: + "Antique typefaces, also known as Egyptians, are a subset of serif typefaces that were popular in the 19th century. They are characterized by their block-like serifs and thick uniform stroke weight.", + }, ], [ "Didone", - [ - "Didot", - "Bodoni MT", - "Noto Serif Display", - "URW Palladio L", - "P052", - "Sylfaen", - "serif", - ], + { + stack: [ + "Didot", + "Bodoni MT", + "Noto Serif Display", + "URW Palladio L", + "P052", + "Sylfaen", + "serif", + ], + description: + "Didone typefaces, also known as Modern typefaces, are characterized by the high contrast between thick and thin strokes, vertical stress, and hairline serifs with no bracketing. The Didone style emerged in the late 18th century and gained popularity during the 19th century.", + }, ], [ "Handwritten", - [ - "Segoe Print", - "Bradley Hand", - "Chilanka", - "TSCu_Comic", - "casual", - "cursive", - ], + { + stack: [ + "Segoe Print", + "Bradley Hand", + "Chilanka", + "TSCu_Comic", + "casual", + "cursive", + ], + description: + "Handwritten typefaces are designed to mimic the look and feel of handwriting. Despite the vast array of handwriting styles, this font stack tend to adopt a more informal and everyday style of handwriting.", + }, ], [ "Emoji", - [ - "Apple Color Emoji", - "Segoe UI Emoji", - "Segoe UI Symbol", - "Noto Color Emoji", - ], - ], - ["Arial", ["Arial", "Roboto", "sans-serif"]], - ["Times New Roman", ["Times New Roman", "sans"]], - ["Courier New", ["Courier New", "monospace"]], + { + stack: [ + "Apple Color Emoji", + "Segoe UI Emoji", + "Segoe UI Symbol", + "Noto Color Emoji", + ], + }, + ], + ["Arial", { stack: ["Arial", "Roboto", "sans-serif"], description: "" }], + ["Times New Roman", { stack: ["Times New Roman", "sans"], description: "" }], + ["Courier New", { stack: ["Courier New", "monospace"], description: "" }], // Chineese fonts - ["SimSun", ["SimSun", "Songti SC, sans-serif"]], - ["PingFang SC", ["PingFang SC", "Microsoft Ya Hei", "sans-serif"]], + ["SimSun", { stack: ["SimSun", "Songti SC, sans-serif"], description: "" }], + [ + "PingFang SC", + { + stack: ["PingFang SC", "Microsoft Ya Hei", "sans-serif"], + description: "", + }, + ], ]); export const DEFAULT_FONT_FALLBACK = "sans-serif"; From 872d0e37db6f19ebd5e3d5ea71691ba6137aa752 Mon Sep 17 00:00:00 2001 From: Oleg Isonen Date: Sun, 15 Sep 2024 23:56:08 +0100 Subject: [PATCH 09/14] add tooltip with description and font family code --- .../shared/fonts-manager/fonts-manager.tsx | 26 ++++++++++++++++++- .../shared/fonts-manager/item-utils.ts | 16 ++++++++---- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/apps/builder/app/builder/shared/fonts-manager/fonts-manager.tsx b/apps/builder/app/builder/shared/fonts-manager/fonts-manager.tsx index 737573072cf4..dad416686183 100644 --- a/apps/builder/app/builder/shared/fonts-manager/fonts-manager.tsx +++ b/apps/builder/app/builder/shared/fonts-manager/fonts-manager.tsx @@ -9,6 +9,7 @@ import { Text, rawTheme, Link, + Flex, } from "@webstudio-is/design-system"; import { AssetsShell, @@ -145,7 +146,30 @@ export const FontsManager = ({ value, onChange }: FontsManagerProps) => { item.type === "uploaded" ? ( renderMenu(index) ) : itemProps.state === "selected" && item.description ? ( - + + {item.label} + + {`font-family: ${item.stack.join(", ")};`} + + {item.description} + + } + > ; }; export const toItems = ( assetContainers: Array ): Array => { - const system = Array.from(SYSTEM_FONTS.keys()).map((label) => ({ - label, - type: "system", - description: SYSTEM_FONTS.get(label)?.description, - })); // We can have 2+ assets with the same family name, so we use a map to dedupe. const uploaded = new Map(); for (const assetContainer of assetContainers) { @@ -32,6 +28,16 @@ export const toItems = ( }); } } + + const system = []; + for (const [label, config] of SYSTEM_FONTS) { + system.push({ + label, + type: "system", + description: config.description, + stack: config.stack, + }); + } return [...uploaded.values(), ...system]; }; From 88ae4f375709f365eca98a05780cb7a7e743ea19 Mon Sep 17 00:00:00 2001 From: Oleg Isonen Date: Mon, 16 Sep 2024 23:09:50 +0100 Subject: [PATCH 10/14] fix unselect when hovering category item --- .../src/components/__DEPRECATED__/list.tsx | 28 ++++++++----------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/packages/design-system/src/components/__DEPRECATED__/list.tsx b/packages/design-system/src/components/__DEPRECATED__/list.tsx index 73b09f9eee65..00101d9a956c 100644 --- a/packages/design-system/src/components/__DEPRECATED__/list.tsx +++ b/packages/design-system/src/components/__DEPRECATED__/list.tsx @@ -27,22 +27,13 @@ const ListItemBase = styled("li", { listStyle: "none", outline: 0, position: "relative", - variants: { - state: { - disabled: { - pointerEvents: "none", - }, - selected: { - "&:before": { - content: "''", - position: "absolute", - pointerEvents: "none", - inset: `0 ${theme.spacing[3]}`, - borderRadius: theme.borderRadius[4], - border: `2px solid ${theme.colors.borderFocus}`, - }, - }, - }, + "&[aria-selected]::before": { + content: "''", + position: "absolute", + pointerEvents: "none", + inset: `0 ${theme.spacing[3]}`, + borderRadius: theme.borderRadius[4], + border: `2px solid ${theme.colors.borderFocus}`, }, }); @@ -66,9 +57,9 @@ export const DeprecatedListItem = forwardRef< return ( Date: Tue, 17 Sep 2024 17:34:58 +0100 Subject: [PATCH 11/14] fix double click bug --- .../font-family/font-family-control.tsx | 8 +++++-- .../shared/fonts-manager/fonts-manager.tsx | 23 +++++++------------ 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/apps/builder/app/builder/features/style-panel/controls/font-family/font-family-control.tsx b/apps/builder/app/builder/features/style-panel/controls/font-family/font-family-control.tsx index 3bddc8a7de2b..7f2a3c7864b4 100644 --- a/apps/builder/app/builder/features/style-panel/controls/font-family/font-family-control.tsx +++ b/apps/builder/app/builder/features/style-panel/controls/font-family/font-family-control.tsx @@ -61,6 +61,10 @@ export const FontFamilyControl = () => { return toValue(value, (value) => value).replace(/"/g, ""); }, [value]); + if (value.type !== "fontFamily") { + return; + } + return ( @@ -69,8 +73,8 @@ export const FontFamilyControl = () => { title="Fonts" content={ { + value={value} + onChange={(newValue = itemValue) => { setValue({ type: "fontFamily", value: [newValue] }); }} /> diff --git a/apps/builder/app/builder/shared/fonts-manager/fonts-manager.tsx b/apps/builder/app/builder/shared/fonts-manager/fonts-manager.tsx index dad416686183..9338ca5fce2a 100644 --- a/apps/builder/app/builder/shared/fonts-manager/fonts-manager.tsx +++ b/apps/builder/app/builder/shared/fonts-manager/fonts-manager.tsx @@ -17,7 +17,7 @@ import { Separator, useAssets, } from "~/builder/shared/assets"; -import { useEffect, useMemo, useState } from "react"; +import { useMemo, useState } from "react"; import { useMenu } from "./item-menu"; import { CheckMarkIcon, InfoCircleIcon } from "@webstudio-is/icons"; import { @@ -27,14 +27,9 @@ import { groupItemsByType, toItems, } from "./item-utils"; +import type { FontFamilyValue } from "@webstudio-is/css-engine"; -const useLogic = ({ - onChange, - value, -}: { - onChange: (value: string) => void; - value: string; -}) => { +const useLogic = ({ onChange, value }: FontsManagerProps) => { const { assetContainers } = useAssets("font"); const [selectedIndex, setSelectedIndex] = useState(-1); const fontItems = useMemo(() => toItems(assetContainers), [assetContainers]); @@ -66,16 +61,14 @@ const useLogic = ({ () => groupItemsByType(filteredItems), [filteredItems] ); - const [currentIndex, setCurrentIndex] = useState(-1); - useEffect(() => { - setCurrentIndex(groupedItems.findIndex((item) => item.label === value)); + const currentIndex = useMemo(() => { + return groupedItems.findIndex((item) => item.label === value.value[0]); }, [groupedItems, value]); const handleChangeCurrent = (nextCurrentIndex: number) => { const item = groupedItems[nextCurrentIndex]; if (item !== undefined) { - setCurrentIndex(nextCurrentIndex); onChange(item.label); } }; @@ -93,7 +86,7 @@ const useLogic = ({ const ids = filterIdsByFamily(family, assetContainers); deleteAssets(ids); if (index === currentIndex) { - setCurrentIndex(-1); + onChange(undefined); } }; @@ -111,8 +104,8 @@ const useLogic = ({ }; type FontsManagerProps = { - value: string; - onChange: (value: string) => void; + value: FontFamilyValue; + onChange: (value?: string) => void; }; export const FontsManager = ({ value, onChange }: FontsManagerProps) => { From 01f6bf6294798313192410c585765e96fb8063e1 Mon Sep 17 00:00:00 2001 From: Oleg Isonen Date: Tue, 17 Sep 2024 17:57:42 +0100 Subject: [PATCH 12/14] delete emoji stack --- packages/fonts/src/constants.ts | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/packages/fonts/src/constants.ts b/packages/fonts/src/constants.ts index 85ef75665af4..b0a6c56dc678 100644 --- a/packages/fonts/src/constants.ts +++ b/packages/fonts/src/constants.ts @@ -214,17 +214,6 @@ export const SYSTEM_FONTS = new Map([ "Handwritten typefaces are designed to mimic the look and feel of handwriting. Despite the vast array of handwriting styles, this font stack tend to adopt a more informal and everyday style of handwriting.", }, ], - [ - "Emoji", - { - stack: [ - "Apple Color Emoji", - "Segoe UI Emoji", - "Segoe UI Symbol", - "Noto Color Emoji", - ], - }, - ], ["Arial", { stack: ["Arial", "Roboto", "sans-serif"], description: "" }], ["Times New Roman", { stack: ["Times New Roman", "sans"], description: "" }], ["Courier New", { stack: ["Courier New", "monospace"], description: "" }], From b857863f45e5c79b626b772b421f0e3942bfee41 Mon Sep 17 00:00:00 2001 From: Oleg Isonen Date: Tue, 17 Sep 2024 18:04:23 +0100 Subject: [PATCH 13/14] delete emoji font, add descriptions for others --- packages/fonts/src/constants.ts | 39 ++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/packages/fonts/src/constants.ts b/packages/fonts/src/constants.ts index b0a6c56dc678..075a2dc02d4a 100644 --- a/packages/fonts/src/constants.ts +++ b/packages/fonts/src/constants.ts @@ -214,16 +214,45 @@ export const SYSTEM_FONTS = new Map([ "Handwritten typefaces are designed to mimic the look and feel of handwriting. Despite the vast array of handwriting styles, this font stack tend to adopt a more informal and everyday style of handwriting.", }, ], - ["Arial", { stack: ["Arial", "Roboto", "sans-serif"], description: "" }], - ["Times New Roman", { stack: ["Times New Roman", "sans"], description: "" }], - ["Courier New", { stack: ["Courier New", "monospace"], description: "" }], + [ + "Arial", + { + stack: ["Arial", "Roboto", "sans-serif"], + description: + "A clean, sans-serif font designed for legibility and versatility. Ideal for modern, minimalistic designs or digital content that requires simplicity.", + }, + ], + [ + "Times New Roman", + { + stack: ["Times New Roman", "sans"], + description: + "A classic serif font known for its formal, professional appearance. Best suited for traditional documents, reports, and academic writing.", + }, + ], + [ + "Courier New", + { + stack: ["Courier New", "monospace"], + description: + "A monospaced serif font with uniform spacing, mimicking typewriter text. Perfect for coding, technical documents, or retro-styled designs.", + }, + ], // Chineese fonts - ["SimSun", { stack: ["SimSun", "Songti SC, sans-serif"], description: "" }], + [ + "SimSun", + { + stack: ["SimSun", "Songti SC, sans-serif"], + description: + "A traditional serif font designed for Chinese characters, offering clear and readable text. Ideal for formal Chinese documents or multilingual content requiring both Chinese and Latin text.", + }, + ], [ "PingFang SC", { stack: ["PingFang SC", "Microsoft Ya Hei", "sans-serif"], - description: "", + description: + "A modern sans-serif font designed for simplified Chinese characters. Sleek and clean, it’s best for digital content and interfaces where modern, streamlined design is needed.", }, ], ]); From d0bc5e18136aa97e0be2a7bc2eb374b823383d92 Mon Sep 17 00:00:00 2001 From: Oleg Isonen Date: Wed, 18 Sep 2024 20:36:33 +0100 Subject: [PATCH 14/14] update tests --- packages/css-engine/src/core/to-value.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/css-engine/src/core/to-value.test.ts b/packages/css-engine/src/core/to-value.test.ts index 37c4d981df9b..c84f7aa525ce 100644 --- a/packages/css-engine/src/core/to-value.test.ts +++ b/packages/css-engine/src/core/to-value.test.ts @@ -50,10 +50,10 @@ describe("Convert WS CSS Values to native CSS strings", () => { expect( toValue({ type: "fontFamily", - value: ["Emoji"], + value: ["Humanist"], }) ).toBe( - '"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"' + 'Seravek, "Gill Sans Nova", Ubuntu, Calibri, "DejaVu Sans", source-sans-pro, sans-serif' ); });