Fill frontend rule gaps and broaden v2 tokens
Add the frontend guides the v2 UI kit and compliance-portal need but that the first rework left uncovered: forms, routing, client state, and permission-gated UI. forms.md documents a tiered approach on Base UI Field/Form -- native constraints, then a validate function, then zod parsed in onSubmit, and react-hook-form only for large or dynamic forms -- and drops the custom useFormWithSchema wrapper. routing.md covers @probo/routes, navigation, typed params, URL-as-state, redirects, auth/protected routes, and the folded-in no-outlet-context rule. state-management.md gives a decision order across Relay, URL, local state, context, and zustand. permissions.md gates UI on the canUpdate/canDelete permission(action:) fields without re-encoding authorization in the client. Rename v2-colors.md to v2-tokens.md and add the typography, radius, shadow, and native-spacing scales alongside color. Extend ui.md with user feedback, empty-state, and accessibility sections; standardize toasts on Base UI's Toast (Toast.useToastManager) and retire the legacy useToast across ui.md, forms.md, error-handling.md, and relay.md. Add an Intl formatting section to i18n.md and a non-Relay HTTP / file upload-download section to ts-style.md. Update the AGENTS.md index and the v2-color-scale cursor rule for the new and renamed guides. Signed-off-by: Émile Ré <emile@probo.com>
This commit is contained in:
@@ -120,27 +120,27 @@ Boundaries will not catch a rejected promise in a submit handler. Wrap the risky
|
||||
```tsx
|
||||
// Good — async event handler guards itself; the boundary above can't help here
|
||||
function PublishButton() {
|
||||
const { __ } = useTranslate();
|
||||
const { toast } = useToast();
|
||||
const { t } = useTranslation();
|
||||
const toast = Toast.useToastManager();
|
||||
const [isPublishing, setIsPublishing] = useState(false);
|
||||
|
||||
async function onPublish() {
|
||||
setIsPublishing(true);
|
||||
try {
|
||||
await publishReport();
|
||||
toast({ title: __("Published"), variant: "success" });
|
||||
toast.add({ title: t("reports.published"), type: "success" });
|
||||
} catch (error) {
|
||||
toast({
|
||||
title: __("Publish failed"),
|
||||
description: error instanceof Error ? error.message : __("Unknown error"),
|
||||
variant: "error",
|
||||
toast.add({
|
||||
title: t("reports.publishFailed"),
|
||||
description: error instanceof Error ? error.message : t("common.unknownError"),
|
||||
type: "error",
|
||||
});
|
||||
} finally {
|
||||
setIsPublishing(false);
|
||||
}
|
||||
}
|
||||
|
||||
return <Button disabled={isPublishing} onClick={onPublish}>{__("Publish")}</Button>;
|
||||
return <Button disabled={isPublishing} onClick={onPublish}>{t("reports.publish")}</Button>;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user