@multiplatform.one/theme 7.88.7 → 7.88.9

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.
@@ -0,0 +1,142 @@
1
+ import { cleanup, render } from "@testing-library/react";
2
+ import { afterEach, describe, expect, it, vi } from "vitest";
3
+ import { contrastRatio, normalizeToHex, relativeLuminance } from "./colorRules";
4
+
5
+ const live = vi.hoisted(() => ({
6
+ name: "light" as string | undefined,
7
+ values: {} as Record<string, string>,
8
+ }));
9
+
10
+ vi.mock("tamagui", async (importOriginal) => ({
11
+ ...((await importOriginal()) as object),
12
+ useThemeName: () => live.name,
13
+ useTheme: () =>
14
+ Object.fromEntries(Object.entries(live.values).map(([key, val]) => [key, { val }])),
15
+ }));
16
+
17
+ const {
18
+ resolveAccentTintedSurface,
19
+ resolveActiveTabInk,
20
+ useAccentTintedSurface,
21
+ useActiveTabInk,
22
+ useIdentityHue,
23
+ useLegibleInkOn,
24
+ useReadableTextOn,
25
+ } = await import("./readableColor");
26
+
27
+ const paper = "#ffffff";
28
+ const ink = "#1c1b1f";
29
+ const contrast = (a: string, b: string) =>
30
+ contrastRatio(relativeLuminance(normalizeToHex(a)!), relativeLuminance(normalizeToHex(b)!));
31
+
32
+ function read<T>(hook: () => T): T {
33
+ const out: { value?: T } = {};
34
+ function Probe() {
35
+ out.value = hook();
36
+ return null;
37
+ }
38
+ render(<Probe />);
39
+ return out.value as T;
40
+ }
41
+
42
+ afterEach(() => {
43
+ cleanup();
44
+ live.name = "light";
45
+ live.values = {};
46
+ });
47
+
48
+ describe("useReadableTextOn", () => {
49
+ it("picks the anchor that reads on a resolved fill token", () => {
50
+ live.values = { color1: paper, color12: ink, color9: "#101010", color3: "#f4f4f4" };
51
+ expect(read(() => useReadableTextOn("$color9"))).toBe(paper);
52
+ expect(read(() => useReadableTextOn("$color3"))).toBe(ink);
53
+ expect(read(() => useReadableTextOn("#0a0a0a"))).toBe(paper);
54
+ });
55
+
56
+ it("gives up, so the caller keeps its default, when any colour fails to resolve", () => {
57
+ live.values = { color1: paper, color12: ink };
58
+ expect(read(() => useReadableTextOn("$missing"))).toBeUndefined();
59
+ expect(read(() => useReadableTextOn(undefined))).toBeUndefined();
60
+ expect(read(() => useReadableTextOn("not a colour"))).toBeUndefined();
61
+ live.values = { color1: "nope", color12: ink };
62
+ expect(read(() => useReadableTextOn("#000000"))).toBeUndefined();
63
+ });
64
+ });
65
+
66
+ describe("useLegibleInkOn", () => {
67
+ it("keeps the component's own ink token while it clears AA", () => {
68
+ live.values = { color1: paper, color12: ink, color2: "#fafafa", color11: "#5a5860" };
69
+ expect(read(() => useLegibleInkOn("$color2", "$color11"))).toBe("$color11");
70
+ });
71
+
72
+ it("hands a failing ink over to a concrete readable colour", () => {
73
+ live.values = { color1: paper, color12: ink, color2: "#fafafa", color6: "#dddddd" };
74
+ const swapped = read(() => useLegibleInkOn("$color2", "$color6"));
75
+ expect(swapped).not.toBe("$color6");
76
+ expect(contrast(swapped, "#fafafa")).toBeGreaterThanOrEqual(4.5);
77
+ });
78
+
79
+ it("returns the token untouched when the fill or ink cannot be read", () => {
80
+ live.values = { color1: paper, color12: ink };
81
+ expect(read(() => useLegibleInkOn("$missing", "$color11"))).toBe("$color11");
82
+ expect(read(() => useLegibleInkOn("#fafafa", "#dddddd"))).not.toBe("#dddddd");
83
+ });
84
+ });
85
+
86
+ describe("useAccentTintedSurface", () => {
87
+ it("mixes the accent solid into paper just past the wash ratio", () => {
88
+ live.values = { accentBackground: "#2a5bd7", color1: paper };
89
+ const wash = read(useAccentTintedSurface);
90
+ expect(wash).toBe(resolveAccentTintedSurface({ solid: "#2a5bd7", paper }));
91
+ expect(contrast(wash!, paper)).toBeGreaterThanOrEqual(1.2);
92
+ expect(contrast(wash!, paper)).toBeLessThan(1.3);
93
+ });
94
+
95
+ it("is undefined without a resolvable solid", () => {
96
+ live.values = { color1: paper };
97
+ expect(read(useAccentTintedSurface)).toBeUndefined();
98
+ });
99
+ });
100
+
101
+ describe("identity hue and active tab ink (LC-150)", () => {
102
+ const accents = Object.fromEntries(
103
+ Array.from({ length: 12 }, (_, index) => [`accent${index + 1}`, "#9a9a9a"]),
104
+ );
105
+
106
+ it("takes the most chromatic accent step that clears AA on both page surfaces", () => {
107
+ live.values = {
108
+ ...accents,
109
+ accent9: "#1a55c9",
110
+ accent11: "#1f3f8f",
111
+ color1: paper,
112
+ color2: "#f7f7f8",
113
+ color12: ink,
114
+ };
115
+ const { hue, c1, c2 } = read(useIdentityHue);
116
+ expect(hue).toBe("#1a55c9");
117
+ expect([c1, c2]).toEqual([paper, "#f7f7f8"]);
118
+ expect(read(useActiveTabInk)).toBe("#1a55c9");
119
+ });
120
+
121
+ it("has no hue on a grey ramp, so the active tab falls back to the accent solid or ink", () => {
122
+ live.values = { ...accents, color1: paper, color2: "#f7f7f8", color12: ink };
123
+ expect(read(useIdentityHue).hue).toBeUndefined();
124
+ expect(read(useActiveTabInk)).toBe(ink);
125
+ live.values = { ...live.values, accentBackground: "#d93a2b" };
126
+ live.name = "dark";
127
+ expect(read(useActiveTabInk)).toBe(
128
+ resolveActiveTabInk({
129
+ hue: undefined,
130
+ solid: "#d93a2b",
131
+ dark: true,
132
+ surfaces: [paper, "#f7f7f8"],
133
+ ink,
134
+ }),
135
+ );
136
+ });
137
+
138
+ it("falls back to the $color12 token when the theme has no ink", () => {
139
+ live.values = { ...accents, color1: paper, color2: "#f7f7f8" };
140
+ expect(read(useIdentityHue).ink).toBe("$color12");
141
+ });
142
+ });
@@ -31,4 +31,12 @@ export declare function identityKeys(themeName: string): string[];
31
31
  * re-render. A picked literal stayed on the scheme it was picked in.
