Skip to main documentation content
Reading time · 2 min

Component

Where UI lives in the SHOPin storefront accelerator presentation app, how it ties to Feature folders, and how to document and test it.

Workspaces

Pick the location

  • Generic / reusable UIcomponents/ui/: buttons, inputs, dialogs, cards, and other design-system pieces used across features.
  • Layout / shellcomponents/layout/: header, footer, top bar, locale switcher, and other app shell pieces.
  • Feature-only — Under features/<name>/ (optional components/ inside the feature). Import from the feature root only from outside that feature—see Feature.

Check for an existing solution

Before adding a new generic primitive, consider shadcn/ui. If you port a pattern, align it with this repo’s tokens and APIs.

Tailwind and design tokens

  • Tokens live in apps/presentation/app/globals.css inside @theme { } (colors, typography, z-index, shadows, etc.). Prefer utilities that map to those tokens over unrelated hardcoded values.
  • Tailwind utilities are the default styling approach.

TypeScript

  • Props — Fully typed; avoid any; use unions where they clarify allowed values.
  • Variants — Use cva (class-variance-authority) and VariantProps when a component has multiple visual or behavioural variants.
  • "use client" — Prefer server-friendly components; add "use client" only when you need client-only APIs (hooks, browser APIs).

Storybook

For components under components/ui/, add a story under apps/storybook/src/stories/ui/<component>.stories.tsx (or a subfolder). Expose controls for the main props so the component can be exercised in isolation.

Tests

  • Shared UIapps/presentation/components/ui/__tests__/<component>.test.tsx, or __tests__/ next to the component when it lives in a subfolder (e.g. components/ui/carousel/__tests__/).
  • Feature UI — Colocate tests with the feature.

Imports and naming

  • Alias — Use @/ from the presentation app root (e.g. @/components/ui/button, @/features/cart/cart-content).
  • Files — kebab-case (product-card.tsx).
  • Exports — PascalCase named exports for React components.
  • Features — Outside a feature, import only from that feature’s public root; ESLint enforces this.

Related

Back to Building blocks · Back to How to work with SHOPin