Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions apps/mobile/src/components/management-layout.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { expect, test } from "@jest/globals";
import { render, screen } from "@testing-library/react-native";
import { Dimensions, StyleSheet, Text, View } from "react-native";
import { SettingsGroup, SettingsRow } from "./management-layout";

test.each([1, 1.5])(
"settings rows adapt to font scale %s without reducing touch targets",
(fontScale) => {
const originalWindow = Dimensions.get("window");
const originalScreen = Dimensions.get("screen");
Dimensions.set({ window: { width: 390, height: 844, scale: 3, fontScale } });
const view = render(
<SettingsGroup title="Transcript">
<SettingsRow>
<Text>Detailed transcript</Text>
</SettingsRow>
</SettingsGroup>,
);
expect(screen.getByRole("header", { name: "Transcript" })).toBeOnTheScreen();
const row = screen.UNSAFE_getByType(SettingsRow).findByType(View);
expect(StyleSheet.flatten(row.props.style)).toMatchObject({
minHeight: 48,
flexDirection: fontScale >= 1.3 ? "column" : "row",
alignItems: fontScale >= 1.3 ? "stretch" : "center",
});
view.unmount();
Dimensions.set({ window: originalWindow, screen: originalScreen });
},
);
60 changes: 60 additions & 0 deletions apps/mobile/src/components/management-layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import type { ReactNode } from "react";
import { StyleSheet, Text, useWindowDimensions, View } from "react-native";

import { palette, radius, space, typography, usesLargeTextLayout } from "../theme";

export function SettingsGroup({ children, title }: { children: ReactNode; title: string }) {
return (
<View style={managementStyles.section}>
<Text accessibilityRole="header" style={managementStyles.sectionTitle}>
{title}
</Text>
<View style={managementStyles.group}>{children}</View>
</View>
);
}

export function SettingsRow({ children }: { children: ReactNode }) {
const { fontScale } = useWindowDimensions();
return (
<View
style={[
managementStyles.row,
usesLargeTextLayout(fontScale) && managementStyles.rowLargeText,
]}
>
{children}
</View>
);
}

export const managementStyles = StyleSheet.create({
content: {
alignSelf: "center",
width: "100%",
maxWidth: 680,
padding: space.md,
paddingBottom: space.xl,
gap: space.md,
},
description: { ...typography.caption, color: palette.dim },
section: { gap: space.xs },
sectionTitle: { ...typography.label, color: palette.dim },
group: {
backgroundColor: palette.card,
borderRadius: radius.md,
borderColor: palette.border,
borderWidth: StyleSheet.hairlineWidth,
overflow: "hidden",
},
row: {
alignItems: "center",
flexDirection: "row",
gap: space.sm,
minHeight: 48,
padding: space.sm,
borderBottomColor: palette.border,
borderBottomWidth: StyleSheet.hairlineWidth,
},
rowLargeText: { alignItems: "stretch", flexDirection: "column" },
});
29 changes: 29 additions & 0 deletions apps/mobile/src/components/request-card-styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { StyleSheet } from "react-native";
import { palette, radius, space, typography } from "../theme";

// Question and approval actions share visual sizing without shrinking touch targets.
export const requestCardStyles = StyleSheet.create({
actions: { flexDirection: "row", flexWrap: "wrap", gap: space.xs },
button: {
minHeight: 44,
paddingHorizontal: space.sm,
paddingVertical: space.xs,
borderRadius: radius.sm,
alignItems: "center",
justifyContent: "center",
borderColor: palette.border,
borderWidth: 1,
maxWidth: "100%",
},
buttonLabel: { ...typography.control, color: palette.ink, textAlign: "center" },
card: {
backgroundColor: palette.card,
borderColor: palette.border,
borderWidth: 1,
borderRadius: radius.md,
borderLeftWidth: 3,
borderLeftColor: palette.warm,
padding: 12,
gap: space.sm,
},
});
24 changes: 22 additions & 2 deletions apps/mobile/src/navigation/root-navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -153,12 +153,20 @@ export function RootNavigation() {
<Stack.Screen
component={SettingsScreen}
name="Settings"
options={{ presentation: "modal", title: "Settings" }}
options={({ navigation }) => ({
presentation: "modal",
title: "Settings",
headerRight: () => <ManagementDoneButton onPress={() => navigation.goBack()} />,
})}
/>
<Stack.Screen
component={FollowedProjectsScreen}
name="FollowedProjects"
options={{ presentation: "modal", title: "Followed projects" }}
options={({ navigation }) => ({
presentation: "modal",
title: "Followed projects",
headerRight: () => <ManagementDoneButton onPress={() => navigation.goBack()} />,
})}
/>
<Stack.Screen
name="Connections"
Expand All @@ -179,6 +187,18 @@ export function RootNavigation() {
);
}

function ManagementDoneButton({ onPress }: { onPress: () => void }) {
return (
<Pressable
accessibilityRole="button"
onPress={onPress}
style={{ minHeight: 44, justifyContent: "center", paddingHorizontal: 10 }}
>
<Text style={{ color: palette.ink, fontSize: 14, fontWeight: "600" }}>Done</Text>
</Pressable>
);
}

function WorkspaceHeader({
onBack,
title,
Expand Down
Loading
Loading