@multiplatform.one/theme 7.44.0 → 7.45.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +5 -5
- package/src/theme/createDefaultThemeConfig.ts +3 -3
- package/src/theme/defaults/fonts.ts +50 -0
- package/src/theme/headingCategoryFamilies.spec.ts +51 -0
- package/src/theme/scale/scaleFonts.ts +2 -1
- package/types/theme/defaults/fonts.d.ts +3 -1
- package/types/theme/defaults/fonts.d.ts.map +1 -1
- package/types/theme/scale/scaleFonts.d.ts.map +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@multiplatform.one/theme",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.45.1",
|
|
4
4
|
"description": "Tamagui theme system for multiplatform.one",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"multiplatform",
|
|
@@ -59,8 +59,8 @@
|
|
|
59
59
|
"access": "public"
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"@multiplatform.one/platform": "^7.
|
|
63
|
-
"@multiplatform.one/store": "^7.
|
|
62
|
+
"@multiplatform.one/platform": "^7.45.1",
|
|
63
|
+
"@multiplatform.one/store": "^7.45.1",
|
|
64
64
|
"@tamagui/animations-react-native": "2.7.6",
|
|
65
65
|
"@tamagui/colors": "2.7.6",
|
|
66
66
|
"@tamagui/config": "2.7.6",
|
|
@@ -73,8 +73,8 @@
|
|
|
73
73
|
"react-cookie": "^8.1.2"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
|
-
"@multiplatform.one/config": "7.
|
|
77
|
-
"@multiplatform.one/test-utils": "7.
|
|
76
|
+
"@multiplatform.one/config": "7.45.1",
|
|
77
|
+
"@multiplatform.one/test-utils": "7.45.1",
|
|
78
78
|
"@tamagui/animations-css": "2.7.6",
|
|
79
79
|
"@tamagui/animations-reanimated": "2.7.6",
|
|
80
80
|
"@tamagui/font-inter": "2.7.6",
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
import { defaultAccentTheme } from "./defaults/accent";
|
|
13
13
|
import { defaultBaseTheme } from "./defaults/base";
|
|
14
14
|
import { defaultBuilderOptions } from "./defaults/builderOptions";
|
|
15
|
-
import { defaultFonts } from "./defaults/fonts";
|
|
15
|
+
import { defaultFonts, withDerivedHeadingCategories } from "./defaults/fonts";
|
|
16
16
|
import { scaleFontSet } from "./scale/scaleFonts";
|
|
17
17
|
import type { Preset } from "./preset.types";
|
|
18
18
|
import { type SizeRecipeInputs } from "./recipeInputs";
|
|
@@ -147,11 +147,11 @@ export function createDefaultThemeConfig(
|
|
|
147
147
|
// pipeline (e.g. the Frappe SPA) where runtime JS themes are required.
|
|
148
148
|
// Always keep themes to ensure TamaguiProvider has valid theme data.
|
|
149
149
|
const themes = options.subset ? subsetThemes(builtThemes, options.subset) : builtThemes;
|
|
150
|
-
const fonts = {
|
|
150
|
+
const fonts = withDerivedHeadingCategories({
|
|
151
151
|
...defaultConfig.fonts,
|
|
152
152
|
...defaultFonts,
|
|
153
153
|
...options.fonts,
|
|
154
|
-
} as Record<string, GenericFont
|
|
154
|
+
} as Record<string, GenericFont>);
|
|
155
155
|
return createThemeConfig(
|
|
156
156
|
{
|
|
157
157
|
...defaultConfig,
|
|
@@ -133,6 +133,7 @@ export function createCategoryFont(
|
|
|
133
133
|
family: string,
|
|
134
134
|
tables: ScaleFonts = defaultTypeTables,
|
|
135
135
|
scope: "body" | "heading" = "body",
|
|
136
|
+
face?: GenericFont["face"],
|
|
136
137
|
): GenericFont {
|
|
137
138
|
const sizes = scope === "heading" ? tables.headingSizes : tables.bodySizes;
|
|
138
139
|
return createFont({
|
|
@@ -141,6 +142,7 @@ export function createCategoryFont(
|
|
|
141
142
|
lineHeight: categoryLineHeights(category, tables, scope),
|
|
142
143
|
weight: scope === "heading" ? headingWeights : bodyWeights,
|
|
143
144
|
letterSpacing: neutralTracking(sizes),
|
|
145
|
+
...(face ? { face } : {}),
|
|
144
146
|
}) as GenericFont;
|
|
145
147
|
}
|
|
146
148
|
|
|
@@ -293,3 +295,51 @@ export const defaultFonts = {
|
|
|
293
295
|
blackletter: defaultBlackletterFont,
|
|
294
296
|
geometric: defaultGeometricFont,
|
|
295
297
|
} as const;
|
|
298
|
+
|
|
299
|
+
type HeadingSource = {
|
|
300
|
+
category: FontCategory;
|
|
301
|
+
family: string;
|
|
302
|
+
face?: GenericFont["face"];
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
const derivedHeadingSources = new WeakMap<GenericFont, HeadingSource>();
|
|
306
|
+
|
|
307
|
+
function deriveHeading(source: HeadingSource, tables: ScaleFonts): GenericFont {
|
|
308
|
+
const font = createCategoryFont(source.category, source.family, tables, "heading", source.face);
|
|
309
|
+
derivedHeadingSources.set(font, source);
|
|
310
|
+
return font;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
export function withDerivedHeadingCategories(
|
|
314
|
+
fonts: Record<string, GenericFont>,
|
|
315
|
+
tables: ScaleFonts = defaultTypeTables,
|
|
316
|
+
): Record<string, GenericFont> {
|
|
317
|
+
const result = { ...fonts };
|
|
318
|
+
for (const [category, key] of Object.entries(headingCategoryFontKeys)) {
|
|
319
|
+
const source = fonts[category];
|
|
320
|
+
if (
|
|
321
|
+
fonts[key] !== defaultFonts[key] ||
|
|
322
|
+
!source ||
|
|
323
|
+
source === defaultFonts[category as keyof typeof defaultFonts]
|
|
324
|
+
)
|
|
325
|
+
continue;
|
|
326
|
+
const family = source.family as string | { val: string };
|
|
327
|
+
result[key] = deriveHeading(
|
|
328
|
+
{
|
|
329
|
+
category: category as FontCategory,
|
|
330
|
+
family: typeof family === "string" ? family : family.val,
|
|
331
|
+
face: source.face,
|
|
332
|
+
},
|
|
333
|
+
tables,
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
return result;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
export function rescaleDerivedHeadingFont(
|
|
340
|
+
font: GenericFont,
|
|
341
|
+
tables: ScaleFonts,
|
|
342
|
+
): GenericFont | undefined {
|
|
343
|
+
const source = derivedHeadingSources.get(font);
|
|
344
|
+
return source ? deriveHeading(source, tables) : undefined;
|
|
345
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
|
+
|
|
3
|
+
vi.mock("tamagui", () => ({ createTamagui: (config: unknown) => config }));
|
|
4
|
+
vi.mock("./animations/index", () => ({ animations: {} }));
|
|
5
|
+
|
|
6
|
+
import { createDefaultFont } from "../font";
|
|
7
|
+
import { createDefaultThemeConfig } from "./createDefaultThemeConfig";
|
|
8
|
+
import { defaultFonts, headingCategoryFontKeys } from "./defaults/fonts";
|
|
9
|
+
import { generateScale } from "./scale/generateScale";
|
|
10
|
+
import { defaultScaleInputs } from "./scale/scaleInputs";
|
|
11
|
+
import { scaleFontSet } from "./scale/scaleFonts";
|
|
12
|
+
|
|
13
|
+
describe("heading category family registration", () => {
|
|
14
|
+
it("uses a consumer category family and face without inheriting body metrics", () => {
|
|
15
|
+
const face = { 400: { normal: "CustomScript" }, 700: { normal: "CustomScriptBold" } };
|
|
16
|
+
const cursive = createDefaultFont({ family: "Custom Script", face });
|
|
17
|
+
const config = createDefaultThemeConfig({ fonts: { cursive } });
|
|
18
|
+
const fonts = config.tamagui.fonts;
|
|
19
|
+
expect(fonts.headingCursive.family).toBe(cursive.family);
|
|
20
|
+
expect(fonts.headingCursive.face).toMatchObject(face);
|
|
21
|
+
expect(fonts.headingCursive.size).toEqual(defaultFonts.headingCursive.size);
|
|
22
|
+
expect(fonts.headingCursive.weight).toEqual(defaultFonts.headingCursive.weight);
|
|
23
|
+
expect(fonts.headingCursive.lineHeight).toEqual(defaultFonts.headingCursive.lineHeight);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("keeps each inherited category family on the heading ladder after a preset scale change", () => {
|
|
27
|
+
const families = Object.fromEntries(
|
|
28
|
+
Object.keys(headingCategoryFontKeys).map((category) => [
|
|
29
|
+
category,
|
|
30
|
+
createDefaultFont({ family: `Loaded-${category}` }),
|
|
31
|
+
]),
|
|
32
|
+
);
|
|
33
|
+
const config = createDefaultThemeConfig({ fonts: families });
|
|
34
|
+
const from = generateScale(defaultScaleInputs).fonts;
|
|
35
|
+
const to = generateScale({ ...defaultScaleInputs, type: 19 }).fonts;
|
|
36
|
+
const scaled = scaleFontSet(config.tamagui.fonts, from, to);
|
|
37
|
+
for (const [category, key] of Object.entries(headingCategoryFontKeys)) {
|
|
38
|
+
expect(scaled[key].family).toBe(`Loaded-${category}`);
|
|
39
|
+
expect(scaled[key].size).toEqual(to.headingSizes);
|
|
40
|
+
expect(scaled[key].weight).toEqual(defaultFonts[key].weight);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it("lets an explicit heading category override win", () => {
|
|
45
|
+
const headingCursive = { ...defaultFonts.headingCursive, family: "Heading Only" };
|
|
46
|
+
const config = createDefaultThemeConfig({
|
|
47
|
+
fonts: { cursive: createDefaultFont({ family: "Body Only" }), headingCursive },
|
|
48
|
+
});
|
|
49
|
+
expect(config.tamagui.fonts.headingCursive.family).toBe("Heading Only");
|
|
50
|
+
});
|
|
51
|
+
});
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
defaultFonts,
|
|
7
7
|
fontFamilyStacks,
|
|
8
8
|
headingCategoryFontKeys,
|
|
9
|
+
rescaleDerivedHeadingFont,
|
|
9
10
|
} from "../defaults/fonts";
|
|
10
11
|
import type { FontCategory } from "../knobs";
|
|
11
12
|
import type { ScaleFonts } from "./generateScale";
|
|
@@ -99,7 +100,7 @@ export function scaleFontSet(
|
|
|
99
100
|
to,
|
|
100
101
|
);
|
|
101
102
|
} else {
|
|
102
|
-
out[name] = rescaleFont(font, from, to);
|
|
103
|
+
out[name] = rescaleDerivedHeadingFont(font, to) ?? rescaleFont(font, from, to);
|
|
103
104
|
}
|
|
104
105
|
}
|
|
105
106
|
return out;
|
|
@@ -30,7 +30,7 @@ export type FontFamilyCategory = FontCategory;
|
|
|
30
30
|
/** Scope leading raised to the category's LC-11 floor. */
|
|
31
31
|
export declare function categoryLineHeights(category: FontCategory, tables?: ScaleFonts, scope?: "body" | "heading"): Record<string, number>;
|
|
32
32
|
/** Category family on the selected scope's size and weight ladder. */
|
|
33
|
-
export declare function createCategoryFont(category: FontCategory, family: string, tables?: ScaleFonts, scope?: "body" | "heading"): GenericFont;
|
|
33
|
+
export declare function createCategoryFont(category: FontCategory, family: string, tables?: ScaleFonts, scope?: "body" | "heading", face?: GenericFont["face"]): GenericFont;
|
|
34
34
|
/** Inter `$heading` on a generated scale's heading ladder. */
|
|
35
35
|
export declare function createHeadingFont(tables?: ScaleFonts): import("@tamagui/web").FillInFont<{
|
|
36
36
|
face: {
|
|
@@ -442,4 +442,6 @@ export declare const defaultFonts: {
|
|
|
442
442
|
readonly blackletter: GenericFont;
|
|
443
443
|
readonly geometric: GenericFont;
|
|
444
444
|
};
|
|
445
|
+
export declare function withDerivedHeadingCategories(fonts: Record<string, GenericFont>, tables?: ScaleFonts): Record<string, GenericFont>;
|
|
446
|
+
export declare function rescaleDerivedHeadingFont(font: GenericFont, tables: ScaleFonts): GenericFont | undefined;
|
|
445
447
|
//# sourceMappingURL=fonts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fonts.d.ts","sourceRoot":"","sources":["../../../src/theme/defaults/fonts.ts"],"names":[],"mappings":"AAKA,OAAO,EAAc,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAG5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAmBxE,6DAA6D;AAC7D,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,yEAAyE;AACzE,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;GAGG;AACH,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAE1C,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEvD;AAmCD;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAsC,CAAC;AAExF,uEAAuE;AACvE,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAEtD,CAAC;AAWF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,8BAAqB,CAAC;AAEnD,MAAM,MAAM,kBAAkB,GAAG,YAAY,CAAC;AAE9C,0DAA0D;AAC1D,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,YAAY,EACtB,MAAM,GAAE,UAA8B,EACtC,KAAK,GAAE,MAAM,GAAG,SAAkB,GACjC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAUxB;AAED,sEAAsE;AACtE,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,YAAY,EACtB,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,UAA8B,EACtC,KAAK,GAAE,MAAM,GAAG,SAAkB,
|
|
1
|
+
{"version":3,"file":"fonts.d.ts","sourceRoot":"","sources":["../../../src/theme/defaults/fonts.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaleFonts.d.ts","sourceRoot":"","sources":["../../../src/theme/scale/scaleFonts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"scaleFonts.d.ts","sourceRoot":"","sources":["../../../src/theme/scale/scaleFonts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAWhD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAQlD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,WAAW,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,UAAU,GAAG,CAAC,CAqC/F;AAQD;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAClC,IAAI,EAAE,UAAU,EAChB,EAAE,EAAE,UAAU,GACb,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CA2B7B"}
|