بنقرة واحدة
react
// Use when creating or editing frontend React code in react-ui or ui-components packages. Triggers on any frontend component, hook, or UI work.
// Use when creating or editing frontend React code in react-ui or ui-components packages. Triggers on any frontend component, hook, or UI work.
| name | react |
| description | Use when creating or editing frontend React code in react-ui or ui-components packages. Triggers on any frontend component, hook, or UI work. |
When working on frontend code in packages/react-ui or packages/ui-components, follow these guidelines strictly.
packages/ui-components and must have Storybook stories in packages/ui-components/src/stories/.packages/react-ui.use-*.ts).hooks/ directories alongside features (e.g., features/campaigns/hooks/use-campaign-charts.ts).QueryKeys from @/app/constants/query-keys.ts — never hardcode query key strings.useQuery for reads, useMutation for writes.queryClient.invalidateQueries.enabled option for conditional queries.campaigns-api.ts).Example — existing pattern:
import { QueryKeys } from '@/app/constants/query-keys';
import { useQuery } from '@tanstack/react-query';
import { campaignsApi } from '../campaigns-api';
export function useCampaignCharts(campaignId: string) {
const { data: chartData } = useQuery({
queryKey: [QueryKeys.campaignCharts, campaignId],
queryFn: () => campaignsApi.getCharts(campaignId),
});
const weekData = useMemo(() => /* derive from chartData */, [chartData]);
return { chartData, weekData };
}
useMemo for expensive computations or derived state.useCallback selectively for handlers where referential stability matters (for example, props to memoized children or values used in hook dependency arrays).Prefer extraction when logic is non-trivial or stability matters:
// ✅ Simple inline callback — fine when the handler is trivial and local
<Button onClick={() => setOpen(true)}>Open</Button>;
// ✅ Extracted handler — preferred when logic is non-trivial or passed to memoized children
const handleSubmit = useCallback(
(values: FormValues) => {
const sanitized = sanitizeInput(values);
onSubmit?.(sanitized);
},
[onSubmit],
);
return <Form onSubmit={handleSubmit} />;
❌ Inline arrow functions in JSX for non-trivial logic or props to memoized children (can cause avoidable re-renders)
❌ Inline object/array literals in JSX props (breaks reference equality)
❌ Complex logic inside render (hard to test, poor separation of concerns)
❌ Missing dependency arrays in useEffect/useCallback/useMemo
❌ Unnecessary state (derive from props when possible)
❌ Hardcoded query key strings (use QueryKeys constants)
✅ Extract and memoize callbacks with useCallback when referential stability matters
✅ Extract complex JSX logic into separate memoized functions or sub-components
✅ Derive state with useMemo instead of storing duplicated state
✅ Keep component functions focused — one clear responsibility per function
✅ Move business logic into custom hooks
cn utility to group Tailwind classnames:<div
className={cn(
'absolute bottom-[-20px] left-1/2 -translate-x-1/2',
'w-[118px] h-[24px] flex items-center justify-center',
'font-satoshi font-medium text-xs text-blueAccent-500',
'border border-solid border-blueAccent-500 rounded-[4px]',
'bg-background-800',
{
'pt-2': !someVar,
},
)}
>
{t('Sample output data')}
</div>
When a component renders a variable-length list (.map() over connections, options, templates, search results, etc.), you MUST verify overflow behavior:
ScrollArea (from @openops/components/ui) or a dedicated scroll wrapper over ad-hoc overflow-y-auto + max-h classes. This keeps behavior consistent and responsive breakpoints centralized.Red flags to catch:
.map() rendering inside a flex/grid container with no height constraintoverflow-clip or overflow-hidden on a parent that hides scrollable contentWhen in doubt: render 20+ items and visually inspect before considering the work done.
npx nx test react-ui
npx nx test ui-components
npx nx lint react-ui
npx nx lint ui-components
@tanstack/react-query) for data fetchingapi.ts; use qs package for query stringstests/ folders alongside code (Jest)