|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +Diamond UI is a lightweight design system built with Lit web components, design tokens, and CSS. Components use minimal JavaScript and follow the "CSS web components" methodology (see [https://etch.co/blog/css-web-components](https://etch.co/blog/css-web-components)). The library is framework-agnostic and can be installed in any web project. |
| 8 | + |
| 9 | +**Component naming convention**: All components are prefixed with `dmd-` (abbreviated from "diamond"). For example: `dmd-grid`, `dmd-card`, `dmd-button`. |
| 10 | + |
| 11 | +## Development Commands |
| 12 | + |
| 13 | +### Running the project |
| 14 | +```bash |
| 15 | +npm start # Start Vite dev server |
| 16 | +npm run storybook # Start Storybook on port 6006 |
| 17 | +``` |
| 18 | + |
| 19 | +### Building |
| 20 | +```bash |
| 21 | +npm run build # Build components and styles with Rollup |
| 22 | +npm run build-storybook # Build Storybook static site |
| 23 | +``` |
| 24 | + |
| 25 | +### Code quality |
| 26 | +```bash |
| 27 | +npm run lint:css # Lint CSS files with Stylelint |
| 28 | +npm run lint:js # Lint JS with eslint |
| 29 | +``` |
| 30 | + |
| 31 | +Note: There are no test scripts configured yet (`npm test` will fail). |
| 32 | + |
| 33 | +## Architecture |
| 34 | + |
| 35 | +### Component Categories |
| 36 | + |
| 37 | +Components are organized into four categories under `components/`: |
| 38 | + |
| 39 | +1. **canvas/** - Layout containers (e.g., `Card`, `Section`) |
| 40 | +2. **composition/** - Layout and structural components (e.g., `Grid`, `FormGroup`, `Dialog`, `Hidden`) |
| 41 | +3. **content/** - Content display components (e.g., `Icon`, `Text`, `List`, `LoadingButton`) |
| 42 | +4. **control/** - Interactive form components (e.g., `Button`, `Input`, `RadioCheckbox`, `Link`) |
| 43 | + |
| 44 | +### Component Types |
| 45 | + |
| 46 | +Diamond UI uses two component approaches: |
| 47 | + |
| 48 | +1. **Lit Components** - JavaScript web components built with Lit |
| 49 | + - Located in `.ts` files |
| 50 | + - Use `@customElement` decorator |
| 51 | + - Extend `LitElement` |
| 52 | + - Example: `Icon`, `LoadingButton` |
| 53 | + |
| 54 | +2. **CSS Web Components** - Pure CSS components with only TypeScript interfaces |
| 55 | + - Have a `.ts` file that ONLY exports TypeScript types/interfaces (no implementation) |
| 56 | + - All styling and behaviour in corresponding `.css` file |
| 57 | + - Example: `Card`, `Button`, `Grid` |
| 58 | + |
| 59 | +### Component Structure Pattern |
| 60 | + |
| 61 | +Each component follows this structure: |
| 62 | + |
| 63 | +```text |
| 64 | +components/[category]/[ComponentName]/ |
| 65 | +├── ComponentName.ts # Lit component OR type definitions only |
| 66 | +├── ComponentName.css # Component styles (always present) |
| 67 | +└── ComponentName.stories.ts # Storybook stories |
| 68 | +``` |
| 69 | + |
| 70 | +**Key files:** |
| 71 | +- `ComponentName.ts` exports an interface `[ComponentName]Attributes` defining the component's props |
| 72 | +- All components declare global types for both vanilla HTML and React JSX usage |
| 73 | +- React type declarations use `JSXCustomElement<T>` helper type from `types/jsx-custom-element.ts` |
| 74 | + |
| 75 | +Example interface pattern: |
| 76 | +```typescript |
| 77 | +export interface CardAttributes { |
| 78 | + border?: string | boolean; |
| 79 | + padding?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'none'; |
| 80 | +} |
| 81 | + |
| 82 | +declare global { |
| 83 | + interface HTMLElementTagNameMap { |
| 84 | + 'dmd-card': CardAttributes; |
| 85 | + } |
| 86 | +} |
| 87 | + |
| 88 | +declare module 'react' { |
| 89 | + namespace JSX { |
| 90 | + interface IntrinsicElements { |
| 91 | + 'dmd-card': JSXCustomElement<CardAttributes>; |
| 92 | + } |
| 93 | + } |
| 94 | +} |
| 95 | +``` |
| 96 | + |
| 97 | +### Design Tokens |
| 98 | + |
| 99 | +All design tokens are defined as CSS custom properties in `styles/tokens/`: |
| 100 | +- `border.css` - Border styles |
| 101 | +- `button.css` - Button-specific tokens |
| 102 | +- `color.css` - Color palette |
| 103 | +- `font.css` - Typography |
| 104 | +- `icon.css` - Icon sizing |
| 105 | +- `input.css` - Form input styles |
| 106 | +- `radius.css` - Border radius values |
| 107 | +- `shadow.css` - Box shadows |
| 108 | +- `spacing.css` - Spacing scale |
| 109 | +- `theme.css` - Theme variables |
| 110 | +- `transition.css` - Animation timings |
| 111 | +- `wrap.css` - Container widths |
| 112 | + |
| 113 | +Tokens can be overridden by defining CSS custom properties on `:root`. |
| 114 | + |
| 115 | +### Build Tool |
| 116 | + |
| 117 | +Rollup is configured to output three bundles: |
| 118 | +1. **JavaScript components** - All `.ts` files from `components/` (excluding `.stories.ts`) |
| 119 | +2. **Type definitions** - Generated `.d.ts` files |
| 120 | +3. **Styles** - `diamond-ui.css` bundle that includes all component styles via PostCSS glob imports |
| 121 | + |
| 122 | +The build: |
| 123 | +- Uses `@rollup/plugin-typescript` for TypeScript compilation |
| 124 | +- Uses `rollup-plugin-postcss` with `postcss-import-ext-glob` to bundle CSS |
| 125 | +- Maintains directory structure in `dist/` |
| 126 | +- Copies individual token files to `dist/styles/` for granular imports |
| 127 | + |
| 128 | +### Shared Utilities |
| 129 | + |
| 130 | +Reusable code in `lib/`: |
| 131 | +- `pulse.ts` - Lit CSS for loading/skeleton animations |
| 132 | +- `breakpoints.ts` - Responsive breakpoint definitions |
| 133 | +- `css-map.ts` - Utility for mapping props to CSS classes |
| 134 | + |
| 135 | +### Interactive Elements Pattern |
| 136 | + |
| 137 | +When custom elements need to be interactive (clickable/tappable), wrap them in semantic HTML elements (`<a>`, `<button>`, or `<label>`). |
| 138 | + |
| 139 | +The base CSS (`styles/base/interactive.css`) hides the styling of these wrappers when they contain: |
| 140 | +- `dmd-card` components |
| 141 | +- Elements with `data-interactive` attribute |
| 142 | + |
| 143 | +This preserves accessibility while allowing visual customization. |
| 144 | + |
| 145 | +### Theming |
| 146 | + |
| 147 | +Diamond supports custom theming via CSS custom properties. No production themes are included by default. Theme styles are defined in `styles/themes.css`. |
| 148 | + |
| 149 | +Theme variables follow the pattern `--dmd-theme-[property]` and can be scoped to specific components or containers. |
0 commit comments