From 2347d88d137255f558e4404216399b276549678f Mon Sep 17 00:00:00 2001 From: Torleif Halseth Date: Thu, 27 Nov 2025 10:14:50 +0100 Subject: [PATCH 1/7] chore: update documentation for project guidelines and standards --- .github/copilot-instructions.md | 61 +++------- .github/instructions/figma.instructions.md | 26 ++++- .../global-coding.instructions.md | 79 +++++++++++-- .github/instructions/react.instructions.md | 95 ++++++++++++---- .github/instructions/styling.instructions.md | 93 +++++++++++++-- .github/instructions/ts.instructions.md | 106 +++++++++++++----- 6 files changed, 339 insertions(+), 121 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 71c42bac58..17d0fc7410 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,53 +1,24 @@ # GitHub Copilot Instructions for Equinor Design System -## Project Overview +## Overview -This monorepo contains Equinor's Design System (EDS) - a component library and design tokens that implement Equinor's design language. The design system consists of multiple packages: +Equinor Design System (EDS) is a monorepo with component libraries and design tokens implementing Equinor's design language. -- `@equinor/eds-core-react`: Core React components -- `@equinor/eds-tokens`: Design tokens and variables -- `@equinor/eds-icons`: Icon library -- `@equinor/eds-lab-react`: Experimental components -- `@equinor/eds-data-grid-react`: Data grid component +## Packages -## Code Style & Patterns +- **`@equinor/eds-core-react`** - Main React component library (most development happens here) +- **`@equinor/eds-tokens`** - Design tokens, CSS variables, and theming +- **`@equinor/eds-icons`** - Icon library +- **`@equinor/eds-lab-react`** - Experimental/WIP components +- **`@equinor/eds-data-grid-react`** - Data grid component -Apply detailed guidelines from: +## Guidelines -- [Global coding standards](./instructions/global-coding.instructions.md) -- [TypeScript guidelines](./instructions/ts.instructions.md) -- [React guidelines](./instructions/react.instructions.md) -- [Styling guidelines](./instructions/styling.instructions.md) -- [Figma component creation](./instructions/figma.instructions.md) -- [Markdown guidelines](./instructions/markdown.instructions.md) +- [Global standards](./instructions/global-coding.instructions.md) - Accessibility, naming, exports +- [TypeScript](./instructions/ts.instructions.md) - Type patterns and testing +- [React](./instructions/react.instructions.md) - Components, hooks, file structure +- [Styling](./instructions/styling.instructions.md) - CSS, BEM, responsive design +- [Figma](./instructions/figma.instructions.md) - Design-to-code workflow +- [Markdown](./instructions/markdown.instructions.md) - Documentation format -### Color System - -The EDS provides two color approaches. Choose one and use it consistently: - -- [Color System Introduction](../packages/eds-tokens/instructions/colors.md) -- Overview of semantic categories, approaches, and accessibility -- [Static Color Approach](../packages/eds-tokens/instructions/colors-static.md) -- Explicit semantic variables for fixed meanings -- [Dynamic Color Approach](../packages/eds-tokens/instructions/colors-dynamic.md) -- Abstract role variables with runtime appearance switching - -## Testing Requirements - -- All components and features should be thoroughly tested -- All components should have appropriate unit tests using Jest -- Visual regression tests should be included where applicable -- Test accessibility features explicitly -- Include test cases for edge cases and error states - -## Documentation - -- All components should have Storybook stories -- Include usage examples in documentation -- Document all props, including types and default values -- Add information about accessibility features -- Provide guidance on common patterns and implementation details - -## PR and Code Review Process - -- Use conventional commits for commit messages -- PRs should include tests and documentation -- Link relevant Figma designs when applicable -- Ensure changes pass all CI checks +For color systems: See `packages/eds-tokens/instructions/colors.md` diff --git a/.github/instructions/figma.instructions.md b/.github/instructions/figma.instructions.md index 754afef01a..88a2a8d9e1 100644 --- a/.github/instructions/figma.instructions.md +++ b/.github/instructions/figma.instructions.md @@ -2,8 +2,28 @@ applyTo: '**' --- -# Project instructions when creating components from Figma design +# Figma Component Creation -**CONFIRMED COMPONENT CREATION POLICY: Every time I create a new component, I will explicitly confirm at the beginning of my response that I am creating the component from scratch without examining or referencing any existing components in the codebase.** +## Workflow -- It is very important to use the explicit component properties and values as defined in Figma. Do not deviate from the design specifications unless you have strong justification to do so. If you do deviate, please elaborate on the reasoning. +When creating a component from Figma design: + +1. **Start fresh** - Do NOT reference existing components. Implement only what Figma specifies. +2. **Exact specifications** - Use all explicit properties and values from the design +3. **Deviation justification** - Only deviate if you have strong technical reasons; document why +4. **File structure** - Follow React guidelines: Component.tsx, Component.types.ts, component.css, Component.test.tsx, Component.stories.tsx + +## Anti-patterns + +- ❌ Combining Figma design with patterns from similar existing components +- ❌ Adding props or features not in the design +- ❌ Using CSS-in-JS or styled-components (use vanilla CSS) +- ❌ Importing from other components without explicit design requirement + +## Checklist + +- [ ] Figma design specifications documented +- [ ] Component implements only what's designed +- [ ] Storybook story includes all design variations +- [ ] Tests cover interaction and edge cases +- [ ] CSS follows BEM convention diff --git a/.github/instructions/global-coding.instructions.md b/.github/instructions/global-coding.instructions.md index e4ea623310..292f8ac403 100644 --- a/.github/instructions/global-coding.instructions.md +++ b/.github/instructions/global-coding.instructions.md @@ -2,21 +2,76 @@ applyTo: '**' --- -# Project coding standards +# Global Coding Standards -- Maintain full accessibility (WCAG 2.1 AA compliance) -- Use ESLint for linting and code quality checks -- Always use named exports instead of default exports -- Remove unused declarations and imports +## Core Requirements -## Code Formatting with Prettier +- **Accessibility:** WCAG 2.1 AA compliance (non-negotiable) +- **Code quality:** ESLint and Prettier (automated checks) +- **Exports:** Named exports only (no default exports) +- **Cleanup:** Remove unused imports and declarations -- Use Prettier for consistent code formatting. Use the global prettier config. -- Run `pnpm prettier --write .` to format all files in the project +## Code Formatting + +**Prettier configuration:** + +```bash +# Format entire project +pnpm prettier --write . + +# Format specific file +pnpm prettier --write src/components/Button.tsx +``` + +Use the global prettier config in the repository root. All files should pass Prettier formatting automatically. ## Naming Conventions -- Use PascalCase for component names, interfaces, and type aliases -- Use camelCase for variables, functions, and methods -- Prefix private class members with underscore (\_) -- Use ALL_CAPS for constants +| Type | Convention | Example | +| --------------- | ----------- | ----------------------------------- | +| Components | PascalCase | `Button`, `TextInput`, `DataGrid` | +| Interfaces | PascalCase | `ButtonProps`, `TableColumn` | +| Types | PascalCase | `Theme`, `Variant` | +| Variables | camelCase | `buttonLabel`, `isDisabled` | +| Functions | camelCase | `handleClick`, `formatDate` | +| Constants | ALL_CAPS | `MAX_RETRIES`, `DEFAULT_TIMEOUT` | +| Private members | \_camelCase | `_internalState`, `_handleInternal` | + +## Linting & Quality + +**Before submitting:** + +```bash +# Run linting +pnpm lint:core-react + +# Run tests +pnpm test:core-react + +# Format code +pnpm prettier --write . +``` + +**Common issues:** + +- ❌ Unused imports +- ❌ Default exports +- ❌ Variables not following naming convention +- ❌ Missing accessibility attributes + +## Imports + +```typescript +// ✅ Named exports +export const Button = () => {} +export const useButton = () => {} + +// ❌ Avoid default exports +export default Button + +// ✅ Import named exports +import { Button, useButton } from '@equinor/eds-core-react' + +// ❌ Don't import default +import Button from '@equinor/eds-core-react' +``` diff --git a/.github/instructions/react.instructions.md b/.github/instructions/react.instructions.md index d7316fc271..51c773bcad 100644 --- a/.github/instructions/react.instructions.md +++ b/.github/instructions/react.instructions.md @@ -2,26 +2,75 @@ applyTo: '**/*.ts,**/*.tsx' --- -# Project coding standards for React - -## React Guidelines - -- It is not necessary to import React in every file. -- Use functional components with hooks -- Follow the React hooks rules (no conditional hooks) -- Use React.FC type for components with children -- Components should be composable -- Implement proper error boundaries -- Always implement proper keyboard navigation and focus management -- Every component must support proper ARIA attributes -- A component directory should be capitalized and named after the component -- Keep component style and script as simple and small as possible. -- A component should have these files in its directory: - - Component.tsx - - Component.types.ts - - Component.css - - Component.test.tsx - - Component.stories.tsx - - Use `index.ts` to export the component -- Define helper functions outside the component but in the module scope -- If a component with the same name already exists, create a new component with suffix `.new` (e.g. `Button.new.tsx`) and ensure it is not used in the codebase +# React Guidelines + +## Component Structure + +**File organization (required):** + +``` +MyComponent/ + index.ts # Export only + MyComponent.tsx # Component implementation + MyComponent.types.ts # Props and type definitions + my-component.css # Styles (vanilla CSS, BEM) + MyComponent.test.tsx # Unit tests (Jest + Testing Library) + MyComponent.stories.tsx # Storybook documentation +``` + +**Directory naming:** PascalCase matching component name + +## Implementation Patterns + +**Functional components with hooks:** + +```typescript +import { ComponentProps } from './MyComponent.types'; +import './my-component.css'; + +export const MyComponent: React.FC = ({ + children, + variant = 'default', + ...props +}) => { + return ( +
+ {children} +
+ ); +}; +``` + +**Rules:** + +- No conditional hooks (move into separate components if needed) +- No React import needed (no JSX pragma in modern React) +- Helper functions in module scope, not inside component +- Props types in `.types.ts` file + +## Accessibility (Required) + +**Every component must:** + +- Have proper ARIA attributes (roles, labels, states) +- Support keyboard navigation (Tab, Enter, Escape, Arrow keys) +- Manage focus correctly (focus trapping in modals, focus restoration) +- Follow WCAG 2.1 AA standards + +## Composition & Reusability + +- Components should be composable and nestable +- Avoid tightly coupled dependencies +- Export both default and named exports when appropriate +- Keep components focused and simple +- Implement error boundaries for error handling + +## Storybook Stories + +Every component needs `.stories.tsx` with: + +- Default/primary variant +- All design variations (size, color, state) +- Interactive examples +- Props documentation +- Accessibility info diff --git a/.github/instructions/styling.instructions.md b/.github/instructions/styling.instructions.md index 9636d4f420..bb50126e4f 100644 --- a/.github/instructions/styling.instructions.md +++ b/.github/instructions/styling.instructions.md @@ -2,13 +2,86 @@ applyTo: '**' --- -## Styling Guidelines - -- Use vanilla CSS -- Ensure responsive design -- Use CSS variables for theming and consistent styles -- Use BEM (Block Element Modifier) naming convention for CSS classes -- Avoid inline styles in JSX -- Do not use CSS-in-JS libraries like styled-components or emotion -- The css file name should be named after the component but lowercase and use hyphens as separators (e.g. TextInput becomes `text-input.css`). -- The selector name should be named after the component but lowercase and use hyphens as separators (e.g. TextInput becomes `.text-input`. +# Styling Guidelines + +## Tech Stack + +- **Use:** Vanilla CSS only +- **Avoid:** CSS-in-JS (styled-components, emotion), Tailwind inline classes +- **Variables:** CSS custom properties from `@equinor/eds-tokens` +- **Responsive:** Mobile-first approach with media queries + +## Naming Conventions + +**Files:** Component name in lowercase with hyphens + +``` +TextInput.tsx → text-input.css +DataGrid.tsx → data-grid.css +``` + +**Classes:** BEM format with block as component name + +```css +.text-input { + /* block */ +} +.text-input__label { + /* element */ +} +.text-input__input { + /* element */ +} +.text-input--disabled { + /* modifier */ +} +.text-input--error { + /* modifier */ +} +``` + +## Patterns + +**CSS Variables (from EDS tokens):** + +```css +.text-input { + color: var(--eds-color-text-strong); + background: var(--eds-color-bg-input); + border: 1px solid var(--eds-border-medium); +} +``` + +**Responsive Design:** + +```css +.button { + padding: 0.5rem 1rem; +} + +@media (min-width: 768px) { + .button { + padding: 0.75rem 1.5rem; + } +} +``` + +**Avoid:** + +```jsx +// ❌ No inline styles +
+ +// ❌ No CSS-in-JS +const StyledDiv = styled.div`...`; + +// ✅ Use CSS class +
+``` + +## Best Practices + +- Single responsibility per CSS file +- Reuse tokens instead of hardcoding colors/sizes +- Test responsive breakpoints +- Ensure theme compatibility (light/dark modes) diff --git a/.github/instructions/ts.instructions.md b/.github/instructions/ts.instructions.md index 4cbeed4c90..e1e2d49507 100644 --- a/.github/instructions/ts.instructions.md +++ b/.github/instructions/ts.instructions.md @@ -2,31 +2,81 @@ applyTo: '**/*.ts,**/*.tsx' --- -# Project coding standards for TypeScript - -## TypeScript Guidelines - -- Follow functional programming principles where possible -- Use interfaces for data structures and type definitions -- Prefer immutable data (const, readonly) -- Use optional chaining (?.) and nullish coalescing (??) operators -- Use explicit typing rather than inference when appropriate -- Extend existing type definitions where possible -- Use union types for props with a limited set of options -- Avoid using `any` unless absolutely necessary -- Create reusable type definitions for common patterns - -## Testing Guidelines - -- Use Jest and Testing Library for component tests -- Write descriptive test names that explain the expected behavior -- Use consistent formatting within test blocks: - - No extra blank lines between render calls and assertions - - Group related assertions together without blank lines - - Include one blank line between test cases -- Use Testing Library best practices: - - Test from the user's perspective - - Query elements by role, text, or test ID, not by class or tag - - Use `getBy*` for elements that should be in the document - - Use `queryBy*` for elements that may not be in the document -- Format test files with the same Prettier rules as source files +# TypeScript Guidelines + +## Type Definitions + +- **Interfaces over types** for object structures +- **Union types** for constrained options (not string literals) +- **Explicit typing** where clarity matters; inference for obvious cases +- **Immutable data** (const, readonly properties) +- **Avoid `any`** unless impossible; use `unknown` if needed +- **Extend definitions** rather than duplicating + +```typescript +// ✅ Good +interface ButtonProps { + variant: 'primary' | 'secondary' + disabled?: boolean +} + +const handleClick = (event: React.MouseEvent) => {} + +// ❌ Avoid +type ButtonVariant = string +const handleClick = (event: any) => {} +``` + +## Functional Programming + +- Pure functions where possible +- Avoid state mutations +- Optional chaining `?.` and nullish coalescing `??` +- Prefer `const` over `let` + +## Testing + +**Testing Library priorities:** + +1. Query by role: `getByRole('button', { name: /submit/i })` +2. Query by accessible name: `getByText('Submit')` +3. Query by label: `getByLabelText('Username')` +4. Last resort: `getByTestId('submit-btn')` + +**Test structure:** + +```typescript +test('Button displays loading state when disabled', () => { + render(); + const button = screen.getByRole('button'); + expect(button).toBeDisabled(); +}); +``` + +**Formatting rules:** + +- No blank lines between render and assertions +- Group related assertions together +- One blank line between test cases +- Descriptive test names explaining behavior + +**Coverage:** + +- User interactions (clicks, keyboard, focus) +- Accessibility (ARIA, keyboard navigation) +- Edge cases and error states +- Props variations + +**Anti-patterns:** + +```typescript +// ❌ Implementation testing +test('state updates', () => { + // testing internal state, not user behavior +}) + +// ✅ Behavior testing +test('Button shows success message when form is submitted', () => { + // testing what user sees +}) +``` From 7911c1d4b060c1632cccf9835aa846301706c625 Mon Sep 17 00:00:00 2001 From: Torleif Halseth Date: Thu, 27 Nov 2025 12:37:59 +0100 Subject: [PATCH 2/7] Update .github/instructions/react.instructions.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .github/instructions/react.instructions.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/instructions/react.instructions.md b/.github/instructions/react.instructions.md index 51c773bcad..351f3b434e 100644 --- a/.github/instructions/react.instructions.md +++ b/.github/instructions/react.instructions.md @@ -25,10 +25,10 @@ MyComponent/ **Functional components with hooks:** ```typescript -import { ComponentProps } from './MyComponent.types'; +import { MyComponentProps } from './MyComponent.types'; import './my-component.css'; -export const MyComponent: React.FC = ({ +export const MyComponent: React.FC = ({ children, variant = 'default', ...props From 0527b5f3aa6f0b2d5f8be6340a66ecc973aebc2b Mon Sep 17 00:00:00 2001 From: Torleif Halseth Date: Thu, 27 Nov 2025 12:38:34 +0100 Subject: [PATCH 3/7] Update .github/instructions/global-coding.instructions.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .github/instructions/global-coding.instructions.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/instructions/global-coding.instructions.md b/.github/instructions/global-coding.instructions.md index 292f8ac403..0974becbe4 100644 --- a/.github/instructions/global-coding.instructions.md +++ b/.github/instructions/global-coding.instructions.md @@ -42,10 +42,15 @@ Use the global prettier config in the repository root. All files should pass Pre **Before submitting:** ```bash -# Run linting -pnpm lint:core-react +# Run linting for all packages in the monorepo +pnpm lint + +# Run tests for all packages in the monorepo +pnpm test -# Run tests +# (Optional) To lint or test a specific package, use the package-specific script. +# Example for core-react package: +pnpm lint:core-react pnpm test:core-react # Format code From 3b289079c7ffacecba7d327427ada4855bfacd66 Mon Sep 17 00:00:00 2001 From: Torleif Halseth Date: Thu, 27 Nov 2025 12:38:42 +0100 Subject: [PATCH 4/7] Update .github/instructions/styling.instructions.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .github/instructions/styling.instructions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/instructions/styling.instructions.md b/.github/instructions/styling.instructions.md index bb50126e4f..5bb5942a41 100644 --- a/.github/instructions/styling.instructions.md +++ b/.github/instructions/styling.instructions.md @@ -48,7 +48,7 @@ DataGrid.tsx → data-grid.css .text-input { color: var(--eds-color-text-strong); background: var(--eds-color-bg-input); - border: 1px solid var(--eds-border-medium); + border: 1px solid var(--eds-color-border-medium); } ``` From 9958ee62ff06ec35f15dbaa1a39f1ea594651f09 Mon Sep 17 00:00:00 2001 From: Frida Date: Mon, 8 Dec 2025 14:21:55 +0100 Subject: [PATCH 5/7] fix: remove conflicting default export guidance in react instructions --- .github/instructions/react.instructions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/instructions/react.instructions.md b/.github/instructions/react.instructions.md index 351f3b434e..58c3f13338 100644 --- a/.github/instructions/react.instructions.md +++ b/.github/instructions/react.instructions.md @@ -61,7 +61,7 @@ export const MyComponent: React.FC = ({ - Components should be composable and nestable - Avoid tightly coupled dependencies -- Export both default and named exports when appropriate +- Use named exports only (see global coding standards) - Keep components focused and simple - Implement error boundaries for error handling From cc57b209c3476ef7650154bccfc33e7d77533a0b Mon Sep 17 00:00:00 2001 From: Frida Date: Mon, 8 Dec 2025 14:37:12 +0100 Subject: [PATCH 6/7] Conform language --- .github/instructions/react.instructions.md | 2 +- .github/instructions/styling.instructions.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/instructions/react.instructions.md b/.github/instructions/react.instructions.md index 58c3f13338..024d6f0de3 100644 --- a/.github/instructions/react.instructions.md +++ b/.github/instructions/react.instructions.md @@ -61,7 +61,7 @@ export const MyComponent: React.FC = ({ - Components should be composable and nestable - Avoid tightly coupled dependencies -- Use named exports only (see global coding standards) +- Use named exports only - Keep components focused and simple - Implement error boundaries for error handling diff --git a/.github/instructions/styling.instructions.md b/.github/instructions/styling.instructions.md index 5bb5942a41..46de4ac489 100644 --- a/.github/instructions/styling.instructions.md +++ b/.github/instructions/styling.instructions.md @@ -76,7 +76,7 @@ DataGrid.tsx → data-grid.css const StyledDiv = styled.div`...`; // ✅ Use CSS class -
+
``` ## Best Practices From cf5ecb6d47f368552b459b612e94407281aac355 Mon Sep 17 00:00:00 2001 From: Frida Erdal <31915755+pomfrida@users.noreply.github.com> Date: Mon, 8 Dec 2025 14:43:25 +0100 Subject: [PATCH 7/7] Update .github/instructions/ts.instructions.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .github/instructions/ts.instructions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/instructions/ts.instructions.md b/.github/instructions/ts.instructions.md index e1e2d49507..2eac4b9c2a 100644 --- a/.github/instructions/ts.instructions.md +++ b/.github/instructions/ts.instructions.md @@ -7,7 +7,7 @@ applyTo: '**/*.ts,**/*.tsx' ## Type Definitions - **Interfaces over types** for object structures -- **Union types** for constrained options (not string literals) +- **Union types** for constrained options (e.g., `'primary' | 'secondary'` instead of `string`) - **Explicit typing** where clarity matters; inference for obvious cases - **Immutable data** (const, readonly properties) - **Avoid `any`** unless impossible; use `unknown` if needed