Create Component
Create a new React component. The argument should be a path like features/product/ProductBadge or common/Tooltip.
Steps
- •
Parse
$ARGUMENTSto determine:- •Component path:
apps/gratia-ui/src/components/$ARGUMENTS/ - •Component name: last segment (PascalCase)
- •Component path:
- •
Read an existing component for reference. Good examples:
- •
apps/gratia-ui/src/components/features/product/ProductCard/ - •
apps/gratia-ui/src/components/common/
- •
- •
Create the component files:
index.tsx — Client Component (needs hooks/events)
tsx
"use client";
import styles from "./<ComponentName>.module.scss";
interface <ComponentName>Props {
// props
}
export default function <ComponentName>({}: <ComponentName>Props) {
return (
<div className={styles.container}>
{/* content */}
</div>
);
}
index.tsx — Server Component (data display only)
tsx
import styles from "./<ComponentName>.module.scss";
interface <ComponentName>Props {
// props
}
export default function <ComponentName>({}: <ComponentName>Props) {
return (
<div className={styles.container}>
{/* content */}
</div>
);
}
<ComponentName>.module.scss
scss
.container {
// styles
}
<ComponentName>.test.tsx (create if asked)
tsx
import { render, screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
import <ComponentName> from "./index";
describe("<ComponentName>", () => {
it("should render correctly", () => {
render(<<ComponentName> />);
// expect(screen.getByText("text")).toBeInTheDocument();
});
});
Conventions
- •Default export for all components
- •SCSS Modules only — never inline styles or Tailwind
- •Import shared components from
@gratia/ui/components/<Name> - •Use
classnamesfor conditional classes:import cx from "classnames"; - •Add
"use client"only if the component uses hooks, event handlers, or browser APIs - •Props interface in the same file unless shared across components
- •Prefer semantic HTML elements (
<section>,<article>,<nav>,<button>)