Give readable content its own text size (#3637)
* feat(app): separate content typography from interface size Readable prose benefits from its own scale without inflating navigation and controls. Preserve existing users’ rendered size during migration while giving fresh desktop installs a 15px content default. * test(app): cover independent content typography The appearance journey now verifies that changing interface size leaves content size intact. Timeline traversal yields when a test deliberately holds the requested page, so the helper no longer waits on its own gate. * test(desktop): cover independent content typography The desktop appearance regression follows the renamed Interface control and verifies it does not alter Content size.
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { darkTheme } from "@/styles/theme";
|
||||
import { appearanceStyleBoundaryKey } from "./appearance-style-boundary";
|
||||
|
||||
describe("appearanceStyleBoundaryKey", () => {
|
||||
it("changes when content size changes without any other appearance token changing", () => {
|
||||
const contentOnlyChange = {
|
||||
...darkTheme,
|
||||
fontSize: { ...darkTheme.fontSize, content: darkTheme.fontSize.content + 1 },
|
||||
};
|
||||
|
||||
expect(appearanceStyleBoundaryKey(contentOnlyChange)).not.toBe(
|
||||
appearanceStyleBoundaryKey(darkTheme),
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -11,8 +11,8 @@ function AppearanceStyleBoundaryBase({ appearanceKey, children }: AppearanceStyl
|
||||
return <Fragment key={appearanceKey}>{children}</Fragment>;
|
||||
}
|
||||
|
||||
const appearanceStyleBoundaryMapping = (theme: Theme): Partial<AppearanceStyleBoundaryProps> => ({
|
||||
appearanceKey: [
|
||||
export function appearanceStyleBoundaryKey(theme: Theme): string {
|
||||
return [
|
||||
theme.fontFamily.ui,
|
||||
theme.fontFamily.mono,
|
||||
theme.fontSize.sm,
|
||||
@@ -22,6 +22,7 @@ const appearanceStyleBoundaryMapping = (theme: Theme): Partial<AppearanceStyleBo
|
||||
theme.fontSize["2xl"],
|
||||
theme.fontSize["3xl"],
|
||||
theme.fontSize["4xl"],
|
||||
theme.fontSize.content,
|
||||
theme.fontSize.code,
|
||||
theme.lineHeight.diff,
|
||||
theme.colors.foreground,
|
||||
@@ -51,8 +52,12 @@ const appearanceStyleBoundaryMapping = (theme: Theme): Partial<AppearanceStyleBo
|
||||
theme.colors.syntax.meta,
|
||||
theme.colors.syntax.heading,
|
||||
theme.colors.syntax.link,
|
||||
].join("\u0000"),
|
||||
});
|
||||
].join("\u0000");
|
||||
}
|
||||
|
||||
function appearanceStyleBoundaryMapping(theme: Theme): Partial<AppearanceStyleBoundaryProps> {
|
||||
return { appearanceKey: appearanceStyleBoundaryKey(theme) };
|
||||
}
|
||||
|
||||
const ThemedAppearanceStyleBoundary = withUnistyles(AppearanceStyleBoundaryBase);
|
||||
|
||||
|
||||
@@ -354,9 +354,12 @@ const userMessageStylesheet = StyleSheet.create((theme) => ({
|
||||
},
|
||||
text: {
|
||||
color: theme.colors.foreground,
|
||||
fontSize: theme.fontSize.base,
|
||||
fontSize: theme.fontSize.content,
|
||||
...(isWeb
|
||||
? { lineHeight: Math.round(theme.fontSize.base * 1.4), overflowWrap: "anywhere" as const }
|
||||
? {
|
||||
lineHeight: Math.round(theme.fontSize.content * 1.4),
|
||||
overflowWrap: "anywhere" as const,
|
||||
}
|
||||
: {}),
|
||||
},
|
||||
imagePreviewContainer: {
|
||||
@@ -1958,8 +1961,8 @@ const speakMessageStylesheet = StyleSheet.create((theme) => ({
|
||||
},
|
||||
text: {
|
||||
fontFamily: theme.fontFamily.ui,
|
||||
fontSize: theme.fontSize.base,
|
||||
lineHeight: Math.round(theme.fontSize.base * 1.4),
|
||||
fontSize: theme.fontSize.content,
|
||||
lineHeight: Math.round(theme.fontSize.content * 1.4),
|
||||
color: theme.colors.foreground,
|
||||
},
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user