Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
268 changes: 153 additions & 115 deletions .github/agents/ag-grid-styling.agent.md

Large diffs are not rendered by default.

80 changes: 46 additions & 34 deletions .github/agents/style.agent.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
---
description: Audit React components for mieweb/ui branding compliance - colors, border radius, fonts, and design tokens
name: Style Agent
tools: ['search', 'codebase', 'editFiles', 'terminalLastCommand', 'runInTerminal']
tools:
['search', 'codebase', 'editFiles', 'terminalLastCommand', 'runInTerminal']
model: Claude Sonnet 4
handoffs:
- label: Apply Fixes
Expand All @@ -17,6 +18,7 @@ You are a specialized style auditor for the **mieweb/ui** design system. Your jo
## Your Expertise

You are an expert in:

- Tailwind CSS utility classes
- CSS custom properties (CSS variables)
- React component patterns
Expand All @@ -29,75 +31,84 @@ You are an expert in:
The branding system uses CSS variables defined per brand. Each brand (BlueHive, MIEWeb, WebChart, Enterprise Health, Waggleline) defines:

**Color Variables:**

- `--mieweb-primary-{50-950}` - Primary brand color scale
- `--mieweb-secondary-{50-950}` - Secondary color scale
- `--mieweb-secondary-{50-950}` - Secondary color scale
- `--mieweb-neutral-{50-950}` - Neutral/gray scale
- `--mieweb-success` / `--mieweb-success-foreground` - Success semantic color
- `--mieweb-destructive` / `--mieweb-destructive-foreground` - Error/danger semantic color
- `--mieweb-warning` / `--mieweb-warning-foreground` - Warning semantic color

**Border Radius Variables:**

- `--mieweb-radius-sm` (0.25rem)
- `--mieweb-radius-md` (0.5rem)
- `--mieweb-radius-lg` (0.75rem)
- `--mieweb-radius-xl` (1rem)
- `--mieweb-radius-2xl` (1.5rem)

**Typography Variables:**

- `--mieweb-font-sans` - Primary font family
- `--mieweb-font-mono` - Monospace font family

**Shadow Variables:**

- `--mieweb-shadow-card` - Card shadow

### Tailwind Preset Mappings

The `tailwind-preset.ts` maps CSS variables to Tailwind classes:

| Tailwind Class | CSS Variable |
|---------------|--------------|
| `primary-500` | `var(--mieweb-primary-500)` |
| Tailwind Class | CSS Variable |
| --------------- | ----------------------------- |
| `primary-500` | `var(--mieweb-primary-500)` |
| `secondary-500` | `var(--mieweb-secondary-500)` |
| `neutral-500` | `var(--mieweb-neutral-500)` |
| `rounded-lg` | `var(--mieweb-radius-lg)` |
| `rounded-2xl` | `var(--mieweb-radius-2xl)` |
| `font-sans` | `var(--mieweb-font-sans)` |
| `neutral-500` | `var(--mieweb-neutral-500)` |
| `rounded-lg` | `var(--mieweb-radius-lg)` |
| `rounded-2xl` | `var(--mieweb-radius-2xl)` |
| `font-sans` | `var(--mieweb-font-sans)` |

## What to Flag as Issues

### ❌ Hardcoded Colors (BAD)

