diff --git a/skills/README.md b/skills/README.md new file mode 100644 index 0000000..4525540 --- /dev/null +++ b/skills/README.md @@ -0,0 +1,129 @@ +# LLM Agent Skills for Ignite UI for React + +This directory contains skills for GitHub Copilot and other LLM agents to help developers use **Ignite UI for React** effectively in their applications. + +## What are Skills? + +Skills are structured instructions that help AI agents understand and execute common tasks consistently. Each skill is a self-contained guide that provides step-by-step instructions, code examples, and best practices — all specific to React and the `igniteui-react` family of packages. + +## Available Skills + +| Skill | Description | Use When | +| --- | --- | --- | +| [igniteui-react-choose-components](./igniteui-react-choose-components/SKILL.md) | Identify the right React components (`Igr*`) for a UI pattern and navigate to official docs/demos | Deciding which components to use | +| [igniteui-react-use-components](./igniteui-react-use-components/SKILL.md) | Install, import, and use components in a React application — JSX patterns, events, refs, forms | Setting up and using components in React | +| [igniteui-react-customize-theme](./igniteui-react-customize-theme/SKILL.md) | Customize styling using CSS custom properties, Sass, and the theming system in a React context | Applying custom brand colors/styles | +| [igniteui-react-optimize-bundle-size](./igniteui-react-optimize-bundle-size/SKILL.md) | Reduce bundle size with granular imports, tree-shaking, and lazy loading | Optimizing production performance | + +## How to Use + +When working with an AI agent like GitHub Copilot, reference skills by name or ask questions naturally: + +### Natural Questions + +- "How do I add a data grid to my React app?" +- "What Ignite UI component should I use for a date picker?" +- "Help me customize the button colors to match my brand" +- "My bundle size is too large, how can I reduce it?" +- "How do I handle events on IgrCombo?" + +### Direct Skill Reference + +- "Follow the igniteui-react-use-components skill for setting up my project" +- "Use the igniteui-react-customize-theme skill to help me style components" +- "Apply the igniteui-react-optimize-bundle-size skill to reduce my bundle" + +## Skill Structure + +Each skill contains: + +- **Example Usage**: Common questions or scenarios +- **When to Use**: Situations where the skill applies +- **Related Skills**: Other relevant skills to explore +- **Step-by-Step Instructions**: Detailed guidance with code examples +- **Common Issues & Solutions**: Troubleshooting guidance +- **Best Practices**: Recommended approaches +- **Additional Resources**: Further reading and documentation + +## Editor / Agent Setup + +### GitHub Copilot + +Add a `.github/copilot-instructions.md` file to your project root: + +```markdown +## Ignite UI for React + +This project uses Ignite UI for React. When answering questions about UI components, +refer to the skills in the `skills/` directory (or the `node_modules/igniteui-react/skills/` directory if using the npm package): + +- **Choosing components**: skills/igniteui-react-choose-components/SKILL.md +- **Using components in React**: skills/igniteui-react-use-components/SKILL.md +- **Theming & styling**: skills/igniteui-react-customize-theme/SKILL.md +- **Bundle optimization**: skills/igniteui-react-optimize-bundle-size/SKILL.md + +All components use the `Igr` prefix (e.g. `IgrButton`, `IgrGrid`). +Packages: `igniteui-react`, `igniteui-react-grids`, `igniteui-react-charts`, `igniteui-react-maps`, `igniteui-react-gauges`. +``` + +### Cursor + +Create or edit `.cursorrules` in your project root: + +``` +This project uses Ignite UI for React. +When working with UI components, consult the skills in skills/ (or node_modules/igniteui-react/skills/): + +- skills/igniteui-react-choose-components/SKILL.md — pick the right component +- skills/igniteui-react-use-components/SKILL.md — React usage patterns +- skills/igniteui-react-customize-theme/SKILL.md — theming and styling +- skills/igniteui-react-optimize-bundle-size/SKILL.md — bundle optimization + +Components use the Igr prefix (IgrButton, IgrGrid, IgrCombo, etc.). +Packages: igniteui-react, igniteui-react-grids, igniteui-react-charts, igniteui-react-maps, igniteui-react-gauges. +``` + +### Claude Code / Claude Desktop + +Add to your `CLAUDE.md` project instructions: + +```markdown +## Ignite UI for React + +This project uses Ignite UI for React. Refer to these skills for guidance: + +- skills/igniteui-react-choose-components/SKILL.md +- skills/igniteui-react-use-components/SKILL.md +- skills/igniteui-react-customize-theme/SKILL.md +- skills/igniteui-react-optimize-bundle-size/SKILL.md + +All React wrapper components use the `Igr` prefix (e.g. `IgrButton`, `IgrGrid`). +Import from: `igniteui-react`, `igniteui-react-grids`, `igniteui-react-charts`, `igniteui-react-maps`, `igniteui-react-gauges`. +``` + +### VS Code / JetBrains — Manual Attachment + +You can also attach individual skill files to your AI chat context manually: + +1. Open the AI chat panel (Copilot Chat, Cody, etc.) +2. Use the "Attach file" or "Add context" action +3. Select the relevant `SKILL.md` file from the `skills/` directory + +## Contributing + +If you identify gaps in the skills or have suggestions for improvements: + +1. [Open an issue](https://github.com/IgniteUI/igniteui-react/issues) describing the improvement +2. Submit a pull request with the proposed changes +3. Follow the skill format and structure of existing skills + +## Additional Resources + +- [Ignite UI for React Documentation](https://www.infragistics.com/reactsite/components/general-getting-started) +- [React Examples Repository](https://github.com/IgniteUI/igniteui-react-examples) +- [npm: igniteui-react](https://www.npmjs.com/package/igniteui-react) +- [GitHub Repository](https://github.com/IgniteUI/igniteui-react) + +## License + +These skills are provided under the same license as the Ignite UI for React library. See [LICENSE](../LICENSE) for details. diff --git a/skills/igniteui-react-choose-components/SKILL.md b/skills/igniteui-react-choose-components/SKILL.md new file mode 100644 index 0000000..2c4fe9f --- /dev/null +++ b/skills/igniteui-react-choose-components/SKILL.md @@ -0,0 +1,353 @@ +--- +name: igniteui-react-choose-components +description: This skill identifies and selects the right Ignite UI for React components for any UI requirement and should be used when mapping UI needs to components, exploring available components, or finding official docs and API references +user-invocable: true +--- + +# Choose the Right Ignite UI for React Components + +This skill helps AI agents and developers identify the best Ignite UI for React components for any UI requirement, then provides direct links to official documentation, usage examples, and API references. + +## Example Usage + +- "What component should I use to display a list of items with actions?" +- "I need a date picker for a booking form in React" +- "How do I show file upload progress?" +- "What's the best component for a navigation sidebar?" +- "I need a searchable dropdown with multi-select" +- "Build a dashboard layout with cards and a data grid" +- "I want to display hierarchical/tree data" +- "Show me components for notifications and alerts" + +## Related Skills + +- [igniteui-react-use-components](../igniteui-react-use-components/SKILL.md) — Install, import, and use chosen components in React +- [igniteui-react-customize-theme](../igniteui-react-customize-theme/SKILL.md) — Style and theme the components you select +- [igniteui-react-optimize-bundle-size](../igniteui-react-optimize-bundle-size/SKILL.md) — Import only the components you actually use + +## When to Use + +- Agent or user needs to decide which component fits a UI requirement +- User describes a UI pattern and needs a matching component name +- User wants to explore what components are available +- User needs links to official docs or live examples for a specific component +- Starting a new feature and mapping requirements to components +- Reworking existing UI with new or different component requirements + +--- + +## Available Packages + +Ignite UI for React is distributed across several packages depending on your needs: + +| Package | License | Install | Best For | +|---|---|---|---| +| [`igniteui-react`](https://www.npmjs.com/package/igniteui-react) | MIT | `npm install igniteui-react` | General UI components (inputs, layouts, notifications, scheduling) | +| [`igniteui-grid-lite`](https://www.npmjs.com/package/igniteui-grid-lite) | MIT | `npm install igniteui-grid-lite` | Lightweight grid (Grid Lite) — web component, requires `IgcGridLite.register()` | +| [`igniteui-react-grids`](https://www.npmjs.com/package/igniteui-react-grids) | Commercial | `npm install igniteui-react-grids` (trial) | Advanced data grids (Data Grid, Tree Grid, Hierarchical Grid, Pivot Grid) | +| [`igniteui-react-charts`](https://www.npmjs.com/package/igniteui-react-charts) | Commercial | `npm install igniteui-react-charts` (trial) | Charts (Category, Financial, Pie, Scatter, etc.) | +| [`igniteui-react-maps`](https://www.npmjs.com/package/igniteui-react-maps) | Commercial | `npm install igniteui-react-maps` (trial) | Geographic maps | +| [`igniteui-react-gauges`](https://www.npmjs.com/package/igniteui-react-gauges) | Commercial | `npm install igniteui-react-gauges` (trial) | Radial and linear gauges | +| [`reveal-sdk-wrappers-react`](https://www.npmjs.com/package/reveal-sdk-wrappers-react) | Commercial | `npm install reveal-sdk-wrappers-react` | Embedded BI dashboards (Reveal SDK) | + +> **Note:** The lightweight Grid Lite (`IgcGridLite` from `igniteui-grid-lite`) is a **web component** — not a React wrapper. It uses the `Igc` prefix and requires `IgcGridLite.register()` before use, plus a sized container. See the [use-components skill](../igniteui-react-use-components/SKILL.md) for setup details. + +--- + +## Component Catalogue by UI Pattern + +Use the tables below to map a UI need to the right React component. All components use the **`Igr`** prefix. + +### Inputs & Forms + +| UI Need | Component | Import | Docs | +|---|---|---|---| +| Text field / text input | `IgrInput` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/inputs/input) | +| Multi-line text | `IgrTextarea` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/inputs/text-area) | +| Checkbox | `IgrCheckbox` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/inputs/checkbox) | +| On/off toggle | `IgrSwitch` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/inputs/switch) | +| Single choice from a list | `IgrRadio` / `IgrRadioGroup` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/inputs/radio) | +| Star / score rating | `IgrRating` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/inputs/rating) | +| Formatted / masked text input | `IgrMaskInput` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/inputs/input) | +| Date and time input | `IgrDateTimeInput` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/inputs/date-time-input) | +| File upload | `IgrFileInput` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/inputs/file-input) | +| Simple dropdown / select | `IgrSelect` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/inputs/select) | +| Searchable dropdown, single or multi-select | `IgrCombo` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/inputs/combo/overview) | +| Grouped toggle buttons | `IgrButtonGroup` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/inputs/button-group) | +| Range / numeric slider | `IgrSlider` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/inputs/slider) | +| Range slider (two handles) | `IgrRangeSlider` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/inputs/slider) | + +### Buttons & Actions + +| UI Need | Component | Import | Docs | +|---|---|---|---| +| Standard clickable button | `IgrButton` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/inputs/button) | +| Icon-only button | `IgrIconButton` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/inputs/icon-button) | +| Click ripple effect | `IgrRipple` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/inputs/ripple) | +| Removable tag / filter chip | `IgrChip` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/inputs/chip) | + +### Scheduling & Date Pickers + +| UI Need | Component | Import | Docs | +|---|---|---|---| +| Full calendar view | `IgrCalendar` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/scheduling/calendar) | +| Date picker (popup calendar) | `IgrDatepicker` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/scheduling/date-picker) | +| Date range selection | `IgrDateRangePicker` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/scheduling/date-range-picker) | + +### Notifications & Feedback + +| UI Need | Component | Import | Docs | +|---|---|---|---| +| Brief auto-dismiss notification | `IgrToast` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/notifications/toast) | +| Actionable dismissible notification bar | `IgrSnackbar` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/notifications/snackbar) | +| Persistent status banner | `IgrBanner` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/notifications/banner) | +| Modal confirmation or content dialog | `IgrDialog` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/notifications/dialog) | +| Tooltip on hover | `IgrTooltip` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/inputs/tooltip) | +| Small count / status indicator | `IgrBadge` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/inputs/badge) | + +### Progress Indicators + +| UI Need | Component | Import | Docs | +|---|---|---|---| +| Horizontal progress bar | `IgrLinearProgress` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/inputs/linear-progress) | +| Circular / spinner progress | `IgrCircularProgress` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/inputs/circular-progress) | + +### Layouts & Containers + +| UI Need | Component | Import | Docs | +|---|---|---|---| +| Generic content card | `IgrCard` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/layouts/card) | +| User avatar / profile image | `IgrAvatar` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/layouts/avatar) | +| Icon display | `IgrIcon` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/layouts/icon) | +| Horizontal or vertical divider | `IgrDivider` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/layouts/divider) | +| Collapsible section | `IgrExpansionPanel` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/layouts/expansion-panel) | +| Multiple collapsible sections | `IgrAccordion` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/layouts/accordion) | +| Tabbed content panels (with inline content) | `IgrTabs` + `IgrTabPanel` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/layouts/tabs) | +| Image / content slideshow | `IgrCarousel` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/layouts/carousel) | +| Multi-step wizard / onboarding flow | `IgrStepper` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/layouts/stepper) | +| Resizable, draggable dashboard tiles | `IgrTileManager` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/layouts/tile-manager) | + +### Navigation + +| UI Need | Component | Import | Docs | +|---|---|---|---| +| Top application bar / toolbar | `IgrNavbar` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/menus/navbar) | +| Side navigation drawer | `IgrNavDrawer` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/menus/navigation-drawer) | +| Tab-based navigation (with router) | `IgrTabs` (no `IgrTabPanel`) | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/layouts/tabs) | +| Context menu / actions dropdown | `IgrDropdown` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/inputs/dropdown) | + +### Lists & Data Display + +| UI Need | Component | Import | Docs | +|---|---|---|---| +| Simple scrollable list | `IgrList` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/grids/list) | +| Hierarchical / tree data | `IgrTree` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/grids/tree) | +| Tabular data (MIT, lightweight) | `IgcGridLite` | `igniteui-grid-lite` (requires `.register()`) | [Docs](https://www.infragistics.com/reactsite/components/grid-lite/overview) | +| Full-featured tabular data grid | `IgrDataGrid` | `igniteui-react-grids` | [Docs](https://www.infragistics.com/reactsite/components/grids/grid/overview) | +| Nested / master-detail grid | `IgrHierarchicalGrid` | `igniteui-react-grids` | [Docs](https://www.infragistics.com/reactsite/components/grids/hierarchical-grid/overview) | +| Parent-child relational tree grid | `IgrTreeGrid` | `igniteui-react-grids` | [Docs](https://www.infragistics.com/reactsite/components/grids/tree-grid/overview) | +| Cross-tabulation / BI pivot table | `IgrPivotGrid` | `igniteui-react-grids` | [Docs](https://www.infragistics.com/reactsite/components/grids/pivot-grid/overview) | + +### Charts & Data Visualization + +> **⚠️ IMPORTANT:** Chart, gauge, and map components require **explicit module registration** and a **sized container**. Import the `*Module` class and call `.register()` at module level, and wrap the component in a container with explicit `min-width`/`min-height` or `flex-grow`. See the [use-components skill](../igniteui-react-use-components/SKILL.md) for details. + +| UI Need | Component | Module Registration | Import | Docs | +|---|---|---|---|---| +| Category / bar / line chart | `IgrCategoryChart` | `IgrCategoryChartModule.register()` | `igniteui-react-charts` | [Docs](https://www.infragistics.com/reactsite/components/charts/chart-overview) | +| Pie / doughnut chart | `IgrPieChart` | `IgrPieChartModule.register()` | `igniteui-react-charts` | [Docs](https://www.infragistics.com/reactsite/components/charts/chart-overview) | +| Financial / stock chart | `IgrFinancialChart` | `IgrFinancialChartModule.register()` | `igniteui-react-charts` | [Docs](https://www.infragistics.com/reactsite/components/charts/chart-overview) | +| Radial gauge | `IgrRadialGauge` | `IgrRadialGaugeModule.register()` | `igniteui-react-gauges` | [Docs](https://www.infragistics.com/reactsite/components/gauges/radial-gauge) | +| Linear gauge | `IgrLinearGauge` | `IgrLinearGaugeModule.register()` | `igniteui-react-gauges` | [Docs](https://www.infragistics.com/reactsite/components/gauges/linear-gauge) | +| Geographic map | `IgrGeographicMap` | `IgrGeographicMapModule.register()` | `igniteui-react-maps` | [Docs](https://www.infragistics.com/reactsite/components/maps/geographic-map) | + +### Conversational / AI + +| UI Need | Component | Import | Docs | +|---|---|---|---| +| Chat / AI assistant message thread | `IgrChat` | `igniteui-react` | [Docs](https://www.infragistics.com/reactsite/components/interactivity/chat) | + +### Embedded Analytics / BI Dashboards (Reveal SDK) + +| UI Need | Component | Import | Docs | +|---|---|---|---| +| Embedded BI dashboard viewer | `RvRevealView` | `reveal-sdk-wrappers-react` | [Docs](https://help.revealbi.io/web/getting-started-react/) | + +> **Note:** Reveal SDK is a companion product for embedding interactive dashboards and data visualizations. It uses separate packages (`reveal-sdk-wrappers-react`, `reveal-sdk-wrappers`) and requires a backend Reveal server URL. See the [use-components skill](../igniteui-react-use-components/SKILL.md) for setup instructions and the [customize-theme skill](../igniteui-react-customize-theme/SKILL.md) for syncing Reveal's theme with Ignite UI theming tokens. + +--- + +## Step-by-Step: Choosing Components for a UI + +Follow these steps when an agent or user describes a UI requirement: + +### Step 1 — Identify UI patterns + +Break the described UI into atomic patterns. Examples: +- "A booking form" → date input, text inputs, button, maybe a calendar picker +- "An admin dashboard" → navbar, nav drawer, cards, data grid, charts +- "A notification center" → snackbar or toast, badge, list +- "A settings page" → tabs or accordion, switch, input, select, button + +### Step 2 — Map patterns to components + +Use the **Component Catalogue** tables above to find matching components. When in doubt: + +| If the user needs… | Prefer… | Over… | +|---|---|---| +| Simple static list | `IgrList` | Data Grid | +| Basic dropdown | `IgrSelect` | `IgrCombo` | +| Searchable or multi-select dropdown | `IgrCombo` | `IgrSelect` | +| Tabular data with basic display | `IgcGridLite` (grid-lite) | `IgrDataGrid` (commercial) | +| Tabular data, advanced features needed | `IgrDataGrid` | `IgcGridLite` (grid-lite) | +| Single dismissible message | `IgrToast` | `IgrSnackbar` | +| Message requiring user action | `IgrSnackbar` | `IgrToast` | +| Collapsible single section | `IgrExpansionPanel` | `IgrAccordion` | +| Multiple collapsible sections | `IgrAccordion` | `IgrExpansionPanel` | +| Stepped wizard UI | `IgrStepper` | `IgrTabs` | +| Content tabs / view switching (inline content) | `IgrTabs` + `IgrTabPanel` | `IgrStepper` | +| Tab-based navigation (with React Router) | `IgrTabs` (no `IgrTabPanel`) | `IgrTabs` + `IgrTabPanel` | + +### Step 3 — Check the package + +Confirm which package provides the component: + +- **MIT components** (inputs, layout, notifications, scheduling, chat) → `igniteui-react` +- **Lightweight grid** (Grid Lite) → `igniteui-grid-lite` *(MIT, web component — requires `IgcGridLite.register()`)* +- **Advanced grids** (Data Grid, Tree Grid, Hierarchical Grid, Pivot Grid) → `igniteui-react-grids` *(commercial)* +- **Charts** → `igniteui-react-charts` *(commercial)* +- **Maps** → `igniteui-react-maps` *(commercial)* +- **Gauges** → `igniteui-react-gauges` *(commercial)* + +### Step 4 — Link to official resources + +Always direct the user to the official documentation linked in the tables above. Key entry points: + +- **Getting started**: [Ignite UI for React Docs](https://www.infragistics.com/reactsite/components/general-getting-started) +- **React examples**: [https://github.com/IgniteUI/igniteui-react-examples](https://github.com/IgniteUI/igniteui-react-examples) +- **npm package**: [https://www.npmjs.com/package/igniteui-react](https://www.npmjs.com/package/igniteui-react) +- **GitHub repository**: [https://github.com/IgniteUI/igniteui-react](https://github.com/IgniteUI/igniteui-react) + +### Step 5 — Provide a starter code snippet + +Once components are identified, give the user a minimal working React snippet. Example for an admin dashboard shell: + +```tsx +import { IgrNavbar, IgrNavDrawer, IgrNavDrawerItem, IgrCard, IgrCardHeader, IgrCardContent, IgrIcon } from 'igniteui-react'; +import 'igniteui-webcomponents/themes/light/bootstrap.css'; + +function Dashboard() { + return ( + <> + +

