@multiplatform.one/theme 7.75.0 → 7.76.0

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.75.0",
3
+ "version": "7.76.0",
4
4
  "description": "Tamagui theme system for multiplatform.one",
5
5
  "keywords": [
6
6
  "multiplatform",
@@ -72,8 +72,8 @@
72
72
  "access": "public"
73
73
  },
74
74
  "dependencies": {
75
- "@multiplatform.one/platform": "^7.75.0",
76
- "@multiplatform.one/store": "^7.75.0",
75
+ "@multiplatform.one/platform": "^7.76.0",
76
+ "@multiplatform.one/store": "^7.76.0",
77
77
  "@tamagui/animations-react-native": "2.7.6",
78
78
  "@tamagui/colors": "2.7.6",
79
79
  "@tamagui/config": "2.7.6",
@@ -89,8 +89,8 @@
89
89
  },
90
90
  "devDependencies": {
91
91
  "@expo/prebuild-config": "55.0.18",
92
- "@multiplatform.one/config": "7.75.0",
93
- "@multiplatform.one/test-utils": "7.75.0",
92
+ "@multiplatform.one/config": "7.76.0",
93
+ "@multiplatform.one/test-utils": "7.76.0",
94
94
  "@tamagui/animations-css": "2.7.6",
95
95
  "@tamagui/animations-reanimated": "2.7.6",
96
96
  "@tamagui/font-inter": "2.7.6",
@@ -0,0 +1,52 @@
1
+ /**
2
+ * FZ-8557 (Round 40): a checked menu row is a selection tint on its panel in
3
+ * every theme. Dark steps lighter than the `$color4` overlay, never a hole;
4
+ * light stays a tint on the white panel, never a slab; the check is the
5
+ * accent (ink when hue-less) and holds 3:1 on the fill.
6
+ */
7
+ import { describe, expect, it } from "vitest";
8
+ import { contrastRatio, normalizeToHex, relativeLuminance } from "./theme/colorRules";
9
+ import { createDefaultThemeConfig } from "./theme/createDefaultThemeConfig";
10
+ import { menuRowChecked, resolveMenuRowCheckInk } from "./menuRow";
11
+
12
+ type ThemeValues = Record<string, { val: string } | undefined>;
13
+ const themes = createDefaultThemeConfig({}).tamagui.themes as unknown as Record<
14
+ string,
15
+ ThemeValues
16
+ >;
17
+
18
+ const lum = (raw: string) => {
19
+ const hex = normalizeToHex(raw);
20
+ if (!hex) throw new Error(`not an opaque colour: ${raw}`);
21
+ return relativeLuminance(hex);
22
+ };
23
+ const token = (theme: ThemeValues, name: string) => {
24
+ const value = theme[name.replace(/^\$/, "")]?.val;
25
+ if (!value) throw new Error(`no ${name}`);
26
+ return value;
27
+ };
28
+
29
+ const hues = ["", "_blue", "_gray", "_green", "_orange", "_pink", "_purple", "_red", "_yellow"];
30
+
31
+ describe("a checked menu row is a selection tint on its panel (FZ-8557)", () => {
32
+ for (const scheme of ["light", "dark"] as const)
33
+ for (const hue of hues) {
34
+ const name = `${scheme}${hue}_alt1`;
35
+ it(`${name}`, () => {
36
+ const theme = themes[name];
37
+ expect(theme, name).toBeTruthy();
38
+ const panel = token(theme!, scheme === "dark" ? "$color4" : "$background");
39
+ const fill = token(theme!, menuRowChecked(scheme).backgroundColor);
40
+ const ratio = contrastRatio(lum(fill), lum(panel));
41
+ if (scheme === "dark") expect(lum(fill), `${fill} on ${panel}`).toBeGreaterThan(lum(panel));
42
+ else expect(lum(fill), `${fill} on ${panel}`).toBeLessThan(lum(panel));
43
+ expect(ratio, `${fill} on ${panel}`).toBeLessThan(1.3);
44
+ const check = resolveMenuRowCheckInk(theme!);
45
+ expect(contrastRatio(lum(check), lum(fill)), `${check} on ${fill}`).toBeGreaterThanOrEqual(
46
+ 3,
47
+ );
48
+ if (hue && hue !== "_gray") expect(check).toBe(token(theme!, "$accentColor"));
49
+ else expect(check).toBe(token(theme!, "$color"));
50
+ });
51
+ }
52
+ });
@@ -31,13 +31,13 @@ describe("menuRowFrame (LC-16 shared menu-row geometry)", () => {
31
31
  });
32
32
  });
