mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-23 09:42:53 +00:00
The subagent track rows were as dense on a phone as in the desktop popover, and the archive and detach actions were hand-rolled pressables that only recoloured the glyph, so a tap or hover never showed the rounded highlight every other icon action has. Rows now take the compact menu-row height and padding below the `md` breakpoint, decided once in the track row style; the desktop popover keeps its density. The actions are `ToolbarButton`, which owns the hitbox, the rounded highlight on hover and press, the compact size, and the tooltip. A repo oxlint rule, `paseo/no-raw-pressable`, reports `Pressable` and `Touchable*` imports outside `components/ui/` so the next tap target reaches for a primitive. Existing importers are on a burn-down list they can only leave. The rule is its own name rather than another `no-restricted-imports` entry so its override cannot interact with the existing burn-downs. Its test runs the real oxlint binary and is wired into the CI quality job.
43 lines
1.4 KiB
JavaScript
43 lines
1.4 KiB
JavaScript
// Repo-specific oxlint rules. Each rule is its own name, so its burn-down list in .oxlintrc.json
|
|
// is one override that cannot interact with the `no-restricted-imports` burn-downs.
|
|
|
|
const PRESS_PRIMITIVE_SOURCES = new Set(["react-native", "react-native-gesture-handler"]);
|
|
const PRESS_PRIMITIVE_NAMES = new Set([
|
|
"Pressable",
|
|
"TouchableHighlight",
|
|
"TouchableNativeFeedback",
|
|
"TouchableOpacity",
|
|
"TouchableWithoutFeedback",
|
|
]);
|
|
|
|
export const NO_RAW_PRESSABLE_MESSAGE =
|
|
"A raw pressable has no standard press or hover feedback. Icon actions use ToolbarButton " +
|
|
"(@/components/ui/pane-content-toolbar); rows on a menu surface use MenuItem or " +
|
|
"ComposerTrackRow; other rows use PressHighlight (@/components/ui/press-highlight); labelled " +
|
|
"buttons use Button. See docs/design.md §2.";
|
|
|
|
const noRawPressable = {
|
|
create(context) {
|
|
return {
|
|
ImportDeclaration(node) {
|
|
if (!PRESS_PRIMITIVE_SOURCES.has(node.source.value)) return;
|
|
for (const specifier of node.specifiers) {
|
|
if (
|
|
specifier.type === "ImportSpecifier" &&
|
|
PRESS_PRIMITIVE_NAMES.has(specifier.imported.name)
|
|
) {
|
|
context.report({ node: specifier, message: NO_RAW_PRESSABLE_MESSAGE });
|
|
}
|
|
}
|
|
},
|
|
};
|
|
},
|
|
};
|
|
|
|
export default {
|
|
meta: { name: "paseo" },
|
|
rules: {
|
|
"no-raw-pressable": noRawPressable,
|
|
},
|
|
};
|