Libs shipped as bare source with no manifest — consumable only via per-app vite/tsconfig alias surgery, no version contract, no tree-shaking signal. Add a minimal package.json matching the @crema/content-ui template: entry + exports map, declared peerDependencies, sideEffects:false. Mechanical, no code change. Frontend audit 2026-06-20, rank 2. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@crema/arcadia-auth-ui
Auth screens for arcadia-backed apps — login, signup, password reset, 2FA, OAuth, invitation acceptance — wired to @crema/arcadia-core-client and themed via Skyrise tokens (var(--card), var(--foreground), var(--primary), --radius).
Components are headless about routing — each takes callbacks (onSuccess, onForgotPassword, etc) so the consuming app routes the user wherever it wants.
Public API
import { LoginForm } from "@crema/arcadia-auth-ui";
Planned additions: SignupForm, PasswordResetRequestForm, PasswordResetConfirmForm, TwoFactorChallengeForm, TwoFactorSetupForm, OAuthButtons, InvitationAcceptForm.
Usage
In a route component (e.g. app/routes/login.tsx):
import { LoginForm } from "@crema/arcadia-auth-ui";
import { useNavigate } from "react-router";
export default function Login() {
const navigate = useNavigate();
return (
<div style={{ display: "grid", placeItems: "center", minHeight: "100dvh", padding: "2rem" }}>
<LoginForm
onSuccess={async ({ tokens, twoFactorRequired, twoFactorChallenge }) => {
if (twoFactorRequired) {
navigate("/login/2fa", { state: { challenge: twoFactorChallenge } });
return;
}
sessionStorage.setItem("arcadia_token", tokens.access_token);
navigate("/");
}}
onForgotPassword={() => navigate("/login/forgot")}
onSignup={() => navigate("/signup")}
/>
</div>
);
}
Requires <ArcadiaProvider> somewhere up the tree (typically in app/root.tsx).
Theming
All components consume Skyrise tokens via inline styles with CSS variables (the lib convention — components in libs don't use Tailwind classes). They render correctly under any theme that satisfies the Skyrise token contract.
Surface tints (body[data-surface="snow|stone|sage|slate"]) and dark mode (html.dark) work transparently — the form picks up whatever the active surface defines.
Conventions
- Inline imports only — no own
package.json. - Path-aliased into apps via
tsconfig.jsonpaths:@crema/arcadia-auth-ui→../lib-arcadia-auth-ui/src/index.tsx. - Tailwind
@sourceline in the consuming app'sapp.cssso any utility classes used (none today, but room for them) get scanned. - Every interactive element has
data-action="auth-<id>"so scripts and the LLM action bus can drive auth flows in tests / demos.