33
33
 
34
- describe("menuRowChecked (LC-262 checked row, FZ-8355 r6)", () => {
35
- it("rests light rows on the $color4 selection surface, one step past the $color3 hover", () => {
36
- expect(menuRowChecked("light").backgroundColor).toBe("$color4");
34
+ describe("menuRowChecked (LC-262 checked row, FZ-8355 r6, FZ-8557)", () => {
35
+ it("rests light rows on the $color3 tint, one step off the white panel", () => {
36
+ expect(menuRowChecked("light").backgroundColor).toBe("$color3");
37
37
  });
38
38
 
39
- it("recesses dark rows to $color2, off the $color4 dark overlay", () => {
40
- expect(menuRowChecked("dark").backgroundColor).toBe("$color2");
39
+ it("lifts dark rows to $color5, a step lighter than the $color4 dark overlay", () => {
40
+ expect(menuRowChecked("dark").backgroundColor).toBe("$color5");
41
41
  });
42
42
 
43
43
  it("keeps the fill through hover and press, and leaves focus rings to the consumer", () => {
@@ -50,22 +50,22 @@ describe("menuRowChecked (LC-262 checked row, FZ-8355 r6)", () => {
50
50
  }
51
51
  });
52
52
 
53
- it("marks the check in the theme's selected ink", () => {
54
- expect(menuRowCheckInk).toBe("$selectedColor");
53
+ it("marks the check in the theme's accent", () => {
54
+ expect(menuRowCheckInk).toBe("$accentColor");
55
55
  });
56
56
  });
57
57
 
58
58
  describe("resolveMenuRowCheckInk (LC-176 bold mono check on hue-less themes)", () => {
59
- it("keeps a colour theme's selected ink", () => {
59
+ it("keeps a colour theme's accent", () => {
60
60
  expect(
61
- resolveMenuRowCheckInk({ selectedColor: { val: "#113264" }, color: { val: "#050505" } }),
62
- ).toBe("#113264");
61
+ resolveMenuRowCheckInk({ accentColor: { val: "#0e6abe" }, color: { val: "#050505" } }),
62
+ ).toBe("#0e6abe");
63
63
  });
64
64
 
65
- it("paints the primary ink when the selected ink is grey", () => {
65
+ it("paints the primary ink when the accent is grey", () => {
66
66
  expect(
67
67
  resolveMenuRowCheckInk({
68
- selectedColor: { val: "hsla(0, 0%, 27%, 1)" },
68
+ accentColor: { val: "hsla(0, 0%, 27%, 1)" },
69
69
  color: { val: "hsla(0, 0%, 2%, 1)" },
70
70
  }),
71
71
  ).toBe("hsla(0, 0%, 2%, 1)");
package/src/menuRow.ts CHANGED
@@ -41,17 +41,19 @@ export const menuRowFrame = {
41
41
  /**
42
42
  * LC-262: a checked or selected menu or picker row is highlighted, so it reads
43
43
  * as chosen without hunting for the check (FZ-8355 r6, rv_9244d1b063a3a4de).
44
- * Light rests on the LC-05 selection surface `$color4`, one step past the
45
- * `$color3` hover. A dark overlay is itself `$color4` (`surface2`), so dark
46
- * recesses to `$color2`, the band Clay rated good. In a colour theme both
47
- * steps carry its hue. Hover and press keep the fill, so a checked row never
48
- * drops to the transient hover fill. Spread it last on the row so it wins
49
- * over the consumer's hover and keyboard-cursor fills; a consumer that paints
50
- * focus as a fill paints `backgroundColor` there too. Focus rings stay the
51
- * consumer's.
44
+ * The fill is a selection tint one step off the panel toward the ink, the way
45
+ * HIG lifts a selection off its material (FZ-8557, Round 40). Light rests on
46
+ * `$color3` over the white `$color1` panel, a tint and not the `$color4` slab.
47
+ * A dark overlay is `$color4` (`surface2`), so dark rests on `$color5`, a step
48
+ * lighter: a recessed `$color2` read as a hole in the panel. In a colour theme
49
+ * both steps carry its hue. Hover and press keep the fill, so a checked row
50
+ * never drops to the transient hover fill. Spread it last on the row so it
51
+ * wins over the consumer's hover and keyboard-cursor fills; a consumer that
52
+ * paints focus as a fill paints `backgroundColor` there too. Focus rings stay
53
+ * the consumer's.
52
54
  */
53
55
  export function menuRowChecked(scheme: ColorScheme) {
54
- const fill = scheme === "dark" ? "$color2" : "$color4";
56
+ const fill = scheme === "dark" ? "$color5" : "$color3";
55
57
  return {
56
58
  backgroundColor: fill,
57
59
  hoverStyle: { backgroundColor: fill },
@@ -59,8 +61,8 @@ export function menuRowChecked(scheme: ColorScheme) {
59
61
  } as const;
60
62
  }
61
63
 
62
- /** The check mark on a `menuRowChecked` row: the theme's selected ink. */
63
- export const menuRowCheckInk = "$selectedColor" as const;
64
+ /** The check mark on a `menuRowChecked` row: the theme's accent (FZ-8557). */
65
+ export const menuRowCheckInk = "$accentColor" as const;
64
66
 
65
67
  type ThemeValues = Record<string, { val?: unknown } | undefined>;
66
68
 
@@ -72,10 +74,10 @@ function isHueless(paint: string): boolean {
72
74
  }
73
75
 
74
76
  /**
75
- * The paint for a checked row's check (LC-176, FZ-8355 r6). A colour theme
76
- * marks it in its selected ink; a hue-less theme's selected ink is a muted
77
- * grey that reads as a thin grey tick on the fill, so it takes the primary
78
- * ink instead, the bold mono glyph. Never undefined.
77
+ * The paint for a checked row's check (LC-176, FZ-8355 r6, FZ-8557). A colour
78
+ * theme marks it in its accent; a hue-less theme's accent is a muted grey that
79
+ * reads as a thin grey tick on the fill, so it takes the primary ink instead,
80
+ * the bold mono glyph. Never undefined.
79
81
  */
80
82
  export function resolveMenuRowCheckInk(theme: ThemeValues): string {
81
83
  const tint = theme[menuRowCheckInk.slice(1)]?.val;
@@ -217,6 +217,24 @@ describe("resolveChartPalette", () => {
217
217
  );
218
218
  });
219
219
 
220
+ it("leads with the series cycle for a hueless accent in both schemes (LC-172)", () => {
221
+ // A hueless preset's dark accent resolves to a mid-grey step: readable,
222
+ // not ink, and still no series hue.
223
+ const midGrey = Colors.grayDark.gray9;
224
+ const dark = resolveChartPalette({ scheme: "dark", identitySolid: midGrey, tint: false });
225
+ expect(dark.single).toBe(Colors.blueDark.blue9);
226
+ expect(dark.categorical).not.toContain(midGrey);
227
+ const light = resolveChartPalette({ scheme: "light", identitySolid: "#111111", tint: false });
228
+ expect(light.single).toBe(Colors.blue.blue10);
229
+ // A gray tint chose gray; a hued accent keeps its hue.
230
+ expect(
231
+ resolveChartPalette({ scheme: "light", identitySolid: grayTintSolid, tint: true }).single,
232
+ ).toBe(grayTintSolid);
233
+ expect(
234
+ resolveChartPalette({ scheme: "dark", identitySolid: darkAccent, tint: false }).single,
235
+ ).toBe(darkAccent);
236
+ });
237
+
220
238
  it("single-series takes the theme identity solid", () => {
221
239
  expect(resolveChartPalette({ scheme: "light", identitySolid: lightAccent }).single).toBe(
222
240
  lightAccent,
@@ -55,6 +55,12 @@ export interface ResolveChartPaletteInput {
55
55
  * Card.
56
56
  */
57
57
  surfaces?: readonly (string | undefined)[];
58
+ /**
59
+ * The identity is a tint sub-theme's solid, chosen as the series hue (a gray
60
+ * tint stays gray). Otherwise it is the accent, and a hueless accent leads
61
+ * the series with the cycle (LC-172).
62
+ */
63
+ tint?: boolean;
58
64
  }
59
65
 
60
66
  /**
@@ -132,6 +138,10 @@ function isInkIdentity(color: string, scheme: "light" | "dark"): boolean {
132
138
  const page = normalizeToHex(chartReferenceSurfaces[scheme][0]) as string;
133
139
  return contrastRatio(relativeLuminance(hex), relativeLuminance(page)) >= inkContrastFloor;
134
140
  }
141
+ function isNeutral(color: string): boolean {
142
+ const hsl = colorToHsl(color);
143
+ return !!hsl && hsl.s < neutralSaturationFloor;
144
+ }
135
145
  /** Cycle hues closer than this to the identity hue are dropped as confusable. */
136
146
  const hueDedupeThresholdDeg = 30;
137
147
 
@@ -221,7 +231,12 @@ export function resolveChartPalette(input: ResolveChartPaletteInput): ChartPalet
221
231
  const cycle = categoricalHueCycle.map((entry) => (scheme === "dark" ? entry.dark : entry.light));
222
232
  // LC-172: an ink identity (a hueless preset's near-black, or near-white in
223
233
  // dark) paints marks as solid as text, so the series leads with the cycle.
224
- const single = isInkIdentity(identity, scheme) ? cycle[0] : identity;
234
+ // A hueless accent does too in either scheme: in dark it resolves to a
235
+ // mid-grey step that is not ink but is still no series hue.
236
+ const single =
237
+ isInkIdentity(identity, scheme) || (input.tint === false && isNeutral(identity))
238
+ ? cycle[0]
239
+ : identity;
225
240
  const identityHsl = colorToHsl(single) as Hsl;
226
241
 
227
242
  const deduped =
@@ -303,6 +318,7 @@ export function useChartPalette(): ChartPalette {
303
318
  color11,
304
319
  ],
305
320
  surfaces: [page, card],
321
+ tint: isTint,
306
322
  }),
307
323
  // eslint-disable-next-line react-hooks/exhaustive-deps
308
324
  [scheme, identitySolid, isTint, accentKey, color10, color11, page, card],
@@ -1658,12 +1658,15 @@ export function ThemeDevtoolsPanel({
1658
1658
  : {}),
1659
1659
  }}
1660
1660
  onClick={handleCopySnapshot}
1661
+ aria-label={
1662
+ copyStatus === "copied"
1663
+ ? "Copied"
1664
+ : copyStatus === "error"
1665
+ ? "Copy failed"
1666
+ : "Copy snapshot"
1667
+ }
1661
1668
  >
1662
- {copyStatus === "copied"
1663
- ? "Copied!"
1664
- : copyStatus === "error"
1665
- ? "Failed"
1666
- : "Copy Snapshot"}
1669
+ {copyStatus === "copied" ? "✓" : copyStatus === "error" ? "!" : "⧉"}
1667
1670
  </button>
1668
1671
  <button type="button" style={styles.resetBtn} onClick={handleRandomize}>
1669
1672
  Random
@@ -12,7 +12,7 @@
12
12
  */
13
13
 
14
14
  import type { ReactNode } from "react";
15
- import { createContext, useContext } from "react";
15
+ import { createContext, useContext, useMemo } from "react";
16
16
  import { useMedia } from "tamagui";
17
17
 
18
18
  const PageGutterContext = createContext<string | null>(null);
@@ -36,6 +36,41 @@ export function usePageGutter(): string | null {
36
36
  return useContext(PageGutterContext);
37
37
  }
38
38
 
39
+ /**
40
+ * LC-159, nested Screen amendment (FZ-7993): a page shell declares itself to
41
+ * the content under it, so a `Screen` inside another `Screen`'s content merges
42
+ * into it instead of rendering a second page. The parent keeps the page's one
43
+ * gutter, cap, scroll view, pinned bar and bottom edge; the nested Screen adds
44
+ * only what this record says the parent lacks. It lives beside the gutter, in
45
+ * the one package every host and every page shell resolves to the same module.
46
+ */
47
+ export interface ParentScreen {
48
+ /** The parent's scroll view carries its content. */
49
+ scrolls: boolean;
50
+ /** The gutter token the page applies, or null when nothing pads it yet. */
51
+ inset: string | null;
52
+ /** A content cap is already applied above. */
53
+ capped: boolean;
54
+ }
55
+
56
+ const ParentScreenContext = createContext<ParentScreen | null>(null);
57
+
58
+ /** Declares a page shell to the content under it. Renders no DOM. */
59
+ export function ScreenNesting({
60
+ scrolls,
61
+ inset,
62
+ capped,
63
+ children,
64
+ }: ParentScreen & { children: ReactNode }) {
65
+ const value = useMemo(() => ({ scrolls, inset, capped }), [scrolls, inset, capped]);
66
+ return <ParentScreenContext.Provider value={value}>{children}</ParentScreenContext.Provider>;
67
+ }
68
+
69
+ /** The page shell this content sits in, or null at the top of a page. */
70
+ export function useParentScreen(): ParentScreen | null {
71
+ return useContext(ParentScreenContext);
72
+ }
73
+
39
74
  /** `$4` → `$-4`. */
40
75
  export function negateSpaceToken(token: string): string {
41
76
  if (token.startsWith("$-")) return `$${token.slice(2)}`;
@@ -37,34 +37,36 @@ export declare const menuRowFrame: {
37
37
  /**
38
38
  * LC-262: a checked or selected menu or picker row is highlighted, so it reads
39
39
  * as chosen without hunting for the check (FZ-8355 r6, rv_9244d1b063a3a4de).
40
- * Light rests on the LC-05 selection surface `$color4`, one step past the
41
- * `$color3` hover. A dark overlay is itself `$color4` (`surface2`), so dark
42
- * recesses to `$color2`, the band Clay rated good. In a colour theme both
43
- * steps carry its hue. Hover and press keep the fill, so a checked row never
44
- * drops to the transient hover fill. Spread it last on the row so it wins
45
- * over the consumer's hover and keyboard-cursor fills; a consumer that paints
46
- * focus as a fill paints `backgroundColor` there too. Focus rings stay the
47
- * consumer's.
40
+ * The fill is a selection tint one step off the panel toward the ink, the way
41
+ * HIG lifts a selection off its material (FZ-8557, Round 40). Light rests on
42
+ * `$color3` over the white `$color1` panel, a tint and not the `$color4` slab.
43
+ * A dark overlay is `$color4` (`surface2`), so dark rests on `$color5`, a step
44
+ * lighter: a recessed `$color2` read as a hole in the panel. In a colour theme
45
+ * both steps carry its hue. Hover and press keep the fill, so a checked row
46
+ * never drops to the transient hover fill. Spread it last on the row so it
47
+ * wins over the consumer's hover and keyboard-cursor fills; a consumer that
48
+ * paints focus as a fill paints `backgroundColor` there too. Focus rings stay
49
+ * the consumer's.
48
50
  */
49
51
  export declare function menuRowChecked(scheme: ColorScheme): {
50
- readonly backgroundColor: "$color2" | "$color4";
52
+ readonly backgroundColor: "$color3" | "$color5";
51
53
  readonly hoverStyle: {
52
- readonly backgroundColor: "$color2" | "$color4";
54
+ readonly backgroundColor: "$color3" | "$color5";
53
55
  };
54
56
  readonly pressStyle: {
55
- readonly backgroundColor: "$color2" | "$color4";
57
+ readonly backgroundColor: "$color3" | "$color5";
56
58
  };
57
59
  };
58
- /** The check mark on a `menuRowChecked` row: the theme's selected ink. */
59
- export declare const menuRowCheckInk: "$selectedColor";
60
+ /** The check mark on a `menuRowChecked` row: the theme's accent (FZ-8557). */
61
+ export declare const menuRowCheckInk: "$accentColor";
60
62
  type ThemeValues = Record<string, {
61
63
  val?: unknown;
62
64
  } | undefined>;
63
65
  /**
64
- * The paint for a checked row's check (LC-176, FZ-8355 r6). A colour theme
65
- * marks it in its selected ink; a hue-less theme's selected ink is a muted
66
- * grey that reads as a thin grey tick on the fill, so it takes the primary
67
- * ink instead, the bold mono glyph. Never undefined.
66
+ * The paint for a checked row's check (LC-176, FZ-8355 r6, FZ-8557). A colour
67
+ * theme marks it in its accent; a hue-less theme's accent is a muted grey that
68
+ * reads as a thin grey tick on the fill, so it takes the primary ink instead,
69
+ * the bold mono glyph. Never undefined.
68
70
  */
69
71
  export declare function resolveMenuRowCheckInk(theme: ThemeValues): string;
70
72
  /** Live `resolveMenuRowCheckInk` for the theme in scope. */
@@ -1 +1 @@
1
- {"version":3,"file":"menuRow.d.ts","sourceRoot":"","sources":["../src/menuRow.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,YAAY;;;;;;;;CAQf,CAAC;AAEX;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW;;;;;;;;EAOjD;AAED,0EAA0E;AAC1E,eAAO,MAAM,eAAe,EAAG,gBAAyB,CAAC;AAEzD,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE;IAAE,GAAG,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,CAAC,CAAC;AASjE;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAKjE;AAED,4DAA4D;AAC5D,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C"}
1
+ {"version":3,"file":"menuRow.d.ts","sourceRoot":"","sources":["../src/menuRow.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,YAAY;;;;;;;;CAQf,CAAC;AAEX;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW;;;;;;;;EAOjD;AAED,8EAA8E;AAC9E,eAAO,MAAM,eAAe,EAAG,cAAuB,CAAC;AAEvD,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE;IAAE,GAAG,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,CAAC,CAAC;AASjE;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAKjE;AAED,4DAA4D;AAC5D,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C"}
@@ -52,6 +52,12 @@ export interface ResolveChartPaletteInput {
52
52
  * Card.
53
53
  */
54
54
  surfaces?: readonly (string | undefined)[];
55
+ /**
56
+ * The identity is a tint sub-theme's solid, chosen as the series hue (a gray
57
+ * tint stays gray). Otherwise it is the accent, and a hueless accent leads
58
+ * the series with the cycle (LC-172).
59
+ */
60
+ tint?: boolean;
55
61
  }
56
62
  /**
57
63
  * Pure palette resolution — see {@link ChartPalette} for the contract.
@@ -1 +1 @@
1
- {"version":3,"file":"chartPalette.d.ts","sourceRoot":"","sources":["../../src/theme/chartPalette.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,YAAY;IAC3B,uCAAuC;IACvC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC;IACzB,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,sEAAsE;IACtE,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/D;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC;IACzB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kFAAkF;IAClF,kBAAkB,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC;IACrD;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC;CAC5C;AAuJD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,wBAAwB,GAAG,YAAY,CA4BjF;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,MAAM,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,GACtC,MAAM,EAAE,CAaV;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,IAAI,YAAY,CAgC9C"}
1
+ {"version":3,"file":"chartPalette.d.ts","sourceRoot":"","sources":["../../src/theme/chartPalette.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,YAAY;IAC3B,uCAAuC;IACvC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC;IACzB,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,sEAAsE;IACtE,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/D;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC;IACzB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kFAAkF;IAClF,kBAAkB,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC;IACrD;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC;IAC3C;;;;OAIG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AA2JD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,wBAAwB,GAAG,YAAY,CAiCjF;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,MAAM,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,GACtC,MAAM,EAAE,CAaV;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,IAAI,YAAY,CAiC9C"}
@@ -1 +1 @@
1
- {"version":3,"file":"ThemeDevtoolsPanel.d.ts","sourceRoot":"","sources":["../../../src/theme/devtools/ThemeDevtoolsPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAuLH,KAAK,UAAU,GAAG;IAChB,OAAO,EAAE,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;IACrC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC;IACxB,GAAG,EAAE,CAAC,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,MAAM,KAAK,IAAI,CAAC;CAC/C,CAAC;AA4hBF,MAAM,WAAW,uBAAuB;IACtC;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,UAAU,CAAC;IAEjC;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAEjC;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IAExB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IAEvB,qEAAqE;IACrE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B,oEAAoE;IACpE,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAE7C;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAmDD,wBAAgB,kBAAkB,CAAC,EACjC,aAAa,EACb,YAAY,EACZ,aAAa,EACb,WAAW,EACX,iBAAiB,EACjB,kBAAkB,EAClB,aAAa,GACd,EAAE,uBAAuB,2CAm5BzB"}
1
+ {"version":3,"file":"ThemeDevtoolsPanel.d.ts","sourceRoot":"","sources":["../../../src/theme/devtools/ThemeDevtoolsPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAuLH,KAAK,UAAU,GAAG;IAChB,OAAO,EAAE,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;IACrC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC;IACxB,GAAG,EAAE,CAAC,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,MAAM,KAAK,IAAI,CAAC;CAC/C,CAAC;AA4hBF,MAAM,WAAW,uBAAuB;IACtC;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,UAAU,CAAC;IAEjC;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAEjC;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IAExB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IAEvB,qEAAqE;IACrE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B,oEAAoE;IACpE,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAE7C;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAmDD,wBAAgB,kBAAkB,CAAC,EACjC,aAAa,EACb,YAAY,EACZ,aAAa,EACb,WAAW,EACX,iBAAiB,EACjB,kBAAkB,EAClB,aAAa,GACd,EAAE,uBAAuB,2CAs5BzB"}
@@ -23,6 +23,28 @@ export interface PageGutterProps {
23
23
  export declare function PageGutter({ inset, children }: PageGutterProps): import("react/jsx-runtime").JSX.Element;
24
24
  /** The nearest page gutter token, or null off the page line. */
25
25
  export declare function usePageGutter(): string | null;
26
+ /**
27
+ * LC-159, nested Screen amendment (FZ-7993): a page shell declares itself to
28
+ * the content under it, so a `Screen` inside another `Screen`'s content merges
29
+ * into it instead of rendering a second page. The parent keeps the page's one
30
+ * gutter, cap, scroll view, pinned bar and bottom edge; the nested Screen adds
31
+ * only what this record says the parent lacks. It lives beside the gutter, in
32
+ * the one package every host and every page shell resolves to the same module.
33
+ */
34
+ export interface ParentScreen {
35
+ /** The parent's scroll view carries its content. */
36
+ scrolls: boolean;
37
+ /** The gutter token the page applies, or null when nothing pads it yet. */
38
+ inset: string | null;
39
+ /** A content cap is already applied above. */
40
+ capped: boolean;
41
+ }
42
+ /** Declares a page shell to the content under it. Renders no DOM. */
43
+ export declare function ScreenNesting({ scrolls, inset, capped, children, }: ParentScreen & {
44
+ children: ReactNode;
45
+ }): import("react/jsx-runtime").JSX.Element;
46
+ /** The page shell this content sits in, or null at the top of a page. */
47
+ export declare function useParentScreen(): ParentScreen | null;
26
48
  /** `$4` → `$-4`. */
27
49
  export declare function negateSpaceToken(token: string): string;
28
50
  export interface PhoneTableBleed {
@@ -1 +1 @@
1
- {"version":3,"file":"pageGutter.d.ts","sourceRoot":"","sources":["../../src/theme/pageGutter.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMvC,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,oFAAoF;AACpF,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,eAAe,2CAE9D;AAED,gEAAgE;AAChE,wBAAgB,aAAa,IAAI,MAAM,GAAG,IAAI,CAE7C;AAED,oBAAoB;AACpB,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGtD;AAED,MAAM,WAAW,eAAe;IAC9B,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,KAAK,EAAE;QAAE,gBAAgB,EAAE,MAAM,CAAA;KAAE,CAAC;CACrC;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,eAAe,GAAG,IAAI,CAK3D"}
1
+ {"version":3,"file":"pageGutter.d.ts","sourceRoot":"","sources":["../../src/theme/pageGutter.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMvC,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,oFAAoF;AACpF,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,eAAe,2CAE9D;AAED,gEAAgE;AAChE,wBAAgB,aAAa,IAAI,MAAM,GAAG,IAAI,CAE7C;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B,oDAAoD;IACpD,OAAO,EAAE,OAAO,CAAC;IACjB,2EAA2E;IAC3E,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,8CAA8C;IAC9C,MAAM,EAAE,OAAO,CAAC;CACjB;AAID,qEAAqE;AACrE,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,KAAK,EACL,MAAM,EACN,QAAQ,GACT,EAAE,YAAY,GAAG;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,2CAGxC;AAED,yEAAyE;AACzE,wBAAgB,eAAe,IAAI,YAAY,GAAG,IAAI,CAErD;AAED,oBAAoB;AACpB,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGtD;AAED,MAAM,WAAW,eAAe;IAC9B,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,KAAK,EAAE;QAAE,gBAAgB,EAAE,MAAM,CAAA;KAAE,CAAC;CACrC;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,eAAe,GAAG,IAAI,CAK3D"}