32
32
  */
33
33
  export declare function withAccentOnSurface(themes: Record<string, Record<string, string>>): Record<string, Record<string, string>>;
34
+ /**
35
+ * FZ-9617. Every theme with the ink {@link resolveIdentityInk} picks inside it,
36
+ * as `identityInk`: the LC-176 icon-button glyph tint under the house `ink`
37
+ * fallback. On web a bar Button paints it through its host alias, so the glyph
38
+ * follows a light/dark flip with no re-render, where the picked literal stayed
39
+ * on the scheme it was picked in.
40
+ */
41
+ export declare function withIdentityInk(themes: Record<string, Record<string, string>>): Record<string, Record<string, string>>;
34
42
  //# sourceMappingURL=accentInk.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"accentInk.d.ts","sourceRoot":"","sources":["../../src/theme/accentInk.ts"],"names":[],"mappings":"AAYA,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG5C;AAYD,wBAAgB,eAAe,CAC7B,UAAU,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,EAC3C,QAAQ,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,GACxC,MAAM,GAAG,SAAS,CAiBpB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,UAAU,EACV,QAAQ,EACR,GAAG,GACJ,EAAE;IACD,UAAU,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC;IAC5C,QAAQ,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC;IAC1C,GAAG,EAAE,MAAM,CAAC;CACb,GAAG,MAAM,CAET;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,GAAG,GACJ,EAAE;IACD,QAAQ,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC;IAC1C,WAAW,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC;IAC7C,QAAQ,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC;IAC1C,GAAG,EAAE,MAAM,CAAC;CACb,GAAG,MAAM,CAkBT;AAED,eAAO,MAAM,cAAc,UAAiE,CAAC;AAE7F,8FAA8F;AAC9F,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAKxD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAC7C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAcxC"}
1
+ {"version":3,"file":"accentInk.d.ts","sourceRoot":"","sources":["../../src/theme/accentInk.ts"],"names":[],"mappings":"AAYA,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG5C;AAYD,wBAAgB,eAAe,CAC7B,UAAU,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,EAC3C,QAAQ,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,GACxC,MAAM,GAAG,SAAS,CAiBpB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,UAAU,EACV,QAAQ,EACR,GAAG,GACJ,EAAE;IACD,UAAU,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC;IAC5C,QAAQ,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC;IAC1C,GAAG,EAAE,MAAM,CAAC;CACb,GAAG,MAAM,CAET;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,GAAG,GACJ,EAAE;IACD,QAAQ,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC;IAC1C,WAAW,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC;IAC7C,QAAQ,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC;IAC1C,GAAG,EAAE,MAAM,CAAC;CACb,GAAG,MAAM,CAkBT;AAED,eAAO,MAAM,cAAc,UAAiE,CAAC;AAE7F,8FAA8F;AAC9F,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAKxD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAC7C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAcxC;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAC7C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAaxC"}
@@ -1 +1 @@
1
- {"version":3,"file":"createThemes.d.ts","sourceRoot":"","sources":["../../src/theme/createThemes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"createThemes.d.ts","sourceRoot":"","sources":["../../src/theme/createThemes.ts"],"names":[],"mappings":"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"}