Copilot AI Apr 22, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These examples are no longer valid JSX/TSX usage of className (they read like assignments, not component markup). This is likely to confuse readers and code-review agents; update the examples back to syntactically correct TSX (e.g., showing <div className=\"...\" />), while keeping the intent about hardcoded vs token-based classes.

Copilot uses AI. Check for mistakes.

```tsx
// These bypass the branding system:
className="bg-violet-500" // Hardcoded violet
className="bg-purple-600" // Hardcoded purple
className="bg-blue-500" // Hardcoded blue
className="text-indigo-600" // Hardcoded indigo
className="from-violet-500 to-purple-600" // Hardcoded gradients
className = 'bg-violet-500'; // Hardcoded violet
className = 'bg-purple-600'; // Hardcoded purple
className = 'bg-blue-500'; // Hardcoded blue
className = 'text-indigo-600'; // Hardcoded indigo
className = 'from-violet-500 to-purple-600'; // Hardcoded gradients
```

### ✅ Brand-Aware Colors (GOOD)

```tsx
// These respect the active brand:
className="bg-primary-500" // Uses brand primary
className="text-primary-600" // Uses brand primary
className="bg-secondary-500" // Uses brand secondary
className="text-neutral-700" // Uses brand neutral
className = 'bg-primary-500'; // Uses brand primary
className = 'text-primary-600'; // Uses brand primary
className = 'bg-secondary-500'; // Uses brand secondary
className = 'text-neutral-700'; // Uses brand neutral
```

### Exceptions - Semantic Colors (OKAY)

These are intentionally hardcoded for consistent meaning across brands:

- `bg-red-*`, `text-red-*` - Error/danger states
- `bg-green-*`, `text-green-*` - Success states
- `bg-green-*`, `text-green-*` - Success states
- `bg-amber-*`, `bg-yellow-*` - Warning states
- `bg-neutral-*` - Only if specifically for UI chrome, not brand expression

### Border Radius Issues

```tsx
// Check if these use brand radius variables:
className="rounded-lg" // ✅ Mapped to --mieweb-radius-lg
className="rounded-2xl" // ✅ Mapped to --mieweb-radius-2xl
className="rounded-full" // ✅ OK for circular elements (avatars, pills)
className="rounded-[20px]" // ❌ Hardcoded - should use brand token
className = 'rounded-lg'; // ✅ Mapped to --mieweb-radius-lg
className = 'rounded-2xl'; // ✅ Mapped to --mieweb-radius-2xl
className = 'rounded-full'; // ✅ OK for circular elements (avatars, pills)
className = 'rounded-[20px]'; // ❌ Hardcoded - should use brand token
```

## Audit Process
Expand Down Expand Up @@ -131,25 +142,26 @@ When reporting issues, use this format:

**File:** `src/components/ComponentName/ComponentName.tsx`

| Line | Issue | Current | Recommended |
|------|-------|---------|-------------|
| 45 | Hardcoded color | `bg-violet-500` | `bg-primary-500` |
| 67 | Hardcoded gradient | `from-violet-500 to-purple-600` | `bg-primary-500` |
| Line | Issue | Current | Recommended |
| ---- | ------------------ | ------------------------------- | ---------------- |
| 45 | Hardcoded color | `bg-violet-500` | `bg-primary-500` |
| 67 | Hardcoded gradient | `from-violet-500 to-purple-600` | `bg-primary-500` |

**Summary:**

- ✅ Border radius: Using brand tokens correctly
- ❌ Colors: 2 hardcoded colors found
- ✅ Typography: Using font-sans correctly

## Brand Reference

| Brand | Primary Color | Example |
|-------|---------------|---------|
| BlueHive | Blue `#27aae1` | Healthcare/Medical |
| MIEWeb | Purple | Enterprise |
| WebChart | Blue | Clinical |
| Enterprise Health | Teal | Corporate |
| Waggleline | Orange | Consumer |
| Brand | Primary Color | Example |
| ----------------- | -------------- | ------------------ |
| BlueHive | Blue `#27aae1` | Healthcare/Medical |
| MIEWeb | Purple | Enterprise |
| WebChart | Blue | Clinical |
| Enterprise Health | Teal | Corporate |
| Waggleline | Orange | Consumer |

## Key Files to Reference

Expand Down
4 changes: 4 additions & 0 deletions .github/prompts/commit.prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,25 @@ Run the standard commit workflow: format, lint, and commit with a generated mess
Execute these steps in order:

1. **Format the code**

```bash
npm run format:fix
```

2. **Lint and fix issues**

```bash
npm run lint:fix
```

3. **Check for any remaining errors**

```bash
npm run lint && npm run typecheck
```

4. **Stage all changes**

```bash
git add -A
```
Expand Down
2 changes: 2 additions & 0 deletions .github/prompts/fix.prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ Auto-fix all formatting and linting issues.
Execute these steps:

1. **Auto-format code**

```bash
npm run format:fix
```

2. **Auto-fix lint issues**

```bash
npm run lint:fix
```
Expand Down
2 changes: 2 additions & 0 deletions .github/prompts/validate.prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ Run validation checks without committing.
Execute these steps and report results:

1. **Format check**

```bash
npm run format
```

2. **Lint check**

```bash
npm run lint
```
Expand Down
22 changes: 12 additions & 10 deletions .storybook/manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ type BrandKey = keyof typeof brandThemes;
// Create a theme for a specific brand
function createBrandTheme(brandKey: BrandKey, isDark = false) {
const brand = brandThemes[brandKey] || brandThemes.bluehive;

if (isDark) {
return create({
base: 'dark',
Expand Down Expand Up @@ -112,7 +112,7 @@ function createBrandTheme(brandKey: BrandKey, isDark = false) {
fontCode: '"SF Mono", "Monaco", "Consolas", monospace',
});
}

return create({
base: 'light',

Expand Down Expand Up @@ -181,13 +181,13 @@ const styleId = 'mieweb-manager-theme';

function injectBrandCSS(brandKey: BrandKey, isDark = false) {
const brand = brandThemes[brandKey] || brandThemes.bluehive;

// Remove existing style
const existingStyle = document.getElementById(styleId);
if (existingStyle) {
existingStyle.remove();
}

// Dark mode colors
const bgColor = isDark ? brand.appBgDark : brand.appBg;
const borderColor = isDark ? brand.borderColorDark : brand.borderColor;
Expand All @@ -197,7 +197,7 @@ function injectBrandCSS(brandKey: BrandKey, isDark = false) {
const barBg = isDark ? '#27272a' : '#ffffff';
const inputBg = isDark ? '#27272a' : '#ffffff';
const inputBorder = isDark ? '#3f3f46' : '#d1d5db';

// Create new style with brand colors
const style = document.createElement('style');
style.id = styleId;
Expand Down Expand Up @@ -399,9 +399,11 @@ function injectBrandCSS(brandKey: BrandKey, isDark = false) {
label[for^="control-"] input[type="checkbox"] {
background: transparent !important;
}
` : ''}
`
: ''
}
`;

document.head.appendChild(style);
}

Expand All @@ -411,18 +413,18 @@ addons.register('mieweb-brand-sync', (api) => {
const initialGlobals = api.getGlobals();
const initialBrand = (initialGlobals?.brand || 'bluehive') as BrandKey;
const initialDark = initialGlobals?.theme === 'dark';

// Apply initial theme
injectBrandCSS(initialBrand, initialDark);
if (initialDark) {
api.setOptions({ theme: createBrandTheme(initialBrand, true) });
}

// Listen for global changes
api.on('globalsUpdated', ({ globals }) => {
const brand = (globals?.brand || 'bluehive') as BrandKey;
const isDark = globals?.theme === 'dark';

// Update CSS and theme
injectBrandCSS(brand, isDark);
api.setOptions({ theme: createBrandTheme(brand, isDark) });
Expand Down
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -670,10 +670,10 @@ This package uses automated releases via GitHub Actions. There are two release c

### Release Channels

| Channel | npm Tag | Install Command | Description |
| ------- | ------- | --------------- | ----------- |
| **Stable** | `latest` | `npm install @mieweb/ui` | Production-ready releases |
| **Prerelease** | `next` | `npm install @mieweb/ui@next` | Latest from `main` branch |
| Channel | npm Tag | Install Command | Description |
| -------------- | -------- | ----------------------------- | ------------------------- |
| **Stable** | `latest` | `npm install @mieweb/ui` | Production-ready releases |
| **Prerelease** | `next` | `npm install @mieweb/ui@next` | Latest from `main` branch |

### Prerelease (Automatic)

Expand All @@ -699,6 +699,7 @@ To create a stable release:
5. Click **Run workflow**

The workflow will:

1. Bump the version in `package.json`
2. Commit and push the change
3. Create a git tag (e.g., `v0.2.0`)
Expand All @@ -715,6 +716,7 @@ git push origin v1.0.0
```

The release workflow will automatically:

- Run tests and build
- Publish to npm with the appropriate tag (`latest` for stable, `next` for prereleases like `v1.0.0-beta.1`)
- Create a GitHub Release with auto-generated release notes
Expand Down
Loading
Loading