diff --git a/.github/instructions/copilot.instructions.md b/.github/instructions/copilot.instructions.md index 8d55b58c90fbca..5515a83789d1db 100644 --- a/.github/instructions/copilot.instructions.md +++ b/.github/instructions/copilot.instructions.md @@ -4,470 +4,68 @@ applyTo: '**' # Fluent UI Copilot Instructions -You are working in the Microsoft Fluent UI monorepo, a comprehensive design system and UI component library for web applications. This repository contains multiple versions and implementations of Fluent UI components serving millions of users across Microsoft's products. - -## Repository Overview - -This is a large Nx monorepo with the following key characteristics: - -- **Package Manager**: Yarn v1 with strict dependency management -- **Build System**: Nx workspace with custom plugins (`tools/workspace-plugin/`) -- **Node.js Versions**: ^22.0.0 -- **Languages**: TypeScript (strict mode), React, Web Components -- **Testing**: Jest, Cypress (E2E), Storybook + StoryWright (Visual Regression), SSR testing (test-ssr) -- **Documentation**: Storybook sites, api.md files via API Extractor -- **Release**: Beachball for version management and change files - -## Project Structure - -1. **Fluent UI v9** (`@fluentui/react-components`) - **PRIORITIZE FOR NEW WORK** - - - Location: `packages/react-components/` - - Nx Project Tags: `vNext` - - Features: Current stable version, actively developed. Tree-shakeable, atomic CSS classes - -2. **Fluent UI v8** (`@fluentui/react`) - **MAINTENANCE ONLY** - - - Location: `packages/react/` - - Nx Project Tags: `v8` - - Status: Maintenance mode - - Features: Runtime styling, mature and stable - -3. **Fluent UI Charting** - - - Location: `packages/charts/` - - Nx Project Tags: `v8`, `vNext`,`charting` - - Features: Charting components compatible with both v8 and v9 - -4. **Web Components** (`@fluentui/web-components`) - Framework-agnostic - - Location: `packages/web-components/` - - Nx Project Tags: `web-components` - - Used by: Microsoft Edge - - Features: Platform-agnostic web standards - -More information about the projects and their status can be found through NX tags. - -## Development Guidelines - -### Essential Nx Workspace Commands - -This workspace uses **Nx** with custom workspace plugins. Key commands: - -```bash -# Initial setup -yarn # Install dependencies and link packages -yarn clean # Clean all build artifacts - -# Development workflows -yarn start # Interactive prompt to choose project to run -yarn nx run :build # Build specific project with dependencies -yarn nx run-many -t build # Build multiple projects -yarn nx run :test # Run tests for specific project -yarn nx run :test -u # Update Jest snapshots -yarn nx run :start # Start Storybook for component - -# Component generation (v9 only) -yarn create-component # Interactive component generator - -# Release management -yarn change # Create beachball change file (required for PRs) - -# Show project targets -yarn nx show projects # List all projects -``` - -### Component Development Workflow - -**For v9 components** (preferred): - -1. Navigate to `packages/react-components/` -2. Use generator: `yarn create-component` or direct Nx command -3. Follow hook-based architecture pattern exactly -4. Add comprehensive tests and Storybook stories -5. Run `yarn nx run :generate-api` to update API docs -6. Create change file with `yarn change` before PR - -**For v8 components** (maintenance only): - -- Work in `packages/react/` with extreme caution -- No new features, only critical bug fixes - -### Testing Architecture - -**Multi-layered testing strategy** ensures quality at scale: - -```bash -# Unit Tests - Jest + React Testing Library + SWC transforms -yarn nx run react-button:test -yarn nx run react-button:test -u # Update snapshots - -# Visual Regression - Storybook + StoryWright -yarn nx run vr-tests-react-components:test-vr # Creates Diff images only. no actual assertions are run - this is used only from CI - -# E2E Integration Tests - Cypress -yarn nx run react-components:e2e - -# SSR Compatibility Tests -yarn nx run ssr-tests-v9:test-ssr - -# Cross-version React compatibility -yarn nx run rit-tests-v9:test-rit - -# Cross-version React testing for react-text project -yarn nx run react-text:test-rit - -``` - -### Code Quality and Standards - -- **Linting**: ESLint with custom `@fluentui/eslint-plugin` rules -- **Formatting**: Prettier (automatic via lint-staged) -- **Type checking**: TypeScript strict mode required -- **Testing**: Jest for unit tests, minimum 80% coverage expected -- **Bundle analysis**: Automated bundle size tracking via build pipeline - -## Important Patterns and Conventions - -### File Organization Patterns - -**CRITICAL**: Every v9 component follows this exact architectural pattern: - -``` -# v9 Component Structure (EXACT pattern required) -packages/react-components/react-component-name/ -├── library/src/ # Implementation source -│ ├── index.ts # Re-exports everything -│ ├── ComponentName.tsx # Main component export -│ ├── components/ComponentName/ # Core implementation -│ │ ├── ComponentName.test.tsx # Unit tests (adjacent) -│ │ ├── ComponentName.tsx # ForwardRefComponent -│ │ ├── ComponentName.types.ts # Props, State, Slots -│ │ ├── index.ts # Local exports -│ │ ├── renderComponentName.tsx # JSX rendering -│ │ ├── useComponentName.ts # State management -│ │ └── useComponentNameStyles.styles.ts # Griffel styling -│ ├── testing/ # Test utilities -│ └── utils # Reusable utils (if needed) -└── stories/src/ # Storybook documentation - ├── ComponentName.stories.tsx # Component stories - └── ComponentNameDefault.stories.tsx # Default story -``` - -### Component Structure Pattern - -``` -react-component-name/ -├── library/src/ -│ ├── index.ts # Main package exports -│ ├── ComponentName.ts # Main export (calls hooks + render) -│ ├── components/ComponentName/ # Hook-based architecture -│ │ ├── ComponentName.tsx # Main component export -│ │ ├── ComponentName.types.ts # Props, State, Slots types -│ │ ├── useComponentName.ts # State management hook -│ │ ├── useComponentNameStyles.styles.ts # Griffel styling -│ │ └── renderComponentName.tsx # JSX rendering logic -│ └── index.ts # Package exports -└── stories/ # Storybook stories -``` - -### Hook-Based Architecture - -Components use three core hooks: - -1. **`useComponent_unstable()`** - Processes props, slots and main component logic into normalized state -2. **`useComponentStyles_unstable()`** - Creates Griffel CSS-in-JS styling -3. **`renderComponent_unstable()`** - Pure JSX rendering from state - -### Slot System - -**Critical Pattern**: All v9 components use slots for extensibility and consistent rendering: - -```tsx -// Define slots in types -type ButtonSlots = { - root: Slot<'button'>; - icon?: Slot<'span'>; -}; - -// Create slots in hook using slot.always() or slot.optional() -const state: ButtonState = { - root: slot.always(props.root, { elementType: 'button' }), - icon: slot.optional(props.icon, { elementType: 'span' }), -}; - -// Render slots with assertSlots for type safety -export const renderButton_unstable = (state: ButtonState) => { - assertSlots(state); - return ( - - {state.icon && } - {state.root.children} - - ); -}; -``` - -### Build-Time CSS-in-JS with Atomic Classes - -**Critical**: v9 uses Griffel for compile-time CSS generation - styles are extracted into atomic CSS classes at build time, not runtime: - -```tsx -// useButtonStyles.styles.ts -import { makeStyles } from '@griffel/react'; -import { tokens } from '@fluentui/react-theme'; - -export const useButtonStyles = makeStyles({ - root: { - // Use design tokens, not hardcoded values - color: tokens.colorNeutralForeground1, - backgroundColor: tokens.colorNeutralBackground1, - padding: `${tokens.spacingVerticalS} ${tokens.spacingHorizontalM}`, - - // Pseudo-selectors and media queries supported - ':hover': { - backgroundColor: tokens.colorNeutralBackground1Hover, - }, - - ':focus-visible': { - outline: `${tokens.strokeWidthThick} solid ${tokens.colorStrokeFocus2}`, - }, - }, - - // Size variations - small: { padding: tokens.spacingVerticalXS }, - large: { padding: tokens.spacingVerticalL }, -}); - -// Apply in component hook -export const useButton_unstable = (props, ref) => { - const classes = useButtonStyles(); - const state = { - /* ... */ - }; - - state.root.className = mergeClasses( - classes.root, - props.size === 'small' && classes.small, - props.size === 'large' && classes.large, - state.root.className, // Always preserve user className - ); - - return state; -}; -``` - -### Design Tokens System - -**Always use design tokens** from `@fluentui/tokens` instead of hardcoded values: - -```tsx -// ✅ CORRECT - uses semantic design tokens -color: tokens.colorBrandForeground1; -padding: tokens.spacingVerticalM; -borderRadius: tokens.borderRadiusMedium; - -// ❌ AVOID - hardcoded values break theming -color: '#0078d4'; -padding: '8px'; -borderRadius: '4px'; -``` - -### Theme Architecture - -Themes define CSS custom properties consumed by components: - -```tsx -// FluentProvider injects CSS variables into DOM - - -; - -// Components reference tokens which resolve to CSS variables -makeStyles({ - root: { - color: tokens.colorNeutralForeground1, // becomes 'var(--colorNeutralForeground1)' - }, -}); -``` - -### TypeScript Patterns (v9) - -**Strict typing with consistent interfaces:** - -```tsx -// Component.types.ts - REQUIRED pattern -export type ComponentProps = ComponentPropsWithRef<'div'> & { - appearance?: 'primary' | 'secondary'; - size?: 'small' | 'medium' | 'large'; -}; - -export type ComponentState = Required> & { - components: ComponentSlots; - root: SlotProps<'div'>; -}; - -export type ComponentSlots = { - root: Slot<'div'>; - icon?: Slot<'span'>; -}; - -// Main component must use ForwardRefComponent -export const Component: ForwardRefComponent = React.forwardRef((props, ref) => { - // Hook pattern implementation -}); -``` - -### Testing Requirements - -**Comprehensive testing is mandatory** for all component changes: - -### Accessibility Standards - -**WCAG 2.1 compliance required** for all interactive components: - -- Provide proper ARIA labels and roles -- Support keyboard navigation patterns -- Test with screen readers (NVDA, JAWS, VoiceOver) -- High contrast mode compatibility required - -## Documentation and Resources - -- **Main docs**: -- **v8 docs**: -- **Web Components docs**: -- **Design specs**: Located in `specs/` directory -- **Storybook**: Run locally with appropriate build commands - -### Code Style - -- Use TypeScript strict mode -- Follow existing patterns in similar components -- Comprehensive prop interfaces with JSDoc comments -- Consistent naming conventions (PascalCase for components, camelCase for props) -- Use React hooks and modern patterns for v9 components -- Focus on the slot system, Griffel styling, and hook-based architecture for v9 - -### Testing Requirements - -- Unit tests for all public APIs -- Accessibility tests for interactive components -- Visual regression tests via Storybook -- Cross-browser compatibility considerations - -## Migration and Compatibility - -- v8 and v9 components can coexist in the same application -- Gradual migration is supported and encouraged -- Pay attention to design token usage for consistent theming -- Consider bundle size impact when mixing versions - -When working in this repository, always prioritize accessibility, design system consistency, and maintainability. The codebase serves millions of users across Microsoft's products, so quality and reliability are paramount. - -## GitHub Issue and Pull Request Labeling - -### Issue Labels - -The repository uses automated labeling based on issue templates and PR file changes. Understanding the labeling system helps with proper issue categorization and triage. - -#### Core Label Categories - -**Type Labels** (required for all issues): - -- `Type: Bug :bug:` - Bug reports across all platforms -- `Type: Feature` - Feature requests and enhancements -- `Area: Documentation` - Documentation issues and improvements - -**Product/Platform Labels** (auto-assigned by issue templates): - -- `Fluent UI react-components (v9)` - v9 React components -- `Fluent UI react (v8)` - v8/legacy React components -- `web-components` - Web Components implementation -- `Fluent UI WC (v3)` - Web Components v3 specific -- `Package: charting` - React Charting components - -**Triage Labels**: - -- `Needs: Triage :mag:` - Automatically applied to new issues, requires team review -- `Area: Build System` - Build tooling and infrastructure - -#### Issue Template Mapping - -**For React Components v9 bugs**: - -```yaml -labels: ['Type: Bug :bug:', 'Needs: Triage :mag:', 'Fluent UI react-components (v9)'] -``` - -**For React v8 bugs**: - -```yaml -labels: ['Type: Bug :bug:', 'Needs: Triage :mag:', 'Fluent UI react (v8)'] -``` - -**For Web Components bugs**: - -```yaml -labels: ['Type: Bug :bug:', 'Needs: Triage :mag:', 'web-components', 'Fluent UI WC (v3)'] -``` - -**For Feature Requests**: - -```yaml -labels: ['Type: Feature', 'Needs: Triage :mag:'] -``` - -**For Documentation Issues**: - -```yaml -labels: ['Area: Documentation', 'Needs: Triage :mag:'] -``` - -### Pull Request Labels - -PRs receive automatic labels based on file changes via GitHub Actions using `.github/labeler.yml`: - -**Workflow Labels**: - -- `Type: RFC` - Changes to RFC documentation (`docs/react-v9/contributing/rfcs/**`) -- `CI` - Changes to CI/CD pipelines (`.github/**`, `.devops/**`, `azure-pipelines*.yml`) - -**Nx Workspace Labels**: - -- `NX: core` - Core Nx configuration changes (`tools/workspace-plugin/**`, `nx.json`, `**/project.json`) -- `NX: workspace generators` - Nx generator changes (`tools/workspace-plugin/src/generators/*`) -- `NX: workspace executors` - Nx executor changes (`tools/workspace-plugin/src/executors/*`) -- `NX: workspace eslint-rules` - ESLint rule changes (`tools/eslint-rules/*`) - -### Automated Triage System - -The repository uses a triage bot that automatically assigns labels and assignees based on issue content: - -**Trigger Keywords** (from `.github/triage-bot.config.json`): - -- `(@fluentui/react-northstar)` → `["Fluent UI react-northstar (v0)", "Needs: Triage :mag:"]` -- `(@fluentui/react)` → `["Fluent UI react (v8)", "Needs: Triage :mag:"]` -- `(@fluentui/react-components)` → `["Fluent UI react-components (v9)", "Needs: Triage :mag:"]` -- `(@fluentui/web-components)` → `["web-components"]` - -### Best Practices for Contributors - -**When Creating Issues**: - -1. Use appropriate issue template - labels are automatically applied -2. Select correct component/package from dropdown - helps with routing -3. Include package version and relevant details -4. Don't manually add labels - let automation handle initial triage - -**When Creating Pull Requests**: - -1. Labels are automatically applied based on changed files -2. Focus on clear PR titles and descriptions -3. Reference related issues with proper syntax (`Fixes #123`) -4. Create change files for breaking changes (`yarn change`) - -**For Maintainers**: - -1. Review `Needs: Triage :mag:` label for new items -2. Add component-specific labels after triage if needed -3. Use consistent labeling for similar issues to help automation learning -4. Update triage bot configuration when adding new packages/areas +## Repository overview + +- Large Nx monorepo using Yarn v1, Node.js 22, TypeScript strict mode, React, and web components. +- Prefer v9 work in `packages/react-components/`. +- Treat `packages/react/` as v8 maintenance-only code; do not copy its patterns into v9 work. +- Search by specific package or component name instead of reading broad top-level directories. + +## Validated setup and commands + +- Run `yarn install --frozen-lockfile` during initial setup and after dependency changes. This command is validated in this repo. +- Always run project tasks through Nx: + - `yarn nx run :build` + - `yarn nx run :test` + - `yarn nx run :type-check` + - `yarn nx run :lint` +- Useful discovery commands: + - `yarn nx show project ` + - `yarn nx show projects` +- Prefer targeted project validation over full-repo commands. +- For published package changes, create a change file with `yarn change`. +- For v9 public API changes, also run `yarn nx run :generate-api`. + +## V9 component rules + +- Package path convention: `@fluentui/react-` → `packages/react-components/react-/library/src/`. +- Use `ForwardRefComponent` with `React.forwardRef`; never use `React.FC`. +- Use the standard hook pipeline: + 1. `use_unstable()` + 2. `useStyles_unstable()` + 3. `render_unstable()` +- Use Griffel `makeStyles` and `mergeClasses`. +- Preserve the user `className` last in `mergeClasses(...)`. +- Never hardcode colors, spacing, typography, border radius, or shadows. Use the `tokens` export from `@fluentui/react-theme`. +- Never access `window`, `document`, or `navigator` directly. Use `useFluent_unstable().targetDocument` in components or `canUseDOM()` in utilities. +- Never add dependencies between component packages. Move shared logic to `react-utilities` or `react-shared-contexts`. + +## Expected file patterns + +- V9 component implementation lives under `library/src/components//`. +- Typical files: + - `.tsx` + - `.types.ts` + - `use.ts` + - `useStyles.styles.ts` + - `render.tsx` + - adjacent `.test.tsx` +- Stories live under `stories/src/`. + +## Testing guidance + +- Add or update focused tests next to the changed code. +- Common validation commands: + - `yarn nx run :test` + - `yarn nx run :test -u` + - `yarn nx run :type-check` + - `yarn nx run ssr-tests-v9:test-ssr` when SSR behavior changes + - `yarn nx run vr-tests-react-components:test-vr` for VRT-only changes +- Do not remove unrelated tests to make validation pass. + +## Guardrails + +- Prefer existing generators or scaffolding for new v9 packages/components. +- Follow the closest local README, spec, and test patterns instead of copying legacy v8 code. +- If you change `.github/workflows`, `package.json`, or `yarn.lock` as part of dependency or automation work, also read `.github/instructions/dependabot-security-fixes.instructions.md`. +- Keep changes surgical and avoid unrelated fixes.