بنقرة واحدة
client-classnames
Use when adding or changing conditional class names in apps/client.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Use when adding or changing conditional class names in apps/client.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Use when adding, changing, extracting, or reusing client components, including Storybook stories and controls.
Use when adding or changing forms in apps/client.
Use when changing GitHub OAuth, session cookies, SessionGuard, logout, or authenticated API request identity.
Use when adding or changing routes in apps/client.
Use when adding or changing client state, React Query data flow, immutable context values, or Zustand stores.
Use when styling apps/client with Tailwind CSS v4.
| name | client-classnames |
| description | Use when adding or changing conditional class names in apps/client. |
Generated from ai/registry.json. Do not edit manually.
Canonical skill: ../../../ai/skills/client-classnames.md.
Referenced context:
../../../ai/rules/client-styling-rules.md../../../ai/examples/good-client-component.mdThis file is compiled from canonical AI knowledge files. Edit canonical files under ai, then run npm run ai:sync.
ai/skills/client-classnames.mdUse this skill when adding or changing conditional class names in apps/client.
Compose conditional Tailwind class names consistently without adding local helper variants.
ai/rules/client-styling-rules.mdai/examples/good-client-component.mdcls only when conditional classes or caller-provided className need composition.classnames is imported as cls.classNames, cn, or wrapper helper is added without repeated need.npm --workspace @capture-flag/client run build.ai/rules/client-styling-rules.mdRules for Tailwind CSS v4 and class composition in apps/client.
@tailwindcss/vite and @import "tailwindcss".styles.css with CSS custom properties and @theme inline when they are true app-wide tokens.classnames package for conditional class composition.classnames as cls with import cls from "classnames";.cls("base", { "active": isActive }).cls when appending or composing conditional class sets.classNames, cn, or wrapper helpers without a concrete repeated need.styles.css when component utility classes can express the behavior.npm --workspace @capture-flag/client run build after styling changes.ai/examples/good-client-component.mdSource: apps/client/src/components/Button.tsx (sha256: 7e1bcb1c45c5d1a5610f108be5028ce68d34ded2c394d326428eca08702a992d)
Source: apps/client/src/components/Panel.tsx (sha256: c0dfcd9d6984e9741af7abe91c60ad8bcb30e4d8f18c3c1456bdea5882d2472f)
Why this is canonical:
classnames as cls for optional classes.Canonical shared component patterns from apps/client/src/components.
import cls from "classnames";
import type { ComponentPropsWithoutRef } from "react";
type ButtonVariant = "primary" | "secondary" | "danger" | "ghost";
const baseButtonClassName =
"inline-flex h-9 shrink-0 items-center justify-center gap-2 whitespace-nowrap rounded-md px-4 py-2 text-sm font-medium shadow-xs outline-none transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4";
const buttonClassNames: Record<ButtonVariant, string> = {
danger:
"border border-transparent bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20",
ghost:
"border border-transparent bg-transparent text-foreground shadow-none hover:bg-accent hover:text-accent-foreground",
primary: "border border-transparent bg-primary text-primary-foreground hover:bg-primary/90",
secondary:
"border border-border bg-background text-foreground hover:bg-accent hover:text-accent-foreground",
};
type ButtonProps = ComponentPropsWithoutRef<"button"> & {
variant?: ButtonVariant;
};
export function Button({ className, variant = "primary", ...props }: ButtonProps) {
return (
<button className={cls(baseButtonClassName, buttonClassNames[variant], className)} {...props} />
);
}
This accepts native button props, keeps variants explicit, and uses cls for optional classes.
export function Panel({ children, className, showTitle = true, title, wide = false }: PanelProps) {
return (
<section
className={cls("grid gap-4 text-foreground", className, {
"lg:col-span-2": wide,
})}
>
{showTitle ? <h2 className="text-xl font-semibold tracking-tight">{title}</h2> : null}
{children}
</section>
);
}
This keeps layout composition explicit through children, accepts optional native composition through className, and preserves product visual language.