My Dashboard

+
+ + + + 🏠 + Home + + + ⚙️ + Settings + + + +
+ + +

Summary

+
+ Dashboard content here +
+
+ + ); +} +``` + +> **Note:** No `defineComponents()` call is needed — React wrappers handle component registration automatically when you import them. + +--- + +## Common UI Scenarios → Recommended Component Sets + +### Login / Authentication Form + +- `IgrInput` — email and password fields +- `IgrCheckbox` — "Remember me" +- `IgrButton` — submit +- `IgrSnackbar` — error/success feedback + +### User Profile / Settings Page + +- `IgrAvatar` — profile picture +- `IgrTabs` — section navigation (Profile, Security, Notifications) +- `IgrInput` / `IgrTextarea` — editable fields +- `IgrSwitch` — feature toggles +- `IgrSelect` — preference dropdowns +- `IgrButton` — save/cancel actions + +### Data Table / Admin List View + +- `IgrInput` — search bar +- `IgrCombo` — filter dropdowns +- `IgcGridLite` (grid-lite) or `IgrDataGrid` — tabular data +- `IgrButton` / `IgrIconButton` — actions +- `IgrDialog` — confirm delete modal +- `IgrBadge` — status indicators + +### Booking / Reservation Form + +- `IgrDateRangePicker` — check-in / check-out +- `IgrInput` — guest details +- `IgrSelect` — room type +- `IgrStepper` — multi-step booking flow +- `IgrButton` — next / confirm +- `IgrToast` — booking confirmation + +### Analytics / Reporting Dashboard + +- `IgrNavbar` — top bar +- `IgrNavDrawer` — side navigation +- `IgrCard` — KPI summary cards +- `IgrTabs` or `IgrTileManager` — section layout +- `IgrDataGrid` or `IgrPivotGrid` — detailed data tables +- `IgrCategoryChart` — charts (from `igniteui-react-charts`) +- `IgrLinearProgress` / `IgrCircularProgress` — loading indicators + +### Master-Detail with Tab Navigation (React Router) + +- `IgrNavbar` — top bar +- `IgrTabs` — **navigation only** (no `IgrTabPanel`); each `IgrTab` triggers a route change +- React Router `` — renders the routed child view below the tabs +- Active tab synced to the current route via `selected` prop + +> **⚠️ Important — Tabs for navigation vs. tabs for content:** +> - **Tabs as content panels** (`IgrTabs` + `IgrTabPanel`): Content is rendered inside tab panels. Use when the tab content is inline and does not require routing. +> - **Tabs as navigation** (`IgrTabs` only, no `IgrTabPanel`): Tabs act as route links. The routing outlet (``) renders the content. **Do NOT add `IgrTabPanel` in this case** — it will create an empty panel that fills the view. See the [use-components skill](../igniteui-react-use-components/SKILL.md) for a full React Router example. + +--- + +## Searching the Documentation + +If you are unsure about a component or need more information: + +1. **Browse the docs** at `https://www.infragistics.com/reactsite/components/` — the left sidebar groups components by category +2. **Use the naming convention**: React components use the `Igr` prefix followed by PascalCase name (e.g., `IgrDateRangePicker`, `IgrNavDrawer`). The docs URL typically uses kebab-case: `components/scheduling/date-range-picker` +3. **Check the examples repo** at [igniteui-react-examples](https://github.com/IgniteUI/igniteui-react-examples) for working sample applications + +## Best Practices + +1. **Start with the MIT package** (`igniteui-react`) — it covers most common UI needs +2. **Only add commercial packages** (`igniteui-react-grids`, `igniteui-react-charts`, etc.) when you need their specific capabilities +3. **Combine components** to build complex UIs — e.g., `IgrTabs` + `IgrDataGrid` for a multi-view data explorer +4. **Always import the theme CSS** — components need a theme to render correctly (see [igniteui-react-customize-theme](../igniteui-react-customize-theme/SKILL.md)) + +## Additional Resources + +- [Ignite UI for React Documentation](https://www.infragistics.com/reactsite/components/general-getting-started) +- [React Examples Repository](https://github.com/IgniteUI/igniteui-react-examples) +- [npm: igniteui-react](https://www.npmjs.com/package/igniteui-react) +- [GitHub Repository](https://github.com/IgniteUI/igniteui-react) diff --git a/skills/igniteui-react-customize-theme/SKILL.md b/skills/igniteui-react-customize-theme/SKILL.md new file mode 100644 index 0000000..079b83e --- /dev/null +++ b/skills/igniteui-react-customize-theme/SKILL.md @@ -0,0 +1,183 @@ +--- +name: igniteui-react-customize-theme +description: This skill customizes Ignite UI for React component styling using CSS custom properties, Sass, and the full theming system and should be used when applying brand colors, dark mode, component-level overrides, or scoped themes in a React application +user-invocable: true +--- + +# Ignite UI for React — Theming Skill + +## Description + +This skill teaches AI agents how to theme Ignite UI for React applications. Two approaches are supported: + +- **CSS custom properties** — works in any project without additional build tooling +- **Sass** — available when the project has Sass configured; provides the full palette/typography/elevation API + +The skill also covers component-level theming, layout controls (spacing, sizing, roundness), and how to use the **Ignite UI Theming MCP server** for AI-assisted code generation — all in a React application context. + +## Example Usage + +- "How do I change the primary color in my Ignite UI React app?" +- "Apply a dark theme to my React app" +- "Customize the grid header colors" +- "How do I scope a theme to a specific section of my React app?" +- "Set up Material Design theming for Ignite UI components" + +## Prerequisites + +- A React project with `igniteui-react` installed +- A theme CSS file imported in your entry point (see [igniteui-react-use-components](../igniteui-react-use-components/SKILL.md)) +- **Optional**: Sass configured in the project (enables the Sass-based theming API) +- **Optional**: The **Ignite UI Theming MCP server** (`igniteui-theming`) for AI-assisted code generation + +## Related Skills + +- [igniteui-react-choose-components](../igniteui-react-choose-components/SKILL.md) — Choose the right components first +- [igniteui-react-use-components](../igniteui-react-use-components/SKILL.md) — Set up your React project +- [igniteui-react-optimize-bundle-size](../igniteui-react-optimize-bundle-size/SKILL.md) — Optimize after theming + +## When to Use + +- Applying custom brand colors or a dark theme to an Ignite UI React app +- Overriding individual component styles (e.g., grid header color, button appearance) +- Switching between light and dark mode in a React app +- Scoping different themes to different sections of a React app +- Setting up the Ignite UI Theming MCP server for AI-assisted theming + +--- + +## Content Guide + +This skill is organized into focused sections. Refer to the appropriate file for detailed instructions: + +| Topic | File | When to Use | +|---|---|---| +| CSS Theming | [CSS-THEMING.md](./reference/CSS-THEMING.md) | Pre-built themes, CSS custom properties, scoped overrides, layout controls, light/dark switching | +| Sass Theming | [SASS-THEMING.md](./reference/SASS-THEMING.md) | Sass-based theming with palette(), component theme functions | +| MCP Server | [MCP-SERVER.md](./reference/MCP-SERVER.md) | AI-assisted theming code generation | +| Reveal Theme Sync | [REVEAL-THEME.md](./reference/REVEAL-THEME.md) | Syncing Reveal SDK dashboards with Ignite UI theme | +| Troubleshooting | [TROUBLESHOOTING.md](./reference/TROUBLESHOOTING.md) | Common issues and solutions | + +--- + +## Quick Start + +### 1. Import a Pre-built Theme (REQUIRED) + +```tsx +// main.tsx +import 'igniteui-webcomponents/themes/light/bootstrap.css'; +``` + +**For grids**, also import: + +```tsx +import 'igniteui-webcomponents-grids/grids/themes/light/bootstrap.css'; +``` + +### 2. Override with CSS Custom Properties + +```css +/* src/index.css */ +:root { + --ig-primary-h: 211deg; + --ig-primary-s: 100%; + --ig-primary-l: 50%; +} +``` + +```tsx +// main.tsx +import 'igniteui-webcomponents/themes/light/bootstrap.css'; // Theme first +import './index.css'; // Overrides second +``` + +--- + +## Theming Architecture + +The Ignite UI theming system is built on four pillars: + +| Concept | Purpose | +|---|---| +| **Palette** | Color system with primary, secondary, surface, gray, info, success, warn, error families | +| **Typography** | Font family, type scale (h1–h6, subtitle, body, button, caption, overline) | +| **Elevations** | Box-shadow levels 0–24 for visual depth | +| **Schema** | Per-component recipes mapping palette colors to component tokens | + +### Design Systems + +- **Material** (default), **Bootstrap**, **Fluent**, **Indigo** +- Each has light and dark variants + +--- + +## Key Concepts + +### CSS Custom Properties + +Override tokens in your CSS: + +```css +:root { --ig-primary-h: 211deg; } +.admin-panel { --ig-primary-h: 260deg; } +``` + +### Component-Level Theming + +Target web component tag names in CSS: + +```css +igc-button { --ig-button-foreground: var(--ig-secondary-500); } +``` + +### CSS `::part()` Selectors + +```css +igc-input::part(input) { font-size: 1.1rem; } +``` + +### Layout Controls + +```css +:root { + --ig-size: 2; /* 1=small, 2=medium, 3=large */ + --ig-spacing: 1; /* 0.5=compact, 1=default, 2=spacious */ + --ig-radius-factor: 1; /* 0=square, 1=max radius */ +} +``` + +### Light/Dark Switching + +See [CSS-THEMING.md](./reference/CSS-THEMING.md) for approaches: class toggle, media query, or stylesheet swap. + +--- + +## Best Practices + +1. **Import theme CSS first**, then your custom overrides +2. **Use palette tokens** (`var(--ig-primary-500)`) for all colors — never hardcode hex values +3. **Use CSS custom properties on `:root`** for global theme adjustments +4. **Scope overrides with CSS classes** for different sections +5. **Use `::part()` selectors** to style shadow DOM internals +6. **In CSS selectors, use web component tag names** (`igc-button`), not React names (`IgrButton`) +7. **Test both light and dark themes** +8. **Use the MCP server** for AI-assisted theme generation when available + +## Key Rules + +1. **Never overwrite existing files directly** — propose theme code as an update for user review +2. **Always call `detect_platform` first** when using MCP tools +3. **Always call `get_component_design_tokens` before `create_component_theme`** +4. **Palette shades**: 50 = lightest, 900 = darkest +5. **Surface color must match variant** — light color for `light`, dark for `dark` +6. **Sass**: Use `@use 'igniteui-theming'` — not `igniteui-angular/theming` +7. **Sass**: Component themes use `@include tokens($theme)` inside a selector +8. **Never hardcode colors after palette generation** + +## Additional Resources + +- [Ignite UI for React — Theming Documentation](https://www.infragistics.com/reactsite/components/general-getting-started) +- [igniteui-theming npm package](https://www.npmjs.com/package/igniteui-theming) +- [CSS Custom Properties on MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties) +- [CSS ::part() on MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/::part) diff --git a/skills/igniteui-react-customize-theme/reference/CSS-THEMING.md b/skills/igniteui-react-customize-theme/reference/CSS-THEMING.md new file mode 100644 index 0000000..a1fbef6 --- /dev/null +++ b/skills/igniteui-react-customize-theme/reference/CSS-THEMING.md @@ -0,0 +1,265 @@ +# CSS Theming + +This guide covers theming Ignite UI for React using CSS custom properties — works in any project without additional build tooling. + +## Pre-built Themes + +Import a pre-built CSS file in your React entry point: + +```tsx +// main.tsx or index.tsx +import 'igniteui-webcomponents/themes/light/bootstrap.css'; +``` + +> **CRITICAL:** Theme CSS imports are **required** for components to render correctly. + +**For grids**, you **must also** import the grid theme CSS: + +```tsx +import 'igniteui-webcomponents/themes/light/bootstrap.css'; +import 'igniteui-webcomponents-grids/grids/themes/light/bootstrap.css'; +``` + +### Available Pre-built CSS Files + +| Import path | Theme | +|---|---| +| `igniteui-webcomponents/themes/light/bootstrap.css` | Bootstrap Light | +| `igniteui-webcomponents/themes/dark/bootstrap.css` | Bootstrap Dark | +| `igniteui-webcomponents/themes/light/material.css` | Material Light | +| `igniteui-webcomponents/themes/dark/material.css` | Material Dark | +| `igniteui-webcomponents/themes/light/fluent.css` | Fluent Light | +| `igniteui-webcomponents/themes/dark/fluent.css` | Fluent Dark | +| `igniteui-webcomponents/themes/light/indigo.css` | Indigo Light | +| `igniteui-webcomponents/themes/dark/indigo.css` | Indigo Dark | + +Grid theme CSS files follow the same pattern under `igniteui-webcomponents-grids/grids/themes/`. + +### Next.js + +In Next.js, import the theme CSS in each client component file or in a shared root layout: + +```tsx +// app/layout.tsx +import 'igniteui-webcomponents/themes/light/bootstrap.css'; +import 'igniteui-webcomponents-grids/grids/themes/light/bootstrap.css'; + +export default function RootLayout({ children }: { children: React.ReactNode }) { + return ( + + {children} + + ); +} +``` + +## Custom Theme via CSS Custom Properties + +After importing a pre-built theme, override individual design tokens with CSS custom properties. + +### Global Overrides (in your CSS file) + +```css +/* src/index.css */ +:root { + --ig-primary-h: 211deg; + --ig-primary-s: 100%; + --ig-primary-l: 50%; + + --ig-secondary-h: 33deg; + --ig-secondary-s: 100%; + --ig-secondary-l: 50%; +} +``` + +Import it in your entry point: + +```tsx +// main.tsx +import 'igniteui-webcomponents/themes/light/bootstrap.css'; // Theme first +import './index.css'; // Overrides — must come after the theme import +``` + +### Scoped Overrides + +Use a CSS class to scope theme overrides to a specific container: + +```css +/* src/AdminPanel.css */ +.admin-panel { + --ig-primary-h: 260deg; + --ig-primary-s: 60%; + --ig-primary-l: 45%; +} +``` + +```tsx +// AdminPanel.tsx +import './AdminPanel.css'; +import { IgrButton, IgrInput } from 'igniteui-react'; + +function AdminPanel() { + return ( +
+ + Save +
+ ); +} +``` + +### CSS Modules + +```css +/* AdminPanel.module.css */ +.panel { + --ig-primary-h: 260deg; + --ig-primary-s: 60%; + --ig-primary-l: 45%; +} +``` + +```tsx +import styles from './AdminPanel.module.css'; +import { IgrButton } from 'igniteui-react'; + +function AdminPanel() { + return ( +
+ Save +
+ ); +} +``` + +### Inline Styles on a Wrapper + +For truly dynamic one-off overrides: + +```tsx +
+ Custom Color Button +
+``` + +> **Note:** TypeScript requires the `as React.CSSProperties` cast. Prefer CSS classes when possible. + +## Component-Level Theming + +Override individual component appearance using CSS custom properties. + +```css +/* Target the Ignite UI web component tag name */ +igc-avatar { + --ig-avatar-background: var(--ig-primary-500); + --ig-avatar-color: var(--ig-primary-500-contrast); +} + +igc-button { + --ig-button-foreground: var(--ig-secondary-500); +} +``` + +> **IMPORTANT — No Hardcoded Colors** +> +> ✅ **Right:** `--ig-avatar-background: var(--ig-primary-500);` +> ❌ **Wrong:** `--ig-avatar-background: #E91E63;` + +### CSS `::part()` Selectors + +Use `::part()` selectors to style shadow DOM internal elements: + +```css +igc-input::part(input) { + font-size: 1.1rem; +} + +igc-card::part(header) { + padding: 1rem; +} +``` + +> **Note:** In CSS, use web component tag names (`igc-input`), not React component names (`IgrInput`). + +## Layout Controls + +### Sizing + +```css +:root { --ig-size: 2; } /* 1 = small, 2 = medium, 3 = large */ +igc-button { --ig-size: 1; } +``` + +### Spacing + +```css +:root { --ig-spacing: 1; } /* 0.5 = compact, 1 = default, 2 = spacious */ +.compact-section { --ig-spacing: 0.75; } +``` + +### Roundness + +```css +:root { --ig-radius-factor: 1; } /* 0 = square, 1 = maximum radius */ +igc-avatar { --ig-radius-factor: 0.5; } +``` + +## Switching Between Light and Dark Themes + +### Approach 1: CSS class toggle + +```tsx +import { useState } from 'react'; +import 'igniteui-webcomponents/themes/light/bootstrap.css'; +import './theme-overrides.css'; + +function App() { + const [isDark, setIsDark] = useState(false); + + return ( +
+ +
+ ); +} +``` + +```css +/* theme-overrides.css */ +.dark-theme { + --ig-surface-h: 0deg; + --ig-surface-s: 0%; + --ig-surface-l: 7%; + + --ig-gray-h: 0deg; + --ig-gray-s: 0%; + --ig-gray-l: 100%; +} +``` + +### Approach 2: CSS media query + +```css +@media (prefers-color-scheme: dark) { + :root { + --ig-surface-h: 0deg; + --ig-surface-s: 0%; + --ig-surface-l: 7%; + } +} +``` + +### Approach 3: Dynamically swap theme stylesheet + +```tsx +import { useEffect } from 'react'; + +function useTheme(variant: 'light' | 'dark', design = 'bootstrap') { + useEffect(() => { + const link = document.getElementById('igc-theme') as HTMLLinkElement; + if (link) { + link.href = `node_modules/igniteui-webcomponents/themes/${variant}/${design}.css`; + } + }, [variant, design]); +} +``` diff --git a/skills/igniteui-react-customize-theme/reference/MCP-SERVER.md b/skills/igniteui-react-customize-theme/reference/MCP-SERVER.md new file mode 100644 index 0000000..ecc05fd --- /dev/null +++ b/skills/igniteui-react-customize-theme/reference/MCP-SERVER.md @@ -0,0 +1,75 @@ +# Ignite UI Theming MCP Server + +The Ignite UI Theming MCP server enables AI assistants to generate production-ready theming code. It must be configured in your editor before the theming tools become available. + +> **AGENT INSTRUCTION — MCP Server Setup (REQUIRED)** +> +> Before using any theming tools, you MUST verify the MCP server is available +> by calling `detect_platform`. If the tool is not available or the call fails, +> configure it by following the setup steps below. + +## VS Code Setup + +Create or edit `.vscode/mcp.json` in your project: + +```json +{ + "servers": { + "igniteui-theming": { + "command": "npx", + "args": ["-y", "igniteui-theming", "igniteui-theming-mcp"] + } + } +} +``` + +## Cursor Setup + +Create or edit `.cursor/mcp.json`: + +```json +{ + "mcpServers": { + "igniteui-theming": { + "command": "npx", + "args": ["-y", "igniteui-theming", "igniteui-theming-mcp"] + } + } +} +``` + +## Claude Desktop Setup + +Edit the Claude Desktop config file: +- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json` +- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json` + +```json +{ + "mcpServers": { + "igniteui-theming": { + "command": "npx", + "args": ["-y", "igniteui-theming", "igniteui-theming-mcp"] + } + } +} +``` + +## WebStorm / JetBrains IDEs Setup + +1. Go to **Settings → Tools → AI Assistant → MCP Servers** +2. Click **+ Add MCP Server** +3. Set Command to `npx` and Arguments to `igniteui-theming igniteui-theming-mcp` +4. Click OK and restart the AI Assistant + +## MCP Server Workflow + +1. **Detect platform**: Call `detect_platform` — it will detect `webcomponents` from `package.json` +2. **Generate a theme**: Call `create_theme` with your desired colors and design system +3. **Customize components**: Call `get_component_design_tokens` first, then `create_component_theme` with palette token values +4. **Get color references**: Call `get_color` to get the correct CSS custom property for any palette shade +5. **Adjust layout**: Call `set_size`, `set_spacing`, or `set_roundness` + +## File Safety Rule + +> **IMPORTANT — File Safety Rule**: When generating theme code, **never overwrite existing style files directly**. Always propose changes as an update and let the user review before writing to disk. diff --git a/skills/igniteui-react-customize-theme/reference/REVEAL-THEME.md b/skills/igniteui-react-customize-theme/reference/REVEAL-THEME.md new file mode 100644 index 0000000..96a76ff --- /dev/null +++ b/skills/igniteui-react-customize-theme/reference/REVEAL-THEME.md @@ -0,0 +1,51 @@ +# Reveal SDK Theme Sync + +When the project includes Reveal SDK (`reveal-sdk-wrappers-react`) alongside Ignite UI for React, the Reveal dashboard theme should be synced with the active Ignite UI theme. + +## How It Works + +Ignite UI themes expose CSS custom properties (`--ig-font-family`, `--ig-surface-500`, `--ig-gray-100`, etc.) on the page. The Reveal SDK has its own `$.ig.RevealTheme` object that controls dashboard appearance. The sync function reads the Ignite UI tokens from computed styles and maps them to Reveal's theme properties. + +## Reveal Theme Sync Function + +Call this function when initializing a component that uses `RvRevealView`: + +```tsx +function setRevealTheme() { + const style = window.getComputedStyle(document.body); + const theme = new $.ig.RevealTheme(); + + // 1. Sync fonts with the Ignite UI --ig-font-family token + theme.regularFont = style.getPropertyValue('--ig-font-family')?.trim() || 'sans-serif'; + theme.mediumFont = theme.regularFont; + theme.boldFont = theme.regularFont; + + // 2. Auto-detect light/dark from surface color brightness + const color = style.getPropertyValue('--ig-surface-500').trim() || '#fff'; + const [r, g, b] = [1, 3, 5].map(i => parseInt(color.substring(i, i + 2), 16)); + const brightness = (r * 299 + g * 587 + b * 114) / 1000; + + theme.isDark = brightness < 128; + theme.fontColor = theme.isDark ? 'white' : 'black'; + + // 3. Sync background colors with Ignite UI palette tokens + theme.dashboardBackgroundColor = style.getPropertyValue('--ig-gray-100').trim(); + theme.visualizationBackgroundColor = style.getPropertyValue('--ig-surface-500').trim(); + + $.ig.RevealSdkSettings.theme = theme; +} +``` + +## Token Mapping Reference + +| Reveal Theme Property | Ignite UI CSS Token | Purpose | +|---|---|---| +| `regularFont`, `mediumFont`, `boldFont` | `--ig-font-family` | Font family | +| `isDark` | Computed from `--ig-surface-500` brightness | Light/dark mode detection | +| `fontColor` | Derived from `isDark` | Text color (white for dark, black for light) | +| `dashboardBackgroundColor` | `--ig-gray-100` | Dashboard background | +| `visualizationBackgroundColor` | `--ig-surface-500` | Individual visualization card background | + +> **Tip:** When switching between light and dark Ignite UI themes, call `setRevealTheme()` again after the theme change so Reveal dashboards stay in sync. + +See the [use-components skill](../../igniteui-react-use-components/SKILL.md) for full Reveal SDK setup instructions including installation and `RvRevealView` usage. diff --git a/skills/igniteui-react-customize-theme/reference/SASS-THEMING.md b/skills/igniteui-react-customize-theme/reference/SASS-THEMING.md new file mode 100644 index 0000000..2ce76fd --- /dev/null +++ b/skills/igniteui-react-customize-theme/reference/SASS-THEMING.md @@ -0,0 +1,125 @@ +# Sass Theming + +> Requires Sass configured in the project (e.g., `sass` in `devDependencies` and Vite/webpack configured to handle `.scss` files). + +## Basic Setup + +```scss +// src/styles.scss +@use 'igniteui-theming' as *; + +// 1. Define a palette +$my-palette: palette( + $primary: #1976D2, + $secondary: #FF9800, + $surface: #FAFAFA +); + +// 2. Apply the palette +@include palette($my-palette); + +// 3. Optional: Typography +@include typography($font-family: "'Roboto', sans-serif"); + +// 4. Optional: Elevations +@include elevations(); + +// 5. Optional: Spacing +@include spacing(); +``` + +Import in your React entry point: + +```tsx +// main.tsx +import './styles.scss'; +``` + +## Dark Theme + +For dark themes, use a dark surface color and a dark schema: + +```scss +@use 'igniteui-theming' as *; + +$dark-palette: palette( + $primary: #90CAF9, + $secondary: #FFB74D, + $surface: #121212 +); + +@include palette($dark-palette, $schema: $dark-material-schema); +``` + +> **Important:** Use `@use 'igniteui-theming'` — not `igniteui-angular/theming` or Angular-specific `core()` / `theme()` mixins. + +## Component-Level Theming with Sass + +When Sass is configured, use component theme functions and the `tokens` mixin: + +```scss +@use 'igniteui-theming' as *; + +$custom-avatar: avatar-theme( + $schema: $light-material-schema, + $background: var(--ig-primary-500), + $color: var(--ig-primary-500-contrast) +); + +igc-avatar { + @include tokens($custom-avatar); +} +``` + +## Light/Dark Toggle with Sass + +```scss +@use 'igniteui-theming' as *; + +$light-palette: palette($primary: #1976D2, $secondary: #FF9800, $surface: #FAFAFA); +$dark-palette: palette($primary: #90CAF9, $secondary: #FFB74D, $surface: #121212); + +@include typography($font-family: "'Roboto', sans-serif"); +@include elevations(); + +// Light is default +@include palette($light-palette, $schema: $light-material-schema); + +// Dark via class on a container or +.dark-theme { + @include palette($dark-palette, $schema: $dark-material-schema); +} +``` + +## Theming Architecture + +The Ignite UI theming system is built on four pillars: + +| Concept | Purpose | +|---|---| +| **Palette** | Color system with primary, secondary, surface, gray, info, success, warn, error families, each with shades 50–900 + accents A100–A700 | +| **Typography** | Font family, type scale (h1–h6, subtitle, body, button, caption, overline) | +| **Elevations** | Box-shadow levels 0–24 for visual depth | +| **Schema** | Per-component recipes mapping palette colors to component tokens | + +### Design Systems + +Four built-in design systems are available: + +- **Material** (default) — Material Design 3 +- **Bootstrap** — Bootstrap-inspired +- **Fluent** — Microsoft Fluent Design +- **Indigo** — Infragistics Indigo Design + +Each has light and dark variants (e.g., `$light-material-schema`, `$dark-fluent-schema`). + +### Palette Shades + +- Shades 50 = lightest, 900 = darkest for all chromatic colors +- Surface color must match the variant — light color for `light`, dark color for `dark` + +## Key Rules + +1. **Sass**: Use `@use 'igniteui-theming'` — not `igniteui-angular/theming` +2. **Sass**: Component themes use `@include tokens($theme)` inside a selector +3. **Never hardcode colors after palette generation** — use `var(--ig--)` palette tokens everywhere diff --git a/skills/igniteui-react-customize-theme/reference/TROUBLESHOOTING.md b/skills/igniteui-react-customize-theme/reference/TROUBLESHOOTING.md new file mode 100644 index 0000000..5faef71 --- /dev/null +++ b/skills/igniteui-react-customize-theme/reference/TROUBLESHOOTING.md @@ -0,0 +1,35 @@ +# Theming Troubleshooting + +## Issue: Theme overrides not taking effect + +**Cause:** Override CSS is loaded before the theme CSS. + +**Solution:** Make sure your custom CSS is imported *after* the theme: + +```tsx +// main.tsx +import 'igniteui-webcomponents/themes/light/bootstrap.css'; // Theme first +import './custom-overrides.css'; // Overrides second +``` + +## Issue: CSS custom properties not recognized by TypeScript in inline styles + +**Solution:** Cast to `React.CSSProperties`: + +```tsx +
+``` + +## Issue: Component-level CSS selectors don't match + +**Cause:** Using React component name instead of web component tag name in CSS. + +**Solution:** Use the underlying web component tag name in CSS selectors: + +```css +/* ✅ Correct — web component tag */ +igc-button { --ig-size: 1; } + +/* ❌ Wrong — React wrapper name */ +IgrButton { --ig-size: 1; } +``` diff --git a/skills/igniteui-react-optimize-bundle-size/SKILL.md b/skills/igniteui-react-optimize-bundle-size/SKILL.md new file mode 100644 index 0000000..660c66c --- /dev/null +++ b/skills/igniteui-react-optimize-bundle-size/SKILL.md @@ -0,0 +1,453 @@ +--- +name: igniteui-react-optimize-bundle-size +description: This skill optimizes application bundle size when using Ignite UI for React and should be used when the bundle is too large, when setting up tree-shaking, or when lazy loading heavy components like grids and charts +user-invocable: true +--- + +# Optimize Bundle Size + +This skill helps users minimize their React application's bundle size when using Ignite UI for React by importing only the components they need, leveraging tree-shaking, and applying lazy loading strategies. + +## Example Usage + +- "My bundle size is too large" +- "How do I reduce the size of igniteui-react?" +- "Import only the components I need" +- "Tree-shake unused components" +- "Optimize imports for production" +- "How do I lazy load the data grid?" + +## Related Skills + +- [igniteui-react-use-components](../igniteui-react-use-components/SKILL.md) — Proper React setup +- [igniteui-react-choose-components](../igniteui-react-choose-components/SKILL.md) — Choose only the components you need +- [igniteui-react-customize-theme](../igniteui-react-customize-theme/SKILL.md) — Theming after optimization + +## When to Use + +- Application bundle size is too large +- User wants to optimize for production +- User is importing more components than needed +- User asks about tree-shaking or optimization +- User wants to improve load times +- User wants to code-split heavy components like grids or charts + +--- + +## Key Principles + +1. **Install only the packages you need** — don't install `igniteui-react-grids` if you only use core UI components +2. **Use named imports** — enable tree-shaking by importing specific components +3. **Lazy load heavy components** — use `React.lazy` + `Suspense` for grids, charts, and other large components +4. **Analyze your bundle** — use tools to identify what's being included +5. **No `defineComponents()` needed** — the React wrappers handle registration automatically per-component + +--- + +## Granular Package Imports + +Only install the packages you actually use: + +| Package | Contains | Install only if you need… | +|---|---|---| +| `igniteui-react` | Buttons, inputs, dialogs, calendars, lists, etc. | Core UI components | +| `igniteui-grid-lite` | Lightweight grid (web component) | Simple tabular data (MIT, requires `.register()`) | +| `igniteui-react-grids` | DataGrid, TreeGrid, PivotGrid, HierarchicalGrid | Advanced data grids (commercial) | +| `igniteui-react-charts` | Category, Pie, Financial, Scatter charts | Charts and data visualization (commercial) | +| `igniteui-react-maps` | Geographic maps | Map visualizations (commercial) | +| `igniteui-react-gauges` | Radial and linear gauges | Gauge indicators (commercial) | + +```bash +# Only install what you need: +npm install igniteui-react # Core UI only +npm install igniteui-react-grids # Only if you need advanced grids +npm install igniteui-react-charts # Only if you need charts +``` + +--- + +## Import Strategies + +### ❌ Bad: Wildcard / Barrel Imports + +```tsx +// DON'T DO THIS — imports everything from the package +import * as IgniteUI from 'igniteui-react'; + +function App() { + return Click; +} +``` + +**Impact:** Tree-shaking cannot eliminate unused components. + +### ✅ Good: Named Imports + +```tsx +// DO THIS — import only what you use +import { IgrButton, IgrInput, IgrCard } from 'igniteui-react'; + +function App() { + return ( +
+ + Submit + Content +
+ ); +} +``` + +**Impact:** Bundle includes only the three components and their dependencies. Tree-shaking removes everything else. + +### About `defineComponents()` + +The React wrappers handle web component registration automatically when you import and render a component. **You never need to call `defineComponents()`** — doing so would be redundant and could pull in unnecessary code if you imported the function from `igniteui-webcomponents` directly. + +```tsx +// ❌ Don't do this — unnecessary and bypasses tree-shaking +import { defineComponents, IgcButtonComponent } from 'igniteui-webcomponents'; +defineComponents(IgcButtonComponent); + +// ✅ Just import the React wrapper +import { IgrButton } from 'igniteui-react'; +``` + +--- + +## Lazy Loading with `React.lazy` + `Suspense` + +Code-split heavy components behind lazy imports to reduce initial bundle size. + +### Lazy Loading a Single Component + +```tsx +import { lazy, Suspense, useState } from 'react'; + +// Lazy load the dialog component +const IgrDialog = lazy(() => + import('igniteui-react').then(module => ({ default: module.IgrDialog })) +); + +function App() { + const [showDialog, setShowDialog] = useState(false); + + return ( + <> + + {showDialog && ( + Loading...
}> + +

