feat: personal/work area toggle
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
This commit is contained in:
64
app/src/components/AreaToggle.tsx
Normal file
64
app/src/components/AreaToggle.tsx
Normal file
@@ -0,0 +1,64 @@
|
||||
// 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" },
|
||||
});
|
||||
Reference in New Issue
Block a user