From 8f7664d42afabc9ff8833152ae162afae5a80d87 Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Fri, 3 Apr 2026 18:50:35 -0400 Subject: [PATCH 01/11] chore: Update dependencies in bun.lock and package.json - Bump librechat-data-provider to version 0.8.407 - Update axios to version 1.13.6 --- bun.lock | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bun.lock b/bun.lock index 15d8a56..f3f9999 100644 --- a/bun.lock +++ b/bun.lock @@ -24,7 +24,7 @@ "i18next-browser-languagedetector": "^8.2.1", "input-otp": "^1.4.2", "js-yaml": "^4.1.1", - "librechat-data-provider": "^0.8.406", + "librechat-data-provider": "^0.8.407", "lucide-react": "^0.545.0", "react": "^19.2.0", "react-dom": "^19.2.0", @@ -706,7 +706,7 @@ "axe-core": ["axe-core@4.11.1", "", {}, "sha512-BASOg+YwO2C+346x3LZOeoovTIoTrRqEsqMa6fmfAV0P+U9mFr9NsyOEpiYvFjbc64NMrSswhV50WdXzdb/Z5A=="], - "axios": ["axios@1.13.5", "", { "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", "proxy-from-env": "^1.1.0" } }, "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q=="], + "axios": ["axios@1.13.6", "", { "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", "proxy-from-env": "^1.1.0" } }, "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ=="], "babel-dead-code-elimination": ["babel-dead-code-elimination@1.0.12", "", { "dependencies": { "@babel/core": "7.29.0", "@babel/parser": "7.29.0", "@babel/traverse": "7.29.0", "@babel/types": "7.29.0" } }, "sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig=="], @@ -1104,7 +1104,7 @@ "levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="], - "librechat-data-provider": ["librechat-data-provider@0.8.406", "", { "dependencies": { "axios": "^1.13.5", "dayjs": "^1.11.13", "js-yaml": "^4.1.1", "zod": "^3.22.4" }, "peerDependencies": { "@tanstack/react-query": "^4.28.0" } }, "sha512-8sU5/6h4SVx9PShnvarNOYe+bMxnZImSN7tVb+Ve28eqJhOkNJgRwdzTZSS0B6mPZJf+K+FmoRwJuBIXq3LqJA=="], + "librechat-data-provider": ["librechat-data-provider@0.8.407", "", { "dependencies": { "axios": "1.13.6", "dayjs": "^1.11.13", "js-yaml": "^4.1.1", "zod": "^3.22.4" }, "peerDependencies": { "@tanstack/react-query": "^4.28.0" } }, "sha512-oMp+d7YFnKRCUu9CAFX0fzU7Z4xOFkiA/Ib9abug+5lRiIvTHZ2r+LvQI+xGJ8aJEcIvBdTPmxrtAIuG3St8pA=="], "lightningcss": ["lightningcss@1.32.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="], diff --git a/package.json b/package.json index 8b48cfa..16eba61 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "i18next-browser-languagedetector": "^8.2.1", "input-otp": "^1.4.2", "js-yaml": "^4.1.1", - "librechat-data-provider": "^0.8.406", + "librechat-data-provider": "^0.8.407", "lucide-react": "^0.545.0", "react": "^19.2.0", "react-dom": "^19.2.0", From 391da28092cb498b86bf3b4d4798a0ae0036f185 Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Fri, 3 Apr 2026 19:02:49 -0400 Subject: [PATCH 02/11] fix: TOC parent-level section navigation for accordion groups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Accordion sections rendered via MultiAccordion.Item had no id attribute on the DOM, so document.getElementById returned null for parent-level TOC items — preventing scroll navigation. Pass the id prop directly to MultiAccordion.Item which spreads it onto the underlying Radix element. --- src/components/configuration/ConfigTabContent.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/configuration/ConfigTabContent.tsx b/src/components/configuration/ConfigTabContent.tsx index 3163758..46b7774 100644 --- a/src/components/configuration/ConfigTabContent.tsx +++ b/src/components/configuration/ConfigTabContent.tsx @@ -304,6 +304,7 @@ export function ConfigTabContent({ {group.sections.map((section) => ( From cf28abcd19d7877222b7b90f515344d5784afcd2 Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Fri, 3 Apr 2026 19:13:51 -0400 Subject: [PATCH 03/11] chore: add Click UI skill and ESLint plugin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add .claude/skills/click-ui.md for AI assistant guidance - Add eslint-plugin-click-ui (v1.1.1) in tools/ with recommended config - Patch plugin rules for ESLint 10 compatibility (context.filename) - Fix Button children→label prop in GroupsTab and RolesTab - Disable require-provider and select-requires-options (false positives) - Exclude tools/ from tsconfig --- .claude/skills/click-ui.md | 741 ++++++++++++++++++ bun.lock | 129 ++- eslint.config.js | 5 + package.json | 1 + src/components/PasswordInput.tsx | 1 + src/components/access/GroupsTab.tsx | 5 +- src/components/access/RolesTab.tsx | 5 +- tools/eslint-plugin-click-ui/.eslintrc.json | 45 ++ tools/eslint-plugin-click-ui/ARCHITECTURE.md | 276 +++++++ tools/eslint-plugin-click-ui/CHANGELOG.md | 51 ++ tools/eslint-plugin-click-ui/IMPROVEMENTS.md | 269 +++++++ tools/eslint-plugin-click-ui/QUICK_START.md | 137 ++++ tools/eslint-plugin-click-ui/README.md | 524 +++++++++++++ tools/eslint-plugin-click-ui/ROLLOUT_GUIDE.md | 340 ++++++++ .../correct-examples.tsx | 138 ++++ tools/eslint-plugin-click-ui/index.js | 90 +++ tools/eslint-plugin-click-ui/package.json | 31 + .../rules/avoid-generic-label.js | 35 + .../rules/button-requires-label.js | 91 +++ .../rules/checkbox-radiogroup-controlled.js | 79 ++ .../rules/container-requires-orientation.js | 59 ++ .../rules/datepicker-controlled.js | 52 ++ .../rules/dialog-controlled-state.js | 66 ++ .../rules/form-controlled-components.js | 62 ++ .../rules/icon-name-format.js | 87 ++ .../rules/logo-name-format.js | 87 ++ .../rules/prefer-named-imports.js | 38 + .../rules/require-css-import.js | 48 ++ .../rules/require-provider.js | 71 ++ .../rules/select-requires-options.js | 63 ++ .../rules/switch-controlled-state.js | 66 ++ .../rules/table-structure.js | 80 ++ .../rules/valid-button-type.js | 55 ++ .../rules/valid-icon-name.js | 130 +++ .../rules/valid-icon-size.js | 55 ++ .../rules/valid-logo-name.js | 126 +++ .../rules/valid-provider-config.js | 49 ++ .../rules/valid-spacing-token.js | 47 ++ .../rules/valid-theme-name.js | 55 ++ .../rules/valid-title-type.js | 55 ++ .../eslint-plugin-click-ui/test-examples.tsx | 104 +++ .../tests/rules.test.js | 98 +++ tsconfig.json | 2 +- 43 files changed, 4539 insertions(+), 9 deletions(-) create mode 100644 .claude/skills/click-ui.md create mode 100644 tools/eslint-plugin-click-ui/.eslintrc.json create mode 100644 tools/eslint-plugin-click-ui/ARCHITECTURE.md create mode 100644 tools/eslint-plugin-click-ui/CHANGELOG.md create mode 100644 tools/eslint-plugin-click-ui/IMPROVEMENTS.md create mode 100644 tools/eslint-plugin-click-ui/QUICK_START.md create mode 100644 tools/eslint-plugin-click-ui/README.md create mode 100644 tools/eslint-plugin-click-ui/ROLLOUT_GUIDE.md create mode 100644 tools/eslint-plugin-click-ui/correct-examples.tsx create mode 100644 tools/eslint-plugin-click-ui/index.js create mode 100644 tools/eslint-plugin-click-ui/package.json create mode 100644 tools/eslint-plugin-click-ui/rules/avoid-generic-label.js create mode 100644 tools/eslint-plugin-click-ui/rules/button-requires-label.js create mode 100644 tools/eslint-plugin-click-ui/rules/checkbox-radiogroup-controlled.js create mode 100644 tools/eslint-plugin-click-ui/rules/container-requires-orientation.js create mode 100644 tools/eslint-plugin-click-ui/rules/datepicker-controlled.js create mode 100644 tools/eslint-plugin-click-ui/rules/dialog-controlled-state.js create mode 100644 tools/eslint-plugin-click-ui/rules/form-controlled-components.js create mode 100644 tools/eslint-plugin-click-ui/rules/icon-name-format.js create mode 100644 tools/eslint-plugin-click-ui/rules/logo-name-format.js create mode 100644 tools/eslint-plugin-click-ui/rules/prefer-named-imports.js create mode 100644 tools/eslint-plugin-click-ui/rules/require-css-import.js create mode 100644 tools/eslint-plugin-click-ui/rules/require-provider.js create mode 100644 tools/eslint-plugin-click-ui/rules/select-requires-options.js create mode 100644 tools/eslint-plugin-click-ui/rules/switch-controlled-state.js create mode 100644 tools/eslint-plugin-click-ui/rules/table-structure.js create mode 100644 tools/eslint-plugin-click-ui/rules/valid-button-type.js create mode 100644 tools/eslint-plugin-click-ui/rules/valid-icon-name.js create mode 100644 tools/eslint-plugin-click-ui/rules/valid-icon-size.js create mode 100644 tools/eslint-plugin-click-ui/rules/valid-logo-name.js create mode 100644 tools/eslint-plugin-click-ui/rules/valid-provider-config.js create mode 100644 tools/eslint-plugin-click-ui/rules/valid-spacing-token.js create mode 100644 tools/eslint-plugin-click-ui/rules/valid-theme-name.js create mode 100644 tools/eslint-plugin-click-ui/rules/valid-title-type.js create mode 100644 tools/eslint-plugin-click-ui/test-examples.tsx create mode 100644 tools/eslint-plugin-click-ui/tests/rules.test.js diff --git a/.claude/skills/click-ui.md b/.claude/skills/click-ui.md new file mode 100644 index 0000000..3073c60 --- /dev/null +++ b/.claude/skills/click-ui.md @@ -0,0 +1,741 @@ +--- +name: click-ui +description: Build interfaces using the Click UI design system (@clickhouse/click-ui). Use this skill when working with ClickHouse frontend projects, React components using Click UI, or when the user mentions Click UI components like Button, TextField, Dialog, Table, etc. +globs: ['**/*.tsx', '**/*.jsx', '**/*.ts'] +version: 0.1.0 +alwaysApply: false +--- + +# Click UI Design System - AI Assistant Skill + +## Overview + +Click UI is the official design system and component library for ClickHouse, built with React, TypeScript, and styled-components. This skill provides guidance for effectively using Click UI in development workflows. + +**Official Documentation**: https://clickhouse.design/click-ui +**GitHub Repository**: https://github.com/ClickHouse/click-ui +**NPM Package**: `@clickhouse/click-ui` + +## Critical First Steps + +**ESSENTIAL AI-SPECIFIC RESOURCE**: https://clickhouse.design/click-ui/ai-quick-reference +This page is specifically designed for AI assistants and contains: + +- Complete component props reference +- All 165 icon names and 58 logo names +- Common error patterns to avoid +- State management patterns +- Validation examples +- Type definitions + +**ALWAYS consult the official documentation** at https://clickhouse.design/click-ui when: + +- Learning about a specific component's API +- Understanding current best practices +- Checking for updates or changes +- Reviewing component examples +- Exploring design patterns + +The documentation is the source of truth and may contain updates beyond this skill's knowledge. + +## Installation & Setup + +### Basic Installation + +```bash +npm i @clickhouse/click-ui +# or +yarn add @clickhouse/click-ui +``` + +### Essential Setup Pattern + +Every Click UI application MUST be wrapped in `ClickUIProvider`: + +```typescript +import { ClickUIProvider } from '@clickhouse/click-ui' + +function App() { + return ( + + {/* Your app components */} + + ) +} +``` + +**Note**: Click UI uses styled-components for styling, so no CSS import is required. The styles are injected automatically via JavaScript. + +## Core Architecture Concepts + +### 1. Provider Configuration + +The `ClickUIProvider` accepts two main props: + +```typescript + +``` + +### 2. Theming System + +Click UI uses a robust design token system: + +- **Dark mode**: Default theme, optimized for data visualization +- **Light mode**: Alternative theme +- **Theme switching**: Runtime theme changes supported +- **Design tokens**: Documented at https://clickhouse.design/click-ui/tokens + +### 3. Accessibility First + +All Click UI components are built with accessibility in mind: + +- ARIA labels and roles +- Keyboard navigation +- Screen reader support +- Reference: https://clickhouse.design/click-ui/accessibility + +## Component Categories + +Click UI components organized by category: + +| Category | Components | +| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Layout** | Container, Grid, GridContainer, Panel | +| **Forms** | TextField, TextArea, NumberField, PasswordField, SearchField, Checkbox, RadioGroup, Switch, Select, AutoComplete, DatePicker, DateRangePicker, FileUpload, Label | +| **Display** | Text, Title, Badge, Avatar, BigStat, CodeBlock, ProgressBar, Icon, Logo, Link | +| **Navigation** | Tabs, FileTabs, FullWidthTabs, Accordion, MultiAccordion, VerticalStepper, Pagination | +| **Sidebar** | SidebarNavigationItem, SidebarNavigationTitle, SidebarCollapsibleItem, SidebarCollapsibleTitle | +| **Overlays** | Dialog, Flyout, Popover, Tooltip, HoverCard, ConfirmationDialog | +| **Actions** | Button, ButtonGroup, IconButton, Dropdown, ContextMenu | +| **Feedback** | Alert, Toast, ToastProvider | +| **Data** | Table, Cards, DateDetails | +| **Utilities** | Spacer, Separator | + +### Sidebar Navigation Components + +Click UI provides dedicated sidebar navigation components: + +```typescript +import { SidebarNavigationItem } from '@clickhouse/click-ui' + + setActive('sql')} +/> +``` + +These are preferred over custom styled buttons for navigation menus. + +## Common Usage Patterns + +### Pattern 1: Theme Switching + +```typescript +import { ClickUIProvider, Switch, ThemeName } from '@clickhouse/click-ui' +import { useState } from 'react' + +function App() { + const [theme, setTheme] = useState('dark') + + const toggleTheme = () => { + setTheme(theme === 'dark' ? 'light' : 'dark') + } + + return ( + + + {/* Rest of app */} + + ) +} +``` + +### Pattern 2: Form Components + +```typescript +import { TextField, NumberField, Select, Button, Container } from '@clickhouse/click-ui' +import { useState } from 'react' + +function Form() { + const [username, setUsername] = useState('') + const [age, setAge] = useState('') + const [country, setCountry] = useState('') + + return ( + + + + + Option 1 + Option 2 + +``` + +### When Extending is Necessary + +If you must extend, use styled-components to add theme-aware styles: + +```typescript +import { Container } from '@clickhouse/click-ui' +import styled from 'styled-components' + +// CORRECT - Extend with theme tokens +const SidebarContainer = styled(Container)` + background: ${({ theme }) => theme.global.color.background.default}; + border-right: 1px solid ${({ theme }) => theme.global.color.stroke.default}; +` + +// If flex properties aren't working, you may need to add them explicitly +const FlexContainer = styled(Container)` + display: flex; + flex-direction: column; +` +``` + +### Theme Token Reference + +When extending components, use these theme tokens: + +- `theme.global.color.background.default` - Main background +- `theme.global.color.background.muted` - Muted/secondary background +- `theme.global.color.stroke.default` - Borders +- `theme.click.sidebar.main.color.background.default` - Sidebar background + +## Component Selection Guide + +### For Dropdowns/Selectors + +| Use Case | Component | +| --------------------- | ----------------------------------------------------------------------- | +| Service/item selector | `Select` with `Select.Item` | +| Database picker | `Select` with icon prop | +| Organization switcher | `Select` | +| User menu | `Dropdown` with `Dropdown.Trigger`, `Dropdown.Content`, `Dropdown.Item` | +| Context actions | `ContextMenu` | + +```typescript +// Service selector pattern + + +// User menu pattern + + + + + + Profile + + Dark theme + + + +``` + +### For Promotional/Alert Banners + +| Use Case | Component | +| ----------------------- | -------------------------------- | +| Trial expiration notice | `CardPromotion` | +| Feature announcement | `CardPromotion` | +| Warning banner | `Alert` | +| Info callout | `Panel` with appropriate styling | + +```typescript +// Promotional banner + +``` + +### For Navigation + +| Use Case | Component | +| ------------------------- | --------------------------------------------------- | +| Main nav items | `SidebarNavigationItem` with `type="main"` | +| Sub nav items | `SidebarNavigationItem` | +| Action buttons in sidebar | `Button` with `type="secondary"` and `align="left"` | +| Tabs | `Tabs` with `Tabs.TriggersList` and `Tabs.Trigger` | + +```typescript +// Navigation items + setActiveNav('sql')} +/> + +// Action buttons (like Connect, Ask AI) + + /> {groups.length === 0 ? ( diff --git a/src/components/access/RolesTab.tsx b/src/components/access/RolesTab.tsx index 2e4ed5c..9f7642d 100644 --- a/src/components/access/RolesTab.tsx +++ b/src/components/access/RolesTab.tsx @@ -77,6 +77,7 @@ export function RolesTab({ onCreateRole }: t.RolesTabProps) { + /> {filtered.length === 0 ? ( diff --git a/tools/eslint-plugin-click-ui/.eslintrc.json b/tools/eslint-plugin-click-ui/.eslintrc.json new file mode 100644 index 0000000..bc4b7d2 --- /dev/null +++ b/tools/eslint-plugin-click-ui/.eslintrc.json @@ -0,0 +1,45 @@ +{ + "env": { + "browser": true, + "es2021": true + }, + "extends": [ + "eslint:recommended", + "plugin:react/recommended", + "plugin:@typescript-eslint/recommended", + "plugin:click-ui/recommended" + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaFeatures": { + "jsx": true + }, + "ecmaVersion": "latest", + "sourceType": "module" + }, + "plugins": [ + "react", + "@typescript-eslint", + "click-ui" + ], + "rules": { + "click-ui/require-provider": "error", + "click-ui/require-css-import": "error", + "click-ui/button-requires-label": "error", + "click-ui/icon-name-format": "error", + "click-ui/logo-name-format": "error", + "click-ui/valid-icon-name": "warn", + "click-ui/valid-logo-name": "warn", + "click-ui/container-requires-orientation": "error", + "click-ui/table-structure": "error", + "click-ui/dialog-controlled-state": "error", + "click-ui/form-controlled-components": "error", + "click-ui/prefer-named-imports": "warn", + "click-ui/valid-theme-name": "error", + "click-ui/valid-spacing-token": "warn", + "click-ui/valid-icon-size": "warn", + "click-ui/valid-button-type": "warn", + "click-ui/select-requires-options": "error", + "click-ui/datepicker-controlled": "error" + } +} diff --git a/tools/eslint-plugin-click-ui/ARCHITECTURE.md b/tools/eslint-plugin-click-ui/ARCHITECTURE.md new file mode 100644 index 0000000..d2ef123 --- /dev/null +++ b/tools/eslint-plugin-click-ui/ARCHITECTURE.md @@ -0,0 +1,276 @@ +# Click UI ESLint Plugin - Architecture & Overview + +## Project Structure + +``` +eslint-plugin-click-ui/ +├── index.js # Main plugin entry point +├── package.json # Package configuration +├── README.md # Comprehensive documentation +├── QUICK_START.md # Quick start guide +├── .eslintrc.json # Example configuration +├── rules/ # Individual rule implementations +│ ├── require-provider.js +│ ├── require-css-import.js +│ ├── button-requires-label.js +│ ├── icon-name-format.js +│ ├── logo-name-format.js +│ ├── valid-icon-name.js +│ ├── valid-logo-name.js +│ ├── container-requires-orientation.js +│ ├── table-structure.js +│ ├── dialog-controlled-state.js +│ ├── form-controlled-components.js +│ ├── prefer-named-imports.js +│ ├── valid-theme-name.js +│ ├── valid-spacing-token.js +│ ├── valid-icon-size.js +│ ├── valid-button-type.js +│ ├── select-requires-options.js +│ └── datepicker-controlled.js +├── tests/ # Test suite +│ └── rules.test.js +├── correct-examples.tsx # Examples of correct usage +└── test-examples.tsx # Examples of violations +``` + +## Rule Categories + +### 1. Setup Rules (Critical) +These ensure the basic Click UI setup is correct: +- `require-provider`: Ensures ClickUIProvider wraps the app +- `require-css-import`: Ensures cui.css is imported + +**Impact**: Without these, Click UI won't work at all + +### 2. Component API Rules (Errors) +These catch incorrect component usage that will cause runtime errors: +- `button-requires-label`: Button needs label prop, not children +- `container-requires-orientation`: Container needs orientation +- `table-structure`: Table needs headers/rows, not data/columns +- `dialog-controlled-state`: Dialog needs controlled state +- `form-controlled-components`: Form inputs need value/onChange +- `select-requires-options`: Select needs all required props +- `datepicker-controlled`: DatePicker needs controlled state + +**Impact**: These will cause runtime errors or broken components + +### 3. Naming Convention Rules (Errors) +These enforce correct naming patterns: +- `icon-name-format`: Icons use hyphens (check-in-circle) +- `logo-name-format`: Logos use underscores (digital_ocean) + +**Impact**: Wrong formats won't find the icon/logo assets +**Auto-fixable**: Yes + +### 4. Validation Rules (Warnings) +These validate against known valid values: +- `valid-icon-name`: Checks against 165 valid icon names +- `valid-logo-name`: Checks against 58 valid logo names +- `valid-theme-name`: Validates theme values +- `valid-spacing-token`: Validates spacing tokens +- `valid-icon-size`: Validates icon sizes +- `valid-button-type`: Validates button types + +**Impact**: Invalid values won't render correctly +**Provides**: Helpful suggestions for typos + +### 5. Best Practice Rules (Warnings) +These encourage good patterns: +- `prefer-named-imports`: Use named imports for tree-shaking + +**Impact**: Performance and bundle size + +## Key Design Decisions + +### 1. Two Config Presets +- **recommended**: Balanced (errors for critical, warnings for suggestions) +- **strict**: All rules as errors for maximum enforcement + +### 2. Auto-fixable Where Possible +Rules that can be automatically fixed: +- `button-requires-label`: Converts children to label +- `icon-name-format`: Converts to hyphen format +- `logo-name-format`: Converts to underscore format + +### 3. Smart Detection +- Only checks root files (App.tsx, _app.tsx) for provider/CSS +- Validates icon/logo names against actual library +- Suggests similar names using Levenshtein distance + +### 4. TypeScript-Friendly +- Works with .tsx files +- Understands JSX expressions +- Validates against TypeScript types + +## Common Patterns Detected + +### Pattern 1: Missing Setup +```tsx +// ❌ Detected +function App() { + return + +// ✅ Fixed to + + +// ✅ Correct + + +// ✅ Good +