Global lens in the home header: every list, Today, Projects and Review show only the active area; new rows are born into it. Tasks and projects gain an area column (personal default); the task form's Area chip re-files across areas. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SW5iVXkZ2JBHgyweMCRymY
65 lines
2.0 KiB
TypeScript
65 lines
2.0 KiB
TypeScript
// The personal / work switch that lives in the home header.
|
|
//
|
|
// A two-segment pill rather than a menu or a settings row: the whole point is
|
|
// that flipping halves of your life is one tap and its state is always
|
|
// visible. Work gets its own tone so a glance at the header tells you which
|
|
// lens is on even before you read the label.
|
|
import { Pressable, StyleSheet, Text, View } from "react-native";
|
|
import { haptic } from "../lib/haptics";
|
|
import { setArea } from "../lib/store";
|
|
import { C, radius, type } from "../lib/theme";
|
|
import { useStore } from "../lib/useStore";
|
|
import { AREA_LABEL, AREAS, type Area } from "../lib/types";
|
|
|
|
export const AREA_TONE: Record<Area, string> = { personal: C.accent, work: C.work };
|
|
|
|
export default function AreaToggle() {
|
|
const { area } = useStore();
|
|
return (
|
|
<View style={s.track} accessibilityRole="tablist">
|
|
{AREAS.map((a) => {
|
|
const active = a === area;
|
|
return (
|
|
<Pressable
|
|
key={a}
|
|
accessibilityRole="tab"
|
|
accessibilityState={{ selected: active }}
|
|
hitSlop={6}
|
|
onPress={() => {
|
|
if (active) return;
|
|
haptic.select();
|
|
setArea(a);
|
|
}}
|
|
style={({ pressed }) => [
|
|
s.segment,
|
|
active && { backgroundColor: AREA_TONE[a] },
|
|
pressed && !active && s.segmentPressed,
|
|
]}
|
|
>
|
|
<Text style={[s.label, active && s.labelActive]}>{AREA_LABEL[a]}</Text>
|
|
</Pressable>
|
|
);
|
|
})}
|
|
</View>
|
|
);
|
|
}
|
|
|
|
const s = StyleSheet.create({
|
|
track: {
|
|
flexDirection: "row",
|
|
padding: 3,
|
|
borderRadius: radius.pill,
|
|
backgroundColor: C.surface2,
|
|
borderWidth: StyleSheet.hairlineWidth,
|
|
borderColor: C.border,
|
|
},
|
|
segment: {
|
|
paddingVertical: 5,
|
|
paddingHorizontal: 16,
|
|
borderRadius: radius.pill,
|
|
},
|
|
segmentPressed: { backgroundColor: C.border },
|
|
label: { ...type.chip, color: C.textSecondary },
|
|
labelActive: { color: C.onAccent, fontWeight: "600" },
|
|
});
|