Lazy loaded dialog content

+
+ + )} + + ); +} +``` + +### Lazy Loading a Heavy Page Component + +This is the recommended approach for code-splitting: wrap entire page components that use heavy Ignite UI components. + +```tsx +// App.tsx +import { BrowserRouter, Routes, Route } from 'react-router-dom'; +import { lazy, Suspense } from 'react'; + +const HomePage = lazy(() => import('./pages/Home')); +const DashboardPage = lazy(() => import('./pages/Dashboard')); +const AnalyticsPage = lazy(() => import('./pages/Analytics')); + +function App() { + return ( + + Loading...}> + + } /> + } /> + } /> + + + + ); +} +``` + +```tsx +// pages/Dashboard.tsx — only loaded when navigating to /dashboard +import { IgrDataGrid, IgrColumn } from 'igniteui-react-grids'; +import 'igniteui-webcomponents-grids/grids/themes/light/bootstrap.css'; + +export default function Dashboard() { + return ( + + + + + ); +} +``` + +```tsx +// pages/Analytics.tsx — only loaded when navigating to /analytics +import { IgrCategoryChart } from 'igniteui-react-charts'; + +export default function Analytics() { + return ; +} +``` + +**Result:** The grid and chart bundles are only downloaded when the user navigates to those routes. + +--- + +## Analyzing Your Bundle + +### Using Vite's Rollup Visualizer + +```bash +npm install --save-dev rollup-plugin-visualizer +``` + +```typescript +// vite.config.ts +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; +import { visualizer } from 'rollup-plugin-visualizer'; + +export default defineConfig({ + plugins: [ + react(), + visualizer({ + open: true, + gzipSize: true, + brotliSize: true, + }) + ] +}); +``` + +```bash +npm run build +# Opens stats.html automatically — inspect which igniteui-react modules are included +``` + +### Using Webpack Bundle Analyzer + +```bash +npm install --save-dev webpack-bundle-analyzer +``` + +```javascript +// webpack.config.js (or CRA with react-app-rewired) +const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); + +module.exports = { + plugins: [ + new BundleAnalyzerPlugin({ + analyzerMode: 'static', + openAnalyzer: false, + reportFilename: 'bundle-report.html' + }) + ] +}; +``` + +### Using source-map-explorer + +```bash +npm install --save-dev source-map-explorer +``` + +```json +{ + "scripts": { + "analyze": "source-map-explorer 'dist/**/*.js'" + } +} +``` + +```bash +npm run build +npm run analyze +``` + +**What to look for:** Check if `igniteui-react-grids` or `igniteui-react-charts` appear in the initial bundle even though they're only used on specific routes. + +--- + +## Audit Your Component Usage + +### 1. Find What Components You're Actually Using + +```bash +# Search for Igr component usage in your source files +grep -roh "Igr[A-Z][a-zA-Z]*" src/ --include="*.tsx" --include="*.ts" | sort | uniq + +# Example output: +# IgrButton +# IgrCard +# IgrInput +``` + +### 2. Compare with Your Imports + +```bash +# Find all import statements from igniteui-react packages +grep -r "from 'igniteui-react" src/ --include="*.tsx" --include="*.ts" +``` + +### 3. Remove Unused Imports + +```tsx +// Before: 5 components imported +import { IgrButton, IgrInput, IgrCard, IgrSelect, IgrCombo } from 'igniteui-react'; + +// After audit: only 3 are actually used in JSX +import { IgrButton, IgrInput, IgrCard } from 'igniteui-react'; +``` + +--- + +## Build Configuration Optimizations + +### Vite Configuration + +```typescript +// vite.config.ts +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; + +export default defineConfig({ + plugins: [react()], + build: { + minify: 'terser', + terserOptions: { + compress: { + drop_console: true, + drop_debugger: true + } + }, + rollupOptions: { + output: { + manualChunks: { + 'igniteui-core': ['igniteui-react'], + // Only include if you use these packages: + // 'igniteui-grids': ['igniteui-react-grids'], + // 'igniteui-charts': ['igniteui-react-charts'], + } + } + }, + chunkSizeWarningLimit: 600, + }, + optimizeDeps: { + include: ['igniteui-react'] + } +}); +``` + +### Webpack Configuration + +```javascript +// webpack.config.js +module.exports = { + optimization: { + splitChunks: { + chunks: 'all', + cacheGroups: { + igniteui: { + test: /[\\/]node_modules[\\/]igniteui-react[\\/]/, + name: 'igniteui', + priority: 20, + }, + igniteuiGrids: { + test: /[\\/]node_modules[\\/]igniteui-react-grids[\\/]/, + name: 'igniteui-grids', + priority: 20, + } + } + }, + minimize: true, + }, + mode: 'production', +}; +``` + +--- + +## Best Practices Checklist + +- [ ] **Install only the packages you need** — don't install `igniteui-react-grids` if you only use buttons and inputs +- [ ] **Use named imports** — `import { IgrButton } from 'igniteui-react'`, not `import * as` +- [ ] **Don't import from `igniteui-webcomponents` directly** — use the `igniteui-react` wrappers +- [ ] **Don't call `defineComponents()`** — the React wrappers handle this automatically +- [ ] **Lazy load heavy components** — use `React.lazy` + `Suspense` for grids, charts, and dialogs +- [ ] **Split by routes** — load component-heavy pages only when navigated to +- [ ] **Audit your imports regularly** — remove unused components +- [ ] **Analyze your bundle** — use bundle analyzer tools to verify tree-shaking is working +- [ ] **Minify in production** — ensure build tool minification is enabled +- [ ] **Use compression** — enable gzip/brotli on your server + +--- + +## Common Issues & Solutions + +### Issue: Bundle still large after using named imports + +**Investigate:** +1. Check if you're importing from `igniteui-webcomponents` instead of `igniteui-react` +2. Verify tree-shaking is working (check build output with a bundle analyzer) +3. Look for barrel imports (`import * as`) +4. Check if large packages like `igniteui-react-grids` are in the initial bundle instead of being lazy loaded + +### Issue: Lazy loaded component flashes or shows fallback too long + +**Solution:** Preload the component on hover or route prefetch: + +```tsx +const DashboardPage = lazy(() => import('./pages/Dashboard')); + +// Preload on hover +function NavLink() { + const preload = () => { import('./pages/Dashboard'); }; + return Dashboard; +} +``` + +### Issue: Tree-shaking not working + +**Cause:** Using `require()` instead of `import`, or a build tool that doesn't support ES module tree-shaking. + +**Solution:** Ensure your project uses ES modules: + +```json +// tsconfig.json +{ + "compilerOptions": { + "module": "esnext", + "moduleResolution": "bundler" + } +} +``` + +--- + +## Expected Results + +After optimization, you should see: + +- **Initial load time reduced** by 40–60% +- **Bundle size reduced** by 50–80% (compared to importing everything) +- **Better Core Web Vitals** scores +- **Faster time to interactive** +- **Lower bandwidth usage** for users + +## Additional Resources + +- [Vite Build Optimizations](https://vitejs.dev/guide/build.html) +- [React.lazy Documentation](https://react.dev/reference/react/lazy) +- [Webpack Tree Shaking](https://webpack.js.org/guides/tree-shaking/) +- [Web Performance Optimization](https://web.dev/fast/) +- [Bundle Size Analysis Tools](https://bundlephobia.com/) diff --git a/skills/igniteui-react-use-components/SKILL.md b/skills/igniteui-react-use-components/SKILL.md new file mode 100644 index 0000000..8064907 --- /dev/null +++ b/skills/igniteui-react-use-components/SKILL.md @@ -0,0 +1,149 @@ +--- +name: igniteui-react-use-components +description: This skill installs, imports, and uses Ignite UI for React components covering JSX patterns, event handling, refs, forms, and TypeScript and should be used when setting up a React project, writing component JSX, handling events, or integrating with React state and form libraries +user-invocable: true +--- + +# Use Ignite UI for React Components + +This skill covers everything you need to install, set up, and use Ignite UI for React components in a React application — including JSX patterns, event handling, refs, controlled/uncontrolled form components, and TypeScript. + +## Example Usage + +- "How do I install Ignite UI for React?" +- "Set up igniteui-react in my project" +- "How do I handle events on IgrCombo?" +- "How do I use IgrInput with React Hook Form?" +- "Show me how to use refs with IgrDialog" +- "What TypeScript types should I use for IgrButton props?" +- "How do I pass children vs slots to Ignite UI components?" + +## Related Skills + +- [igniteui-react-choose-components](../igniteui-react-choose-components/SKILL.md) — Pick the right component for your UI +- [igniteui-react-customize-theme](../igniteui-react-customize-theme/SKILL.md) — Theme and style components +- [igniteui-react-optimize-bundle-size](../igniteui-react-optimize-bundle-size/SKILL.md) — Reduce bundle size + +## When to Use + +- Setting up Ignite UI for React in a new or existing project +- Writing JSX that uses Ignite UI components +- Handling events from Ignite UI components +- Integrating components with React state or form libraries +- Using refs to call imperative methods on components +- Working with TypeScript prop types + +--- + +## Content Guide + +This skill is organized into focused sections. Refer to the appropriate file for detailed instructions: + +| Topic | File | When to Use | +|---|---|---| +| Installation & Setup | [INSTALLATION.md](./reference/INSTALLATION.md) | Setting up packages, importing theme CSS, Next.js setup | +| JSX Patterns | [JSX-PATTERNS.md](./reference/JSX-PATTERNS.md) | Props, children, slots, IgrTabs content vs navigation | +| Event Handling | [EVENT-HANDLING.md](./reference/EVENT-HANDLING.md) | Event props, CustomEvent types, common events | +| Refs & Forms | [REFS-FORMS.md](./reference/REFS-FORMS.md) | useRef, controlled/uncontrolled forms, React Hook Form | +| Charts, Gauges, Maps & Grid Lite | [CHARTS-GRIDS.md](./reference/CHARTS-GRIDS.md) | Module registration, container sizing | +| Reveal SDK | [REVEAL-SDK.md](./reference/REVEAL-SDK.md) | Embedded BI dashboards, theme sync | +| Troubleshooting | [TROUBLESHOOTING.md](./reference/TROUBLESHOOTING.md) | Common issues and solutions | + +--- + +## Quick Start + +### 1. Install + +```bash +npm install igniteui-react +``` + +### 2. Import Theme CSS (REQUIRED) + +```tsx +// main.tsx +import 'igniteui-webcomponents/themes/light/bootstrap.css'; +``` + +> **CRITICAL:** Without the theme CSS, components will render without styles and icons will be broken. + +### 3. Use Components + +```tsx +import { IgrButton, IgrInput } from 'igniteui-react'; + +function App() { + return ( +
+ + Submit +
+ ); +} +``` + +> **No `defineComponents()` needed.** React wrappers auto-register. See [CHARTS-GRIDS.md](./CHARTS-GRIDS.md) for exceptions (charts, gauges, maps, Grid Lite). + +--- + +## Key Concepts + +### Theme CSS Import + +- **Always import theme CSS** before using components — see [INSTALLATION.md](./INSTALLATION.md) +- **For grids**, also import `igniteui-webcomponents-grids/grids/themes/...` +- **In Next.js**, import in each client component file or root layout + +### JSX Patterns + +- Use `slot` attribute for named slots: `📊` +- Boolean props: `` is shorthand for `disabled={true}` +- See [JSX-PATTERNS.md](./JSX-PATTERNS.md) + +### IgrTabs: Content vs Navigation + +- **Content panels**: Use `IgrTab` + `IgrTabPanel` together +- **Navigation (router)**: Use **only `IgrTab`** — no `IgrTabPanel` +- See [JSX-PATTERNS.md](./JSX-PATTERNS.md) + +### Events + +- Events are `CustomEvent` objects, not React `SyntheticEvent` +- Access data via `e.target` or `e.detail` +- See [EVENT-HANDLING.md](./EVENT-HANDLING.md) + +### Refs + +- Use `useRef(null)` and cast to access imperative API +- See [REFS-FORMS.md](./REFS-FORMS.md) + +### Charts, Gauges, Maps & Grid Lite + +- **Require explicit registration**: `IgrCategoryChartModule.register()`, `IgcGridLite.register()` +- **Require sized container**: `min-width`, `min-height`, or `flex-grow` +- **Grid Lite** uses `Igc` prefix (web component, not React wrapper) +- See [CHARTS-GRIDS.md](./CHARTS-GRIDS.md) + +--- + +## Best Practices + +1. **Import theme CSS first** — components need it to render correctly +2. **Don't call `defineComponents()`** — React wrappers auto-register +3. **Register chart/gauge/map/Grid Lite modules** — call `.register()` at module level +4. **Wrap charts/gauges/maps/Grid Lite in sized containers** — they need explicit dimensions +5. **Grid Lite uses `Igc` prefix** — `IgcGridLite` from `igniteui-grid-lite` +6. **Use named imports** — enables tree-shaking +7. **Handle events as `CustomEvent`** — not `React.SyntheticEvent` +8. **Use refs sparingly** — prefer declarative props +9. **Prefer controlled components** for forms +10. **Check slot names** in the docs +11. **Tabs for navigation** — do NOT include `IgrTabPanel` when using with router + +## Additional Resources + +- [Ignite UI for React — Getting Started](https://www.infragistics.com/reactsite/components/general-getting-started) +- [React Examples Repository](https://github.com/IgniteUI/igniteui-react-examples) +- [npm: igniteui-react](https://www.npmjs.com/package/igniteui-react) +- [@lit/react Documentation](https://lit.dev/docs/frameworks/react/) diff --git a/skills/igniteui-react-use-components/reference/CHARTS-GRIDS.md b/skills/igniteui-react-use-components/reference/CHARTS-GRIDS.md new file mode 100644 index 0000000..bd447ac --- /dev/null +++ b/skills/igniteui-react-use-components/reference/CHARTS-GRIDS.md @@ -0,0 +1,126 @@ +# Charts, Gauges, Maps & Grid Lite + +## Module Registration + +> **⚠️ IMPORTANT:** Unlike core UI components (from `igniteui-react`), chart, gauge, and map components from `igniteui-react-charts`, `igniteui-react-gauges`, and `igniteui-react-maps` **require explicit module registration** before use. You must import the corresponding `*Module` class and call `.register()` at the module level (outside the component function). +> +> **Grid Lite** (`IgcGridLite` from `igniteui-grid-lite`) is a **web component** — not a React wrapper. It also requires `IgcGridLite.register()` and a sized container. + +### Registration Syntax + +```tsx +import { IgrCategoryChart, IgrCategoryChartModule } from 'igniteui-react-charts'; + +// ⚠️ REQUIRED — register the module before using the component +IgrCategoryChartModule.register(); +``` + +### Common Module Registrations + +| Component | Module Import | Registration | +|---|---|---| +| `IgrCategoryChart` | `IgrCategoryChartModule` | `IgrCategoryChartModule.register()` | +| `IgrPieChart` | `IgrPieChartModule` | `IgrPieChartModule.register()` | +| `IgrFinancialChart` | `IgrFinancialChartModule` | `IgrFinancialChartModule.register()` | +| `IgrRadialGauge` | `IgrRadialGaugeModule` | `IgrRadialGaugeModule.register()` | +| `IgrLinearGauge` | `IgrLinearGaugeModule` | `IgrLinearGaugeModule.register()` | +| `IgrGeographicMap` | `IgrGeographicMapModule` | `IgrGeographicMapModule.register()` | +| `IgcGridLite` | (self-registering) | `IgcGridLite.register()` | + +## Container Sizing (REQUIRED) + +> **⚠️ CRITICAL:** Charts, gauges, maps, and Grid Lite **require an explicit-sized container** to render. They inherit their dimensions from the parent element — if the parent has no height/width, the component will not be visible. Always wrap these components in a container with explicit `min-width`, `min-height`, or `flex-grow` styling. + +```css +/* Chart container CSS */ +.chart-container { + min-width: 400px; + min-height: 300px; + flex-grow: 1; + flex-basis: 0; +} + +/* Ensure the chart fills its container */ +.chart-container > * { + height: 100%; + width: 100%; +} +``` + +## Complete Chart Example + +```tsx +import { IgrCategoryChart, IgrCategoryChartModule } from 'igniteui-react-charts'; +import styles from './dashboard-view.module.css'; + +// Register the chart module (required, called once at module level) +IgrCategoryChartModule.register(); + +export default function DashboardView() { + const salesData = [ + { month: 'Jan', revenue: 12500 }, + { month: 'Feb', revenue: 18200 }, + { month: 'Mar', revenue: 15800 }, + ]; + + return ( +
+ +
+ ); +} +``` + +```css +/* dashboard-view.module.css */ +.chart-container { + min-width: 400px; + min-height: 300px; + flex-grow: 1; + flex-basis: 0; +} +.chart-container > * { + height: 100%; + width: 100%; +} +``` + +> **Note:** Core UI components from `igniteui-react` (e.g., `IgrButton`, `IgrInput`) do NOT require module registration — they auto-register when imported. Charts, gauges, maps, and Grid Lite all need explicit `.register()` calls. + +## Complete Grid Lite Example + +> **⚠️ IMPORTANT:** Grid Lite (`IgcGridLite`) is a **web component** from `igniteui-grid-lite` — it uses the `Igc` prefix (not `Igr`). It requires `IgcGridLite.register()` and a sized container. + +```tsx +import { IgcGridLite } from 'igniteui-grid-lite'; +import { useGetCustomers } from '../hooks/northwind-hooks'; +import styles from './master-view.module.css'; + +// ⚠️ REQUIRED — register the web component before use +IgcGridLite.register(); + +export default function MasterView() { + const { northwindCustomers } = useGetCustomers(); + + return ( +
+ +
+ ); +} +``` + +```css +/* master-view.module.css */ +.grid-lite { + min-width: 400px; + min-height: 220px; + flex-grow: 1; + flex-basis: 0; +} +``` diff --git a/skills/igniteui-react-use-components/reference/EVENT-HANDLING.md b/skills/igniteui-react-use-components/reference/EVENT-HANDLING.md new file mode 100644 index 0000000..60d0e65 --- /dev/null +++ b/skills/igniteui-react-use-components/reference/EVENT-HANDLING.md @@ -0,0 +1,70 @@ +# Event Handling + +## How Events Work + +Ignite UI React wrappers map web component custom events to React-style `onXxx` callback props. The event name is converted from the web component event name to a camelCase `on`-prefixed prop. + +```tsx +import { IgrButton, IgrInput, IgrCheckbox } from 'igniteui-react'; + +function MyForm() { + const handleClick = (event: CustomEvent) => { + console.log('Button clicked'); + }; + + const handleInput = (event: CustomEvent) => { + // event.target is the underlying web component element (e.g., igc-input) + console.log('Input value:', (event.target as any).value); + }; + + const handleChange = (event: CustomEvent) => { + console.log('Checkbox changed:', event.detail); + }; + + return ( + <> + + Submit + + + Accept terms + + ); +} +``` + +## Common Event Props + +| Component | Event Prop | Fires When | +|---|---|---| +| `IgrButton` | `onClick` | Button is clicked | +| `IgrInput` | `onInput` | Value changes (each keystroke) | +| `IgrInput` | `onChange` | Value committed (blur / Enter) | +| `IgrCheckbox` | `onChange` | Checked state changes | +| `IgrSwitch` | `onChange` | Toggle state changes | +| `IgrSelect` | `onChange` | Selection changes | +| `IgrCombo` | `onChange` | Selection changes | +| `IgrSlider` | `onInput` | Slider value changes (live) | +| `IgrSlider` | `onChange` | Slider value committed | +| `IgrDialog` | `onClosing` | Dialog is about to close | +| `IgrDialog` | `onClosed` | Dialog has closed | +| `IgrTabs` | `onChange` | Active tab changes | +| `IgrCalendar` | `onChange` | Selected date changes | +| `IgrDatepicker` | `onChange` | Selected date changes | + +## TypeScript Event Types + +When using TypeScript, event handlers receive the underlying `CustomEvent`: + +```tsx +import { IgrInput } from 'igniteui-react'; + +function SearchBar() { + const handleInput = (e: CustomEvent) => { + const value = (e.target as HTMLInputElement).value; + console.log('Search:', value); + }; + + return ; +} +``` diff --git a/skills/igniteui-react-use-components/reference/INSTALLATION.md b/skills/igniteui-react-use-components/reference/INSTALLATION.md new file mode 100644 index 0000000..1b7b75d --- /dev/null +++ b/skills/igniteui-react-use-components/reference/INSTALLATION.md @@ -0,0 +1,140 @@ +# Installation & Setup + +## Install the Package + +```bash +# Core UI components (MIT) +npm install igniteui-react + +# If you need the lightweight grid (MIT, web component) +npm install igniteui-grid-lite + +# If you need advanced grids (commercial) +npm install igniteui-react-grids + +# If you need charts (commercial) +npm install igniteui-react-charts + +# If you need gauges (commercial) +npm install igniteui-react-gauges + +# If you need maps (commercial) +npm install igniteui-react-maps +``` + +## Peer Dependencies + +`igniteui-react` requires `react` and `react-dom` (v18+ or v19+). These are typically already in your project: + +```bash +npm install react react-dom +``` + +## Import a Theme (REQUIRED) + +> **CRITICAL:** Components will render without styles, with broken icons and missing visuals if the theme CSS is not imported. **Always import the theme CSS before using any Ignite UI component.** + +Import one theme CSS file in your entry point (`main.tsx`, `index.tsx`, or `App.tsx`). The theme CSS must be imported **in every file that uses Ignite UI components** if your framework does not have a single global entry point (e.g., Next.js — see below). + +```tsx +// main.tsx or index.tsx +import 'igniteui-webcomponents/themes/light/bootstrap.css'; +``` + +Available themes: + +| Import | Theme | +|---|---| +| `igniteui-webcomponents/themes/light/bootstrap.css` | Bootstrap Light | +| `igniteui-webcomponents/themes/dark/bootstrap.css` | Bootstrap Dark | +| `igniteui-webcomponents/themes/light/material.css` | Material Light | +| `igniteui-webcomponents/themes/dark/material.css` | Material Dark | +| `igniteui-webcomponents/themes/light/fluent.css` | Fluent Light | +| `igniteui-webcomponents/themes/dark/fluent.css` | Fluent Dark | +| `igniteui-webcomponents/themes/light/indigo.css` | Indigo Light | +| `igniteui-webcomponents/themes/dark/indigo.css` | Indigo Dark | + +**For grids**, you **must also** import the grid theme CSS. Without it, the grid will be missing styles and icons will show as placeholders: + +```tsx +import 'igniteui-webcomponents/themes/light/bootstrap.css'; +import 'igniteui-webcomponents-grids/grids/themes/light/bootstrap.css'; +``` + +> **Note:** The theme CSS is imported from the underlying `igniteui-webcomponents` and `igniteui-webcomponents-grids` packages (dependencies of `igniteui-react` and `igniteui-react-grids`), not from `igniteui-react` itself. + +## Next.js Setup + +In Next.js, there is no single `main.tsx` entry point. Import the theme CSS **in each client component file** that uses Ignite UI components, or in a shared layout component: + +```tsx +// app/components/DataTable.tsx +'use client'; + +import 'igniteui-webcomponents/themes/light/bootstrap.css'; +import 'igniteui-webcomponents-grids/grids/themes/light/bootstrap.css'; + +import { IgrGrid, IgrColumn, IgrPaginator } from 'igniteui-react-grids'; + +export default function DataTable({ data }: { data: any[] }) { + return ( + + + + + + ); +} +``` + +Alternatively, import themes once in a root layout: + +```tsx +// app/layout.tsx +import 'igniteui-webcomponents/themes/light/bootstrap.css'; +import 'igniteui-webcomponents-grids/grids/themes/light/bootstrap.css'; + +export default function RootLayout({ children }: { children: React.ReactNode }) { + return ( + + {children} + + ); +} +``` + +## Minimal App Example (Vite / CRA) + +```tsx +// main.tsx +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import 'igniteui-webcomponents/themes/light/bootstrap.css'; +import App from './App'; + +ReactDOM.createRoot(document.getElementById('root')!).render( + + + +); +``` + +```tsx +// App.tsx +import { IgrButton, IgrInput } from 'igniteui-react'; + +function App() { + return ( +
+ + Submit +
+ ); +} + +export default App; +``` + +> **No `defineComponents()` needed.** Unlike the underlying web components library, the React wrappers automatically register the web component when you import and render them. You never need to call `defineComponents()`. +> +> **Exception — Charts, Gauges, Maps & Grid Lite:** Components from `igniteui-react-charts`, `igniteui-react-gauges`, `igniteui-react-maps`, and `igniteui-grid-lite` **do** require explicit registration. See [CHARTS-GRIDS.md](./CHARTS-GRIDS.md). diff --git a/skills/igniteui-react-use-components/reference/JSX-PATTERNS.md b/skills/igniteui-react-use-components/reference/JSX-PATTERNS.md new file mode 100644 index 0000000..7e4ed7c --- /dev/null +++ b/skills/igniteui-react-use-components/reference/JSX-PATTERNS.md @@ -0,0 +1,171 @@ +# JSX Usage Patterns + +## Props vs HTML Attributes + +Ignite UI React components accept props just like any React component. Use JSX expression syntax for dynamic values: + +```tsx +// ✅ Correct — JSX expression + + +Submit + +// ❌ Wrong — string for numeric/boolean values + +``` + +## Boolean Props + +Pass `true` / `false` explicitly, or use the shorthand (presence = `true`): + +```tsx +// These are equivalent: + + + +// Explicitly false: + +``` + +## Children vs Slots + +Ignite UI components use the web component **slot** mechanism under the hood. In JSX, pass children to the default slot and use the `slot` attribute to target named slots: + +```tsx + + {/* Default slot — button label */} + Click Me + + + + +

