mirror of
https://github.com/jakejarvis/sofa.git
synced 2026-07-14 18:15:56 -04:00
Migrate the entire monorepo from Biome 2.4.7 to oxlint 1.56.0 (linter) and oxfmt 0.41.0 (formatter) for faster lint/format and broader rule coverage. - Add `.oxlintrc.json` with React, TypeScript, unicorn, import plugins and correctness/suspicious categories - Add `.oxfmtrc.json` with 2-space indent, import sorting, and Tailwind class sorting (all 30+ custom className attributes migrated) - Add `docs/.oxlintrc.json` and `docs/.oxfmtrc.json` with Next.js plugin - Update all 12 workspace package.json scripts: `oxlint`, `oxfmt`, `oxfmt --check` - Add `format:check` turbo task and CI step - Update VS Code settings/extensions to use `oxc.oxc-vscode` - Update CI path triggers from `biome.json` to new config files - Remove all `biome-ignore` comments and fix shadowed variables - Delete `biome.json` and `docs/biome.json` - Reformat entire codebase with oxfmt Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
62 lines
1.9 KiB
TypeScript
62 lines
1.9 KiB
TypeScript
import { IconTrash } from "@tabler/icons-react-native";
|
|
import type { PropsWithChildren } from "react";
|
|
import { View } from "react-native";
|
|
import ReanimatedSwipeable from "react-native-gesture-handler/ReanimatedSwipeable";
|
|
import type { SharedValue } from "react-native-reanimated";
|
|
import Animated, { interpolate, useAnimatedStyle } from "react-native-reanimated";
|
|
|
|
import { ScaledIcon } from "@/components/ui/scaled-icon";
|
|
import * as Haptics from "@/utils/haptics";
|
|
|
|
const ACTION_WIDTH = 80;
|
|
|
|
function RightAction({ drag }: { drag: SharedValue<number> }) {
|
|
const animatedStyle = useAnimatedStyle(() => {
|
|
const scale = interpolate(drag.get(), [0, -ACTION_WIDTH], [0.6, 1], {
|
|
extrapolateLeft: "clamp",
|
|
extrapolateRight: "clamp",
|
|
});
|
|
return { transform: [{ scale }] };
|
|
});
|
|
|
|
return (
|
|
<View className="bg-destructive items-center justify-center" style={{ width: ACTION_WIDTH }}>
|
|
<Animated.View style={animatedStyle}>
|
|
<ScaledIcon icon={IconTrash} size={22} color="#fff" />
|
|
</Animated.View>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
interface SwipeableRowProps extends PropsWithChildren {
|
|
onDelete: () => void;
|
|
}
|
|
|
|
export function SwipeableRow({ onDelete, children }: SwipeableRowProps) {
|
|
return (
|
|
<View
|
|
accessibilityActions={[{ name: "delete", label: "Delete" }]}
|
|
onAccessibilityAction={(event) => {
|
|
if (event.nativeEvent.actionName === "delete") {
|
|
onDelete();
|
|
}
|
|
}}
|
|
>
|
|
<ReanimatedSwipeable
|
|
friction={2}
|
|
rightThreshold={40}
|
|
overshootRight={false}
|
|
renderRightActions={(_progress, drag) => <RightAction drag={drag} />}
|
|
onSwipeableOpen={(direction) => {
|
|
if (direction === "left") {
|
|
Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success);
|
|
onDelete();
|
|
}
|
|
}}
|
|
>
|
|
{children}
|
|
</ReanimatedSwipeable>
|
|
</View>
|
|
);
|
|
}
|