From ede80dc2adc97d77dd2f4a4cb60c899deeca878f Mon Sep 17 00:00:00 2001 From: "blink-so[bot]" <211532188+blink-so[bot]@users.noreply.github.com> Date: Tue, 1 Jul 2025 19:16:14 +0000 Subject: [PATCH 1/3] docs: update frontend contributing guide for shadcn/ui and TailwindCSS migration Update the frontend contributing guide to reflect the current architecture and ongoing migration from MUI to shadcn/ui and from Emotion to TailwindCSS. Key changes: - Updated tech stack to include TailwindCSS, shadcn/ui, Lucide React, and Biome - Added migration status section with current progress (~210 MUI files, ~41 migrated) - Added development commands section with pnpm commands and pre-PR checklist - Rewrote UI components section to prioritize shadcn/ui over MUI - Completely updated styling section to focus on TailwindCSS - Enhanced accessibility section with TailwindCSS examples - Added comprehensive migration guide with practical examples and checklists - Documented semantic color system and best practices Co-authored-by: BrunoQuaresma <3165839+BrunoQuaresma@users.noreply.github.com> --- docs/about/contributing/frontend.md | 364 +++++++++++++++++++++++++--- 1 file changed, 334 insertions(+), 30 deletions(-) diff --git a/docs/about/contributing/frontend.md b/docs/about/contributing/frontend.md index ceddc5c2ff819..a70c06c2d4ce7 100644 --- a/docs/about/contributing/frontend.md +++ b/docs/about/contributing/frontend.md @@ -26,6 +26,40 @@ In both cases, you can access the dashboard on `http://localhost:8080`. If using > [!NOTE] > **Default Credentials:** `admin@coder.com` and `SomeSecurePassword!`. +## Development Commands + +All commands should be run from the `site/` directory: + +```bash +# Development +pnpm dev # Start Vite development server +pnpm storybook --no-open # Run Storybook for component development + +# Testing +pnpm test # Run Jest unit tests +pnpm test -- path/to/file # Run specific test file +pnpm playwright:test # Run Playwright E2E tests (requires license) + +# Code Quality +pnpm lint # Run complete linting suite (Biome + TypeScript + circular deps + knip) +pnpm lint:fix # Auto-fix linting issues where possible +pnpm format # Format code with Biome (always run before PR) +pnpm check # Type-check with TypeScript + +# Build +pnpm build # Production build +``` + +### Pre-PR Checklist + +Before creating a pull request, ensure you run: + +1. `pnpm check` - Ensure no TypeScript errors +2. `pnpm lint` - Fix linting issues +3. `pnpm format` - Format code consistently +4. `pnpm test` - Run affected unit tests +5. Visual check in Storybook if component changes + ## Tech Stack Overview All our dependencies are described in `site/package.json`, but the following are @@ -34,7 +68,9 @@ the most important. - [React](https://reactjs.org/) for the UI framework - [Typescript](https://www.typescriptlang.org/) to keep our sanity - [Vite](https://vitejs.dev/) to build the project -- [Material V5](https://mui.com/material-ui/getting-started/) for UI components +- [TailwindCSS](https://tailwindcss.com/) for styling (migrating from Emotion) +- [shadcn/ui](https://ui.shadcn.com/) + [Radix UI](https://www.radix-ui.com/) for UI components (migrating from Material UI) +- [Lucide React](https://lucide.dev/) for icons - [react-router](https://reactrouter.com/en/main) for routing - [TanStack Query v4](https://tanstack.com/query/v4/docs/react/overview) for fetching data @@ -43,8 +79,42 @@ the most important. - [Jest](https://jestjs.io/) for integration testing - [Storybook](https://storybook.js.org/) and [Chromatic](https://www.chromatic.com/) for visual testing +- [Biome](https://biomejs.dev/) for linting and formatting - [PNPM](https://pnpm.io/) as the package manager +## Migration Status + +**⚠️ Important: We are currently migrating from Material UI (MUI) to shadcn/ui and from Emotion to TailwindCSS.** + +### Current State +- **~210 files** still use MUI components (`@mui/material`) +- **~41 components** have been migrated to use TailwindCSS classes +- **shadcn/ui components** are being added incrementally to `src/components/` +- **Emotion CSS** is deprecated but still present in legacy components + +### Migration Guidelines + +When working on existing components: +1. **Prefer shadcn/ui components** over MUI when available +2. **Use TailwindCSS classes** instead of Emotion `css` prop or `sx` prop +3. **Check `src/components/`** for existing shadcn/ui implementations before creating new ones +4. **Do not use the shadcn CLI** - manually add components to maintain consistency +5. **Update tests** to reflect new component structure when migrating + +For new components: +1. **Always use TailwindCSS** for styling +2. **Use shadcn/ui components** as the foundation +3. **Use Lucide React icons** instead of MUI icons +4. **Follow the semantic color tokens** defined in `tailwind.config.js` + +### Semantic Color System + +Use the custom semantic color tokens defined in our Tailwind configuration: +- **Content colors**: `content-primary`, `content-secondary`, `content-disabled`, `content-invert`, `content-success`, `content-link`, `content-destructive`, `content-warning` +- **Surface colors**: `surface-primary`, `surface-secondary`, `surface-tertiary`, `surface-quaternary`, `surface-invert-primary`, `surface-invert-secondary`, `surface-destructive`, `surface-green`, `surface-grey`, `surface-orange`, `surface-sky`, `surface-red`, `surface-purple` +- **Border colors**: `border-default`, `border-warning`, `border-destructive`, `border-success`, `border-hover` +- **Highlight colors**: `highlight-purple`, `highlight-green`, `highlight-grey`, `highlight-sky`, `highlight-red` + ## Structure All UI-related code is in the `site` folder. Key directories include: @@ -182,13 +252,36 @@ Components should be atomic, reusable and free of business logic. Modules are similar to components except that they can be more complex and can contain business logic specific to the product. -### MUI +### UI Components + +**⚠️ MUI is deprecated** - we are migrating to shadcn/ui + Radix UI. + +#### shadcn/ui Components (Preferred) + +We use [shadcn/ui](https://ui.shadcn.com/) components built on top of [Radix UI](https://www.radix-ui.com/) primitives. These components are: +- **Accessible by default** with ARIA attributes and keyboard navigation +- **Customizable** with TailwindCSS classes +- **Consistent** with our design system +- **Type-safe** with full TypeScript support + +Existing shadcn/ui components can be found in `src/components/`. Examples include: +- `Checkbox` - Form checkbox input +- `ScrollArea` - Custom scrollable area +- `Table` - Data table with sorting and filtering +- `Slider` - Range input slider +- `Switch` - Toggle switch +- `Command` - Command palette/search +- `Collapsible` - Expandable content sections -The codebase is currently using MUI v5. Please see the -[official documentation](https://mui.com/material-ui/getting-started/). In -general, favor building a custom component via MUI instead of plain React/HTML, -as MUI's suite of components is thoroughly battle-tested and accessible right -out of the box. +#### MUI Components (Legacy) + +The codebase still contains MUI v5 components that are being phased out. When encountering MUI components: +1. **Check if a shadcn/ui equivalent exists** in `src/components/` +2. **Migrate to the shadcn/ui version** when making changes +3. **Create a new shadcn/ui component** if no equivalent exists +4. **Do not add new MUI components** to the codebase + +For reference, the [MUI documentation](https://mui.com/material-ui/getting-started/) can still be consulted for understanding existing legacy components. ### Structure @@ -199,35 +292,65 @@ remain easy to navigate, healthy and maintainable for all contributors. ### Accessibility -We strive to keep our UI accessible. +We strive to keep our UI accessible. **shadcn/ui components are accessible by default** with proper ARIA attributes, keyboard navigation, and focus management. + +#### Color Contrast + +Colors should come from our semantic color tokens in the Tailwind theme. These tokens are designed to meet WCAG level AA compliance (4.5:1 contrast ratio). If you need to add a custom color, ensure proper contrast using: +- [WebAIM Contrast Checker](https://webaim.org/resources/contrastchecker/) +- [Dequeue's axe DevTools](https://chrome.google.com/webstore/detail/axe-devtools-web-accessib/lhdoppojpmngadmnindnejefpokejbdd) + +#### Form Labels + +Always associate labels with input elements. Labels can be visually hidden but must be present in the markup for screen readers. + +```tsx +// ✅ Good: Visible label + + + +// ✅ Good: Visually hidden label + + +``` + +#### Images and Icons -In general, colors should come from the app theme, but if there is a need to add -a custom color, please ensure that the foreground and background have a minimum -contrast ratio of 4.5:1 to meet WCAG level AA compliance. WebAIM has -[a great tool for checking your colors directly](https://webaim.org/resources/contrastchecker/), -but tools like -[Dequeue's axe DevTools](https://chrome.google.com/webstore/detail/axe-devtools-web-accessib/lhdoppojpmngadmnindnejefpokejbdd) -can also do automated checks in certain situations. +Provide descriptive text for images and icons: -When using any kind of input element, always make sure that there is a label -associated with that element (the label can be made invisible for aesthetic -reasons, but it should always be in the HTML markup). Labels are important for -screen-readers; a placeholder text value is not enough for all users. +```tsx +// ✅ Good: Alt text for images +Revenue increased 25% this quarter + +// ✅ Good: Screen reader text for icons + + +// ✅ Good: Using Lucide React icons with proper labeling +import { Settings } from "lucide-react"; + +``` + +#### Legacy MUI Accessibility -When possible, make sure that all image/graphic elements have accompanying text -that describes the image. `` elements should have an `alt` text value. In -other situations, it might make sense to place invisible, descriptive text -inside the component itself using MUI's `visuallyHidden` utility function. +For legacy MUI components, you may still see the `visuallyHidden` utility: ```tsx +// ❌ Legacy: MUI visuallyHidden import { visuallyHidden } from "@mui/utils"; +Settings -; +// ✅ Migrated: Tailwind sr-only class +Settings ``` ### Should I create a new component or module? @@ -250,7 +373,54 @@ new conventions, but all new components should follow these guidelines. ## Styling -We use [Emotion](https://emotion.sh/) to handle CSS styles. +**⚠️ Emotion is deprecated** - we are migrating to TailwindCSS. + +### TailwindCSS (Preferred) + +We use [TailwindCSS](https://tailwindcss.com/) for all new styling. Key points: + +- **Use semantic color tokens** from our custom theme (see Migration Status section above) +- **Responsive design** with Tailwind's responsive prefixes (`sm:`, `md:`, `lg:`, `xl:`) +- **No dark mode prefix** - our theme handles light/dark mode automatically +- **Custom utilities** are defined in `tailwind.config.js` +- **Conditional styling** using `clsx` utility for dynamic classes + +#### TailwindCSS Best Practices + +```tsx +// ✅ Good: Use semantic color tokens +
+ +// ✅ Good: Group related classes +
+ +// ✅ Good: Responsive design +
+ +// ✅ Good: Conditional styling with clsx +import { clsx } from "clsx"; + + +// ✅ After: shadcn/ui Button (if available) or custom button +import { Button } from "components/Button"; + + +``` + +#### Form Field Migration + +```tsx +// ❌ Before: MUI TextField +import { TextField } from "@mui/material"; + + + +// ✅ After: shadcn/ui Input with Label +import { Input } from "components/Input"; +import { Label } from "components/Label"; + +
+ + + {errors.email && ( +

+ {errors.email} +

+ )} +
+``` + +#### Icon Migration + +```tsx +// ❌ Before: MUI Icons +import { Settings as SettingsIcon } from "@mui/icons-material"; + + + +// ✅ After: Lucide React Icons +import { Settings } from "lucide-react"; + + +``` + +### Migration Checklist + +When migrating a component, ensure you: + +- [ ] Replace MUI imports with shadcn/ui equivalents +- [ ] Convert `sx` props and Emotion `css` to TailwindCSS classes +- [ ] Use semantic color tokens from the theme +- [ ] Update icon imports to use Lucide React +- [ ] Maintain or improve accessibility +- [ ] Update component tests +- [ ] Update Storybook stories if they exist +- [ ] Verify responsive behavior +- [ ] Test keyboard navigation +- [ ] Check color contrast compliance + +### Getting Help + +If you encounter challenges during migration: + +1. **Check existing implementations** in `src/components/` for patterns +2. **Refer to shadcn/ui documentation** at [ui.shadcn.com](https://ui.shadcn.com/) +3. **Ask in Discord** - the team is happy to help with migration questions +4. **Look at recent PRs** for migration examples + +### Creating New shadcn/ui Components + +When a shadcn/ui equivalent doesn't exist: + +1. **Check the shadcn/ui registry** for the component +2. **Copy the component code** (don't use the CLI) +3. **Adapt to our theme** using semantic color tokens +4. **Add to `src/components/`** with proper folder structure +5. **Create Storybook stories** for documentation +6. **Add TypeScript types** for props +7. **Include accessibility features** (ARIA attributes, keyboard support) + +Example component structure: +``` +src/components/NewComponent/ +├── NewComponent.tsx +├── NewComponent.stories.tsx +├── NewComponent.test.tsx +└── index.ts +``` From 1dc4f8548644327c69824cb5e54be85ffc1a7bee Mon Sep 17 00:00:00 2001 From: "blink-so[bot]" <211532188+blink-so[bot]@users.noreply.github.com> Date: Tue, 1 Jul 2025 19:24:30 +0000 Subject: [PATCH 2/3] chore: run formatting and linting checks Ran make fmt and frontend linting to ensure code quality: - Go formatting: passed - Terraform formatting: passed - Frontend formatting (Biome): passed (1124 files, no fixes needed) - Frontend linting (Biome): passed (1124 files, no issues) No changes were required as the code already meets all formatting standards. Co-authored-by: BrunoQuaresma <3165839+BrunoQuaresma@users.noreply.github.com> From 2de73301196652c4080d303f09e4faa86f2ce7d2 Mon Sep 17 00:00:00 2001 From: "blink-so[bot]" <211532188+blink-so[bot]@users.noreply.github.com> Date: Tue, 1 Jul 2025 19:28:49 +0000 Subject: [PATCH 3/3] fix: resolve markdown linting issues in frontend contributing guide Fixed 11 markdown linting errors found by markdownlint-cli2: - MD022: Added blank lines around headings - MD032: Added blank lines around lists (9 instances) - MD031: Added blank lines around fenced code blocks - MD040: Added language specification to fenced code block All markdown linting rules now pass with 0 errors. Co-authored-by: BrunoQuaresma <3165839+BrunoQuaresma@users.noreply.github.com> --- docs/about/contributing/frontend.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/about/contributing/frontend.md b/docs/about/contributing/frontend.md index a70c06c2d4ce7..0cc7c4e405fed 100644 --- a/docs/about/contributing/frontend.md +++ b/docs/about/contributing/frontend.md @@ -87,6 +87,7 @@ the most important. **⚠️ Important: We are currently migrating from Material UI (MUI) to shadcn/ui and from Emotion to TailwindCSS.** ### Current State + - **~210 files** still use MUI components (`@mui/material`) - **~41 components** have been migrated to use TailwindCSS classes - **shadcn/ui components** are being added incrementally to `src/components/` @@ -95,6 +96,7 @@ the most important. ### Migration Guidelines When working on existing components: + 1. **Prefer shadcn/ui components** over MUI when available 2. **Use TailwindCSS classes** instead of Emotion `css` prop or `sx` prop 3. **Check `src/components/`** for existing shadcn/ui implementations before creating new ones @@ -102,6 +104,7 @@ When working on existing components: 5. **Update tests** to reflect new component structure when migrating For new components: + 1. **Always use TailwindCSS** for styling 2. **Use shadcn/ui components** as the foundation 3. **Use Lucide React icons** instead of MUI icons @@ -110,6 +113,7 @@ For new components: ### Semantic Color System Use the custom semantic color tokens defined in our Tailwind configuration: + - **Content colors**: `content-primary`, `content-secondary`, `content-disabled`, `content-invert`, `content-success`, `content-link`, `content-destructive`, `content-warning` - **Surface colors**: `surface-primary`, `surface-secondary`, `surface-tertiary`, `surface-quaternary`, `surface-invert-primary`, `surface-invert-secondary`, `surface-destructive`, `surface-green`, `surface-grey`, `surface-orange`, `surface-sky`, `surface-red`, `surface-purple` - **Border colors**: `border-default`, `border-warning`, `border-destructive`, `border-success`, `border-hover` @@ -259,12 +263,14 @@ business logic specific to the product. #### shadcn/ui Components (Preferred) We use [shadcn/ui](https://ui.shadcn.com/) components built on top of [Radix UI](https://www.radix-ui.com/) primitives. These components are: + - **Accessible by default** with ARIA attributes and keyboard navigation - **Customizable** with TailwindCSS classes - **Consistent** with our design system - **Type-safe** with full TypeScript support Existing shadcn/ui components can be found in `src/components/`. Examples include: + - `Checkbox` - Form checkbox input - `ScrollArea` - Custom scrollable area - `Table` - Data table with sorting and filtering @@ -276,6 +282,7 @@ Existing shadcn/ui components can be found in `src/components/`. Examples includ #### MUI Components (Legacy) The codebase still contains MUI v5 components that are being phased out. When encountering MUI components: + 1. **Check if a shadcn/ui equivalent exists** in `src/components/` 2. **Migrate to the shadcn/ui version** when making changes 3. **Create a new shadcn/ui component** if no equivalent exists @@ -297,6 +304,7 @@ We strive to keep our UI accessible. **shadcn/ui components are accessible by de #### Color Contrast Colors should come from our semantic color tokens in the Tailwind theme. These tokens are designed to meet WCAG level AA compliance (4.5:1 contrast ratio). If you need to add a custom color, ensure proper contrast using: + - [WebAIM Contrast Checker](https://webaim.org/resources/contrastchecker/) - [Dequeue's axe DevTools](https://chrome.google.com/webstore/detail/axe-devtools-web-accessib/lhdoppojpmngadmnindnejefpokejbdd) @@ -663,7 +671,8 @@ When a shadcn/ui equivalent doesn't exist: 7. **Include accessibility features** (ARIA attributes, keyboard support) Example component structure: -``` + +```text src/components/NewComponent/ ├── NewComponent.tsx ├── NewComponent.stories.tsx