Card Title

+

Card subtitle

+
+ +

Default slot content inside the card body.

+
+ + Cancel + Confirm + +
+ + + 📊 + Dashboard + +``` + +> **Tip:** Check the component documentation for available slot names. Common slots include `start`, `end`, `prefix`, `suffix`, `header`, `content`, `icon`, `title`, `subtitle`. + +## Render Props (Grids & Complex Components) + +Some components like the Data Grid support **render props** for custom cell rendering: + +```tsx +import { IgrDataGrid, IgrColumn } from 'igniteui-react-grids'; + +function UserGrid({ users }: { users: User[] }) { + return ( + + + + ( + {ctx.cell.value} + )} + /> + + ); +} +``` + +## IgrTabs — Content Panels vs Navigation + +`IgrTabs` supports two distinct usage patterns. Choosing the wrong one is a common mistake. + +### Pattern 1: Tabs with Content Panels (inline content) + +Use `IgrTab` + `IgrTabPanel` when the tabbed content is rendered inline — no routing involved: + +```tsx +import { IgrTabs, IgrTab, IgrTabPanel } from 'igniteui-react'; + +function SettingsPage() { + return ( + + Profile + Security + Notifications + + +

Profile settings content here

+
+ +

Security settings content here

+
+ +

Notification preferences content here

+
+
+ ); +} +``` + +### Pattern 2: Tabs as Navigation (with React Router — NO `IgrTabPanel`) + +> **⚠️ CRITICAL:** When using `IgrTabs` for navigation with React Router (or any router), **do NOT include `IgrTabPanel`**. Adding tab panels creates empty content areas that fill the view and push the routed content out of sight. Only render `IgrTab` elements and let the router's `` handle the content below the tabs. + +```tsx +import { IgrTabs, IgrTab } from 'igniteui-react'; +import { useNavigate, useLocation, Outlet } from 'react-router-dom'; + +const tabs = [ + { path: '/dashboard', label: 'Dashboard' }, + { path: '/orders', label: 'Orders' }, + { path: '/customers', label: 'Customers' }, +]; + +function MainLayout() { + const navigate = useNavigate(); + const location = useLocation(); + + const handleTabChange = (e: CustomEvent) => { + const selectedIndex = (e.target as any).selectedIndex; + if (selectedIndex !== undefined && tabs[selectedIndex]) { + navigate(tabs[selectedIndex].path); + } + }; + + return ( +
+ {/* Tabs for navigation — NO IgrTabPanel */} + + {tabs.map((tab) => ( + + {tab.label} + + ))} + + + {/* Router outlet renders the routed view */} +
+ +
+
+ ); +} +``` + +**Key rules for tabs-as-navigation:** +- ✅ Use only `IgrTab` inside `IgrTabs` — no `IgrTabPanel` +- ✅ Sync the active tab to the current route using the `selected` prop +- ✅ Handle `onChange` to call `navigate()` for route changes +- ✅ Use `` (or the equivalent in your router) for content rendering +- ❌ Do NOT add `IgrTabPanel` — it creates an empty panel body that fills the viewport diff --git a/skills/igniteui-react-use-components/reference/REFS-FORMS.md b/skills/igniteui-react-use-components/reference/REFS-FORMS.md new file mode 100644 index 0000000..e6f830d --- /dev/null +++ b/skills/igniteui-react-use-components/reference/REFS-FORMS.md @@ -0,0 +1,228 @@ +# Refs & Forms + +## Refs & Imperative API + +Use `useRef` to access the underlying web component element and call imperative methods (e.g., showing/hiding a dialog, focusing an input): + +```tsx +import { useRef } from 'react'; +import { IgrDialog, IgrButton, IgrInput } from 'igniteui-react'; + +function MyPage() { + const dialogRef = useRef(null); + const inputRef = useRef(null); + + const openDialog = () => { + // Access the underlying web component and call its methods + (dialogRef.current as any)?.show(); + }; + + const focusInput = () => { + inputRef.current?.focus(); + }; + + return ( + <> + + Open Dialog + + + +

Are you sure?

+ (dialogRef.current as any)?.hide()}> + Close + +
+ + + Focus Input + + + + ); +} +``` + +> **Tip:** The ref gives you direct access to the web component's DOM element. You can call any method documented in the web component API. + +## Controlled Components with `useState` + +Wire up Ignite UI form components with React state for controlled behavior: + +```tsx +import { useState } from 'react'; +import { IgrInput, IgrCheckbox, IgrSelect, IgrSelectItem } from 'igniteui-react'; + +function ProfileForm() { + const [name, setName] = useState(''); + const [newsletter, setNewsletter] = useState(false); + const [role, setRole] = useState('user'); + + return ( +
+ + setName((e.target as HTMLInputElement).value) + } + /> + + + setNewsletter((e.target as any).checked) + } + > + Subscribe to newsletter + + + + setRole((e.detail as any).value) + } + > + User + Admin + Editor + + + ); +} +``` + +## Uncontrolled Components + +For simpler scenarios, omit state and read the value on submit: + +```tsx +import { useRef } from 'react'; +import { IgrInput, IgrButton } from 'igniteui-react'; + +function SimpleForm() { + const nameRef = useRef(null); + + const handleSubmit = () => { + const value = (nameRef.current as any)?.value; + console.log('Name:', value); + }; + + return ( +
+ + + Submit + + + ); +} +``` + +## React Hook Form Integration + +Ignite UI components are form-associated web components. You can integrate them with React Hook Form using `Controller`: + +```tsx +import { useForm, Controller } from 'react-hook-form'; +import { IgrInput, IgrCheckbox, IgrButton } from 'igniteui-react'; + +interface FormData { + email: string; + acceptTerms: boolean; +} + +function SignUpForm() { + const { control, handleSubmit, formState: { errors } } = useForm(); + + const onSubmit = (data: FormData) => { + console.log(data); + }; + + return ( +
+ ( + + field.onChange((e.target as HTMLInputElement).value) + } + onBlur={() => field.onBlur()} + invalid={!!errors.email} + /> + )} + /> + {errors.email && {errors.email.message}} + + ( + + field.onChange((e.target as any).checked) + } + > + I accept the terms and conditions + + )} + /> + + + Sign Up + + + ); +} +``` + +## TypeScript + +### Importing Component Types + +Each component exports its props interface. Import and use them for type-safe code: + +```tsx +import { IgrButton, IgrInput } from 'igniteui-react'; +import type { ComponentProps } from 'react'; + +// Get the props type for a component +type ButtonProps = ComponentProps; +type InputProps = ComponentProps; + +// Use in your own components +interface FormFieldProps { + label: string; + inputProps?: Partial; +} + +function FormField({ label, inputProps }: FormFieldProps) { + return ( +
+ +
+ ); +} +``` + +### Auto-complete + +IDEs with TypeScript support will provide auto-complete for all `Igr*` component props. Make sure your `tsconfig.json` includes: + +```json +{ + "compilerOptions": { + "jsx": "react-jsx", + "moduleResolution": "bundler" + } +} +``` diff --git a/skills/igniteui-react-use-components/reference/REVEAL-SDK.md b/skills/igniteui-react-use-components/reference/REVEAL-SDK.md new file mode 100644 index 0000000..25eaaa0 --- /dev/null +++ b/skills/igniteui-react-use-components/reference/REVEAL-SDK.md @@ -0,0 +1,106 @@ +# Reveal SDK Integration + +Reveal SDK is a companion product for embedding interactive BI dashboards and data visualizations inside your React application. It uses separate packages and requires a backend Reveal server URL. + +## Install Reveal SDK + +```bash +npm install reveal-sdk-wrappers-react reveal-sdk-wrappers +``` + +> **Note:** `reveal-sdk-wrappers-react` provides the React component (`RvRevealView`), while `reveal-sdk-wrappers` provides the options and configuration types (`RevealViewOptions`). +> +> The Reveal SDK exposes its API through the `$.ig` global namespace. If TypeScript reports that `$` is not defined, add a declaration at the top of your file: +> ```tsx +> declare const $: any; +> ``` + +## Basic Usage + +```tsx +import { RvRevealView } from 'reveal-sdk-wrappers-react'; +import { RevealViewOptions } from 'reveal-sdk-wrappers'; + +declare const $: any; + +function DashboardView() { + // Set the Reveal SDK backend URL (required) + $.ig.RevealSdkSettings.setBaseUrl('https://your-reveal-server/reveal-api/'); + + const options: RevealViewOptions = { + visualizations: { + menu: { + copy: false, + duplicate: false + } + } + }; + + return ; +} +``` + +## Syncing Reveal Theme with Ignite UI Theme + +When using Reveal SDK alongside Ignite UI components, sync the Reveal theme with Ignite UI's CSS custom properties so both share the same visual style. Call `setRevealTheme()` at component initialization: + +```tsx +import { RvRevealView } from 'reveal-sdk-wrappers-react'; +import { RevealViewOptions } from 'reveal-sdk-wrappers'; + +declare const $: any; + +export default function DashboardView() { + const options: RevealViewOptions = { + visualizations: { + menu: { + copy: false, + duplicate: false + } + } + }; + + $.ig.RevealSdkSettings.setBaseUrl('https://your-reveal-server/reveal-api/'); + setRevealTheme(); + + function setRevealTheme() { + const style = window.getComputedStyle(document.body); + const theme = new $.ig.RevealTheme(); + + // Sync font with Ignite UI's --ig-font-family token + theme.regularFont = style.getPropertyValue('--ig-font-family')?.trim() || 'sans-serif'; + theme.mediumFont = theme.regularFont; + theme.boldFont = theme.regularFont; + + // Auto-detect light/dark mode from the surface color brightness + const color = style.getPropertyValue('--ig-surface-500').trim() || '#fff'; + const [r, g, b] = [1, 3, 5].map(i => parseInt(color.substring(i, i + 2), 16)); + const brightness = (r * 299 + g * 587 + b * 114) / 1000; + + theme.isDark = brightness < 128; + theme.fontColor = theme.isDark ? 'white' : 'black'; + + // Sync background colors with Ignite UI palette tokens + theme.dashboardBackgroundColor = style.getPropertyValue('--ig-gray-100').trim(); + theme.visualizationBackgroundColor = style.getPropertyValue('--ig-surface-500').trim(); + + $.ig.RevealSdkSettings.theme = theme; + } + + return ; +} +``` + +## Token Mapping Reference + +| Reveal Theme Property | Ignite UI CSS Token | Purpose | +|---|---|---| +| `regularFont`, `mediumFont`, `boldFont` | `--ig-font-family` | Font family | +| `isDark` | Computed from `--ig-surface-500` brightness | Light/dark mode detection | +| `fontColor` | Derived from `isDark` | Text color (white for dark, black for light) | +| `dashboardBackgroundColor` | `--ig-gray-100` | Dashboard background | +| `visualizationBackgroundColor` | `--ig-surface-500` | Individual visualization card background | + +> **Tip:** When switching between light and dark Ignite UI themes, call `setRevealTheme()` again after the theme change so Reveal dashboards stay in sync. + +See the [customize-theme skill](../../igniteui-react-customize-theme/SKILL.md) for more details on Ignite UI CSS custom properties and theme switching. diff --git a/skills/igniteui-react-use-components/reference/TROUBLESHOOTING.md b/skills/igniteui-react-use-components/reference/TROUBLESHOOTING.md new file mode 100644 index 0000000..fcc50d8 --- /dev/null +++ b/skills/igniteui-react-use-components/reference/TROUBLESHOOTING.md @@ -0,0 +1,167 @@ +# Troubleshooting + +## Issue: Components render without styles + +**Cause:** Missing theme CSS import. Without the theme CSS, components will render with broken layouts, missing icons (showing placeholders), and no visual styling. + +**Solution:** Add the theme CSS import **before** any component usage. In Vite/CRA apps, add it to your entry point. In Next.js, add it to each client component file or the root layout: + +```tsx +// Always required for core components +import 'igniteui-webcomponents/themes/light/bootstrap.css'; + +// Also required when using grids (IgrGrid, IgrDataGrid, IgrTreeGrid, etc.) +import 'igniteui-webcomponents-grids/grids/themes/light/bootstrap.css'; +``` + +**Next.js example:** + +```tsx +'use client'; + +import 'igniteui-webcomponents/themes/light/bootstrap.css'; +import 'igniteui-webcomponents-grids/grids/themes/light/bootstrap.css'; + +import { IgrNavbar, IgrButton } from 'igniteui-react'; +import { IgrGrid, IgrColumn, IgrPaginator } from 'igniteui-react-grids'; +``` + +## Issue: Grid renders but icons show as placeholders and styles are missing + +**Cause:** The grid theme CSS (`igniteui-webcomponents-grids/grids/themes/...`) is not imported. The base theme CSS alone is not enough for grids. + +**Solution:** Import **both** theme CSS files: + +```tsx +import 'igniteui-webcomponents/themes/light/bootstrap.css'; // Base theme +import 'igniteui-webcomponents-grids/grids/themes/light/bootstrap.css'; // Grid theme +``` + +## Issue: Grid Lite does not render or compilation error + +**Cause:** Grid Lite (`IgcGridLite`) is a **web component** from `igniteui-grid-lite` — not a React wrapper from `igniteui-react`. It uses the `Igc` prefix and requires explicit registration. + +**Solution:** + +1. Install the correct package: `npm install igniteui-grid-lite` +2. Import `IgcGridLite` from `igniteui-grid-lite` (not from `igniteui-react`) +3. Call `IgcGridLite.register()` at module level +4. Wrap in a sized container + +```tsx +import { IgcGridLite } from 'igniteui-grid-lite'; + +IgcGridLite.register(); + +// Use in JSX with a sized container: +
+ +
+``` + +```css +.grid-lite { + min-width: 400px; + min-height: 220px; + flex-grow: 1; + flex-basis: 0; +} +``` + +## Issue: `IgcGridLite` from `igniteui-grid-lite` is confused with `IgrDataGrid` from `igniteui-react-grids` + +**Solution:** These are different components: +- `igniteui-grid-lite` → lightweight MIT grid (`IgcGridLite`, web component — requires `.register()`) +- `igniteui-react-grids` → full-featured commercial grids (`IgrDataGrid`, `IgrTreeGrid`, etc. — React wrappers) + +Import from the correct package for your needs: + +```tsx +// Lightweight grid (MIT, web component) +import { IgcGridLite } from 'igniteui-grid-lite'; +IgcGridLite.register(); + +// Full-featured grid (commercial, React wrapper) +import { IgrDataGrid } from 'igniteui-react-grids'; +``` + +## Issue: Events fire but have unexpected shape + +**Cause:** Ignite UI events are `CustomEvent` objects from the underlying web component, not React `SyntheticEvent` objects. + +**Solution:** Type the handler parameter as `CustomEvent` and access `.detail` for event-specific data or `.target` for the element: + +```tsx +const handleChange = (e: CustomEvent) => { + const target = e.target as HTMLElement; + const detail = e.detail; + // Use target or detail as appropriate +}; +``` + +## Issue: Component methods not accessible + +**Solution:** Use `useRef` and cast to the underlying web component type: + +```tsx +const dialogRef = useRef(null); + +// Call imperative method +(dialogRef.current as any)?.show(); +``` + +## Issue: Chart / gauge / map / Grid Lite does not render or is invisible + +**Cause:** Two common causes: +1. The corresponding module was not registered (e.g., `IgrCategoryChartModule.register()` or `IgcGridLite.register()` was not called) +2. The parent container has no explicit dimensions — these components inherit size from their container and will be invisible if the container has zero height/width + +**Solution:** + +1. **Register the module** at the top level of the file (outside the component): + +```tsx +import { IgrCategoryChart, IgrCategoryChartModule } from 'igniteui-react-charts'; +IgrCategoryChartModule.register(); +``` + +2. **Wrap the chart in a sized container** with explicit dimensions: + +```css +.chart-container { + min-width: 400px; + min-height: 300px; + flex-grow: 1; + flex-basis: 0; +} +.chart-container > * { height: 100%; width: 100%; } +``` + +```tsx +
+ +
+``` + +## Issue: IgrTabs used for navigation fills the entire view with an empty panel + +**Cause:** `IgrTabPanel` elements were included alongside `IgrTab` elements when using tabs for navigation with React Router. The tab panels create empty content areas that take up space and push the routed content out of view. + +**Solution:** When using `IgrTabs` for navigation, use **only `IgrTab`** — do NOT include `IgrTabPanel`. Let the router's `` render the content: + +```tsx +// ✅ Correct — navigation tabs without panels + + Dashboard + Orders + + + +// ❌ Wrong — panels create empty space when used for navigation + + Dashboard + Orders + ... {/* Don't do this for navigation */} + ... {/* Don't do this for navigation */} + +```