@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@multiplatform.one/theme",
3
- "version": "7.44.0",
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.44.0",
63
- "@multiplatform.one/store": "^7.44.0",
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.44.0",
77
- "@multiplatform.one/test-utils": "7.44.0",
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":"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"}
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;AAUhD,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"}
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"}