* 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.
71 lines
2.1 KiB
TypeScript
71 lines
2.1 KiB
TypeScript
import { Fragment, type ReactNode } from "react";
|
|
import { withUnistyles } from "react-native-unistyles";
|
|
import type { Theme } from "@/styles/theme";
|
|
|
|
interface AppearanceStyleBoundaryProps {
|
|
appearanceKey?: string;
|
|
children: ReactNode;
|
|
}
|
|
|
|
function AppearanceStyleBoundaryBase({ appearanceKey, children }: AppearanceStyleBoundaryProps) {
|
|
return <Fragment key={appearanceKey}>{children}</Fragment>;
|
|
}
|
|
|
|
export function appearanceStyleBoundaryKey(theme: Theme): string {
|
|
return [
|
|
theme.fontFamily.ui,
|
|
theme.fontFamily.mono,
|
|
theme.fontSize.sm,
|
|
theme.fontSize.base,
|
|
theme.fontSize.lg,
|
|
theme.fontSize.xl,
|
|
theme.fontSize["2xl"],
|
|
theme.fontSize["3xl"],
|
|
theme.fontSize["4xl"],
|
|
theme.fontSize.content,
|
|
theme.fontSize.code,
|
|
theme.lineHeight.diff,
|
|
theme.colors.foreground,
|
|
theme.colors.foregroundMuted,
|
|
theme.colors.mutedForeground,
|
|
theme.colors.surface1,
|
|
theme.colors.surface2,
|
|
theme.colors.border,
|
|
theme.colors.accentBright,
|
|
theme.colors.syntax.keyword,
|
|
theme.colors.syntax.comment,
|
|
theme.colors.syntax.string,
|
|
theme.colors.syntax.number,
|
|
theme.colors.syntax.literal,
|
|
theme.colors.syntax.function,
|
|
theme.colors.syntax.definition,
|
|
theme.colors.syntax.class,
|
|
theme.colors.syntax.type,
|
|
theme.colors.syntax.tag,
|
|
theme.colors.syntax.attribute,
|
|
theme.colors.syntax.property,
|
|
theme.colors.syntax.variable,
|
|
theme.colors.syntax.operator,
|
|
theme.colors.syntax.punctuation,
|
|
theme.colors.syntax.regexp,
|
|
theme.colors.syntax.escape,
|
|
theme.colors.syntax.meta,
|
|
theme.colors.syntax.heading,
|
|
theme.colors.syntax.link,
|
|
].join("\u0000");
|
|
}
|
|
|
|
function appearanceStyleBoundaryMapping(theme: Theme): Partial<AppearanceStyleBoundaryProps> {
|
|
return { appearanceKey: appearanceStyleBoundaryKey(theme) };
|
|
}
|
|
|
|
const ThemedAppearanceStyleBoundary = withUnistyles(AppearanceStyleBoundaryBase);
|
|
|
|
export function AppearanceStyleBoundary({ children }: { children: ReactNode }) {
|
|
return (
|
|
<ThemedAppearanceStyleBoundary uniProps={appearanceStyleBoundaryMapping}>
|
|
{children}
|
|
</ThemedAppearanceStyleBoundary>
|
|
);
|